react-doctor/nextjs-no-script-in-head
Move <Script> out of <Head>: next/script ignores head placement, so a Script nested in Head silently never loads
- Category: Bugs
- Severity: error
- Source:
oxlint-plugin-react-doctor - Framework: nextjs
- Enabled when: framework=nextjs and capabilities=nextjs
- Tags: test-noise
- Default: Enabled
- Documentation: https://nextjs.org/docs/app/api-reference/components/script
Validate the diagnostic
Confirm the reported code matches this rule before you edit it.
Fires on a JSXOpeningElement whose name is the JSXIdentifier "Script" while insideHeadDepth > 0; that depth is a single flat counter incremented by every non-self-closing <Head> opening element and decremented on every </Head> closing element (clamped at 0 via Math.max(0, insideHeadDepth - 1), not stack-based tag pairing), so any <Script> appearing anywhere between an open <Head> and a </Head> is flagged regardless of nesting depth. Matching is purely by the literal identifier names Head and Script — the import source is never checked. False positive: a locally-defined or aliased component that happens to be named Script (or a Head that is not next/head, e.g. a styled-components Head or a custom layout Head wrapper) — confirm both resolve to next/script and next/head before reporting; a self-closing <Head /> never opens a head scope so a sibling <Script> after it is correctly not flagged.
How to fix
Follow the rule guidance while preserving unrelated behavior.
Copyable fix prompt
Copy this self-contained prompt into your coding agent after you confirm the diagnostic.
Related rules
More Bugs rules from the rules reference:
react-doctor/nextjs-no-use-search-params-without-suspense: Wrap the component using useSearchParams: `<Suspense fallback={<Skeleton />}><SearchComponent /></Suspense>`react-doctor/nextjs-no-vercel-og-import: Replace the @vercel/og import with import { ImageResponse } from "next/og"react-doctor/no-adjust-state-on-prop-change: Disallow adjusting state in an effect when a prop changes.react-doctor/no-arithmetic-on-optional-chained-operand: Multiplicative math on optional-chained value can be NaNreact-doctor/no-array-find-result-member-access-without-guard: Unguarded member access on find() result