{"record":{"id":"b674ebcd330fc537","repo":"oxc-project/oxc","slug":"prefer-next-script-component-when-using-the-inli","errorCode":null,"errorMessage":"Prefer `next/script` component when using the inline script for Google Analytics.","messagePattern":"Prefer `next/script` component when using the inline script for Google Analytics\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/nextjs/next_script_for_ga.rs","lineNumber":20,"sourceCode":"    AstKind,\n    ast::{\n        Expression, JSXAttributeItem, JSXAttributeValue, JSXElementName, JSXExpression,\n        JSXOpeningElement, ObjectProperty, ObjectPropertyKind, PropertyKey,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::Rule,\n    utils::{get_string_literal_prop_value, has_jsx_prop_ignore_case},\n};\n\nfn next_script_for_ga_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\n        \"Prefer `next/script` component when using the inline script for Google Analytics.\",\n    )\n    .with_help(\"See https://nextjs.org/docs/messages/next-script-for-ga\")\n    .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NextScriptForGa;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Enforces the use of the `next/script` component when implementing Google Analytics in Next.js applications,\n    /// instead of using regular `<script>` tags.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using regular `<script>` tags for Google Analytics can lead to several issues:","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/nextjs/next_script_for_ga.rs#L2-L38","documentation":"Warning from oxlint rule `nextjs/next-script-for-ga`. Next.js ships `next/script`, which loads third-party scripts with the correct priority and deduplication; raw `<script>` tags for Google Analytics bypass that machinery. The rule fires on plain `<script>` elements (inline or external) whose content or `src` matches Google Analytics / Google Tag Manager patterns.","triggerScenarios":"A JSX `<script>` with `dangerouslySetInnerHTML` content containing GA markers (e.g. `googletagmanager.com/gtag/js`, `google-analytics.com/analytics.js`, `ga(`, `gtag(`), or a `<script src>` pointing at those hosts, in any page or component.","commonSituations":"Copying the GA4 or Universal Analytics install snippet from the Google dashboard into a Next.js page or layout; migrating a CRA site and keeping its index.html analytics tags; GTM setups.","solutions":["Replace the external tag with `<Script id=\"google-analytics\" strategy=\"afterInteractive\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XXXX\" />`.","Move the inline `gtag('config', ...)` init into `<Script id=\"ga-init\" strategy=\"afterInteractive\">{`...`}</Script>` right after it.","In the pages router, place both in `pages/_app.js` so they load once for the whole app."],"exampleFix":"// before\n<script async src=\"https://www.googletagmanager.com/gtag/js?id=G-XX\" />\n\n// after\nimport Script from 'next/script';\n<Script id=\"ga\" strategy=\"afterInteractive\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XX\" />","handlingStrategy":"validation","validationCode":"// grep for raw GA snippets that bypass next/script:\n// rg -n \"googletagmanager|google-analytics|gtag\\(\" -g '*.tsx' src | rg -v \"next/script\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on one analytics loader component that wraps `next/script` and use it everywhere.","Load GA once in `_app.js` or the root layout instead of per page.","Add an oxlint CI step with the nextjs plugin so raw GA scripts are caught automatically."],"tags":["nextjs","google-analytics","next-script","lint"],"backgroundTag":"lint-prefer-framework-api","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}