A beforeInteractive script must be in the HTML the server sends, before any Next.js code runs. In the Pages Router, only pages/_document.js writes that HTML. In a page or a component, the script isn't part of that HTML and loads later.
Files under an app/ directory aren't checked. In the App Router, beforeInteractive belongs in the root layout.
Configure
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"@next/next/no-before-interactive-script-outside-document" = "error"
Examples
Reported:
import Script from "next/script";
export default function Home() {
return <Script src="https://example.com/consent.js" strategy="beforeInteractive" />;
}
Not reported, in pages/_document.jsx:
import { Head, Html, Main, NextScript } from "next/document";
import Script from "next/script";
export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<Script src="https://example.com/consent.js" strategy="beforeInteractive" />
</body>
</Html>
);
}
Not reported, in app/layout.jsx:
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://example.com/consent.js" strategy="beforeInteractive" />
</body>
</html>
);
}