In Next.js, load the script once with next/script in your root layout, and render the slot as a plain div wherever the card should go. Don't put a raw <script> tag inside a component: React doesn't run it.
Step 1: load the script in the root layout
Add the Script component to app/layout.tsx. The default loading strategy, afterInteractive, loads the script early but after some hydration, which suits a widget that isn't needed to draw the page.
// app/layout.tsx
import Script from "next/script"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://appadswap.com/w.js" strategy="afterInteractive" />
</body>
</html>
)
}
lazyOnload also works if you'd rather it wait for the browser to be idle. You don't need beforeInteractive, which Next.js reserves for scripts needed as early as possible, such as bot detectors and cookie consent.
Step 2: render the slot
The slot is an element with the data-appadswap attribute. It works in a Server Component as well as a Client Component, since it's plain markup:
// app/blog/[slug]/page.tsx
export default function Post() {
return (
<article>
{/* ...post content... */}
<div data-appadswap="SITE_ID" data-format="card" />
</article>
)
}
Navigation between pages
Next.js runs a script like this once per document load, and client-side navigation doesn't run it again. The widget is built for that: a slot that is rendered after the script has loaded is picked up on its own. So a slot on a page you navigate to still fills, without any extra code.
Corner card, no slot
To use the corner format, give the script tag the attributes instead and skip the div:
<Script
src="https://appadswap.com/w.js"
data-appadswap="SITE_ID"
data-format="corner"
strategy="afterInteractive"
/>
Check it works
Run the app and open a page with a slot. The Sites page in your dashboard flips from unverified to live on its own once the widget has loaded on the address you registered. In development that's localhost, so the real check is your deployed site.
If it doesn't work
- Nothing renders and there's no request for
w.js. TheScriptisn't in a layout that wraps the page. Check that it's in the root layout. - You used
<script>in JSX. Replace it withnext/script. - A content security policy blocks it. If you set a CSP, allow
https://appadswap.cominscript-srcandconnect-src. - The slot has no height and the card seems missing. The card reserves some height while it loads, but a parent with
overflow: hiddenand a fixed height can still clip it.
Source
The Next.js Script component reference. Next: other install guides, or add your app.