oxc-project/oxc · warning · OxcDiagnostic
`next/script` components with inline content must specify an
Error message
`next/script` components with inline content must specify an `id` attribute.
What it means
Warning from oxlint rule `nextjs/inline-script-id`. Next.js registers inline `next/script` content under its `id` so the script is deduplicated and not re-executed during client-side navigation; without an `id` those guarantees break. Any `<Script>` that provides inline content via `dangerouslySetInnerHTML` must also declare an `id` attribute.
Source
Thrown at crates/oxc_linter/src/rules/nextjs/inline_script_id.rs:13
use oxc_ast::{
AstKind,
ast::{Expression, JSXAttributeItem, JSXAttributeName, ObjectPropertyKind, PropertyKey},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use rustc_hash::FxHashSet;
use crate::{AstNode, context::LintContext, rule::Rule};
fn inline_script_id_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(
"`next/script` components with inline content must specify an `id` attribute.",
)
.with_help("See https://nextjs.org/docs/messages/inline-script-id")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct InlineScriptId;
declare_oxc_lint!(
/// ### What it does
///
/// Enforces that all `next/script` components with inline content or `dangerouslySetInnerHTML` must have an `id` prop.
///
/// ### Why is this bad?
///
/// Next.js requires a unique `id` prop for inline scripts to properly deduplicate them during page renders.
/// Without an `id`, the same inline script might be executed multiple times, leading to unexpected behaviorView on GitHub (pinned to e1e7af627c)
Solutions
- Add a unique `id` attribute, e.g. `<Script id="ga4" ...>`; ids must be unique across the whole app.
- If the code comes from a third party, prefer an external script: `<Script src="https://..." strategy="afterInteractive" />` and drop the inline content.
- Re-run oxlint (nextjs plugin) on the file to confirm the warning is gone.
Example fix
// before
<Script dangerouslySetInnerHTML={{ __html: `(function(){...})();` }} />
// after
<Script id="my-inline-script">{`(function(){...})();`}</Script> Defensive patterns
Strategy: validation
Validate before calling
// CI gate: run the rule directly // npx oxlint -c .oxlintrc.json src (.oxlintrc.json enables the nextjs plugin) // quick grep for inline scripts missing an id: // rg -U -n 'dangerouslySetInnerHTML' -g '*.tsx' src | rg -v 'id='
Prevention
- Treat every inline `next/script` as needing a stable id named after its purpose (e.g. id="hotjar-init").
- Keep ids unique app-wide; reuse of an id makes Next.js dedupe the second script away.
- Run oxlint with the nextjs plugin in CI so a missing id fails the build.
When it happens
Trigger: A JSX element whose tag is the local name imported from `next/script` that sets `dangerouslySetInnerHTML={{ __html: ... }}` (inline content) and has no `id` attribute.
Common situations: Pasting an analytics or pixel snippet (GA4, GTM, Meta Pixel, Hotjar) into a Next.js page as inline `next/script`; converting a raw `<script>` tag to `next/script` while keeping the content but not adding an id; following older tutorials that omit `id`.
Related errors
- Prefer `next/script` component when using the inline script
- next/script's `beforeInteractive` strategy should not be use
- Do not include stylesheets manually.
- Prevent usage of `next/script` in `next/head` component.
- A font-display parameter is missing (adding `&display=option
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/24eb370d51266033.
Report an issue: GitHub.