Next.js uses the id of an inline <Script> to keep track of it, so the code runs once instead of again after each navigation. A script with a src is tracked by its URL. An inline script doesn't have one, so it needs an id.
A script is inline if it has children or a dangerouslySetInnerHTML prop. The rule follows the name you give to the default import of next/script.
Configure
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"@next/next/inline-script-id" = "error" # or "warn"
Examples
Reported:
import Script from "next/script";
export default function Page() {
return <Script>{`window.startedAt = Date.now();`}</Script>;
}
import Script from "next/script";
export default function Page() {
return <Script dangerouslySetInnerHTML={{ __html: "window.startedAt = Date.now();" }} />;
}
Not reported:
import Script from "next/script";
export default function Page() {
return (
<>
<Script id="started-at">{`window.startedAt = Date.now();`}</Script>
<Script src="https://example.com/widget.js" />
</>
);
}
If you spread a variable into the props, the id might be in there, so the element isn't reported:
import Script from "next/script";
export default function Tracker(props) {
return <Script {...props}>{`window.startedAt = Date.now();`}</Script>;
}