How to add a popup to Next.js
Building a popup in React is not hard; building the trigger logic, frequency rules, multi-step form validation, storage, notifications and analytics around it is a week you probably did not plan for. PopupForge ships all of that behind one script, and Next.js has a first-class way to load it: the Script component.
This guide puts the tag in the root layout with strategy="afterInteractive" so it loads after hydration and only once per document. It also covers the Pages Router, the Content-Security-Policy entries you need if you set one, and how to check the popup behaves across client-side navigations.
The script tag
<script src="https://getpopupforge.com/lead-modal.js?appId=YOUR_APP_ID&configId=YOUR_CONFIG_ID" async defer></script>Replace YOUR_APP_ID and YOUR_CONFIG_ID with the values from the install panel of your published popup. The tag is the same on every platform; only where you paste it changes.
Step by step
- 01
Build and publish the popup in PopupForge
Create a free account, generate or design the popup in the visual editor, set the trigger and frequency, then publish it. The install panel shows your script tag with the appId and configId already filled in. Copy that exact tag; the placeholder version on this page will not load a popup.
- 02
Import Script in the root layout
Open app/layout.js or app/layout.tsx and add: import Script from 'next/script'. The root layout wraps every route, so the popup is available site-wide without touching individual pages.
- 03
Add the Script component inside body
Inside the body element, after {children}, add: <Script src="https://getpopupforge.com/lead-modal.js?appId=YOUR_APP_ID&configId=YOUR_CONFIG_ID" strategy="afterInteractive" />. afterInteractive is the default strategy, so you may omit it; it loads the script after hydration begins, which is right for a popup.
- 04
Pages Router: use pages/_app.js instead
If your project uses the Pages Router, put the same Script component in pages/_app.js (or _app.tsx) next to <Component {...pageProps} />. Do not use beforeInteractive; it forces the script into the head and offers nothing for a popup.
- 05
Allow the domain in your Content-Security-Policy
If you send a CSP header from next.config or middleware, add https://getpopupforge.com to script-src (the loader), connect-src (it fetches the popup config) and frame-src (it injects an iframe that renders the popup). Without these, the browser blocks the popup silently except for a console error.
- 06
Deploy and test client-side navigation
Deploy to Vercel or your host. The script loads once per document; visit the site, trigger the popup, then navigate with Link to another route and confirm the frequency rule you chose (once per session, cooldown) behaves as expected.
- 07
Test the popup and check the lead arrives
Open the live site in a private browsing window so a previous session does not suppress the popup, trigger it the way you configured (wait for the delay, scroll, or move the pointer out through the top of the window), submit a test lead, then confirm it shows in the PopupForge lead list.
Next.js notes and gotchas
- A plain <script> tag in JSX also works in the App Router layout, but next/script gives you loading strategies and avoids hydration warnings. Use the component.
- Do not use strategy="lazyOnload" for a popup with an immediate or short delay trigger. lazyOnload waits for browser idle time, which can push the popup well past the moment you configured.
- Frameworks that render the layout on the server still execute the script only in the browser, so the popup never appears in server-side HTML snapshots or in tests that render without a DOM.
- If you run a strict CSP with nonces, next/script forwards the nonce automatically when you pass it; the frame-src and connect-src entries are still required.
Verify the install
Confirm the popup shows and the lead arrives
- 1.Open the deployed site in a private window and check the Network tab for lead-modal.js with a 200 status.
- 2.Trigger the popup, submit a test lead, then navigate client-side and confirm the frequency rule holds.
- 3.Open PopupForge and confirm the lead and analytics counts.
Official Next.js documentation
Platform menus and plan rules change. If a step here no longer matches what you see, the official page above is the source of truth.
FAQ
Frequently asked questions
Which next/script strategy should I use?
afterInteractive, which is the default. It loads after hydration begins, early enough for immediate and timed triggers. Avoid beforeInteractive (forces the head, no benefit) and lazyOnload (waits for idle time, which delays the popup).
Does this work with the Pages Router?
Yes. Place the same Script component in pages/_app.js so it renders on every page. The strategy and CSP guidance are identical.
What CSP directives does the popup need?
Add https://getpopupforge.com to script-src, connect-src and frame-src. The loader is a script, it fetches the popup config, and it injects an iframe that draws the popup; each of those needs its own directive.
Can I render the popup with a React component instead of a script?
Not at the moment; PopupForge installs through the script tag on every platform. In Next.js the Script component is the idiomatic wrapper for exactly this kind of third-party tag.
Get your script tag
Generate a popup for your site, then paste one tag into Next.js.
The free generator shows three brand-matched directions from your URL, no account needed. Creating an account gives you the visual editor, triggers, URL targeting and the install panel with your real appId and configId.