oxc-project/oxc · warning · OxcDiagnostic

Prefer `next/script` component when using the inline script

Error message

Prefer `next/script` component when using the inline script for Google Analytics.

What it means

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.

Source

Thrown at crates/oxc_linter/src/rules/nextjs/next_script_for_ga.rs:20

    AstKind,
    ast::{
        Expression, JSXAttributeItem, JSXAttributeValue, JSXElementName, JSXExpression,
        JSXOpeningElement, ObjectProperty, ObjectPropertyKind, PropertyKey,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{
    AstNode,
    context::LintContext,
    rule::Rule,
    utils::{get_string_literal_prop_value, has_jsx_prop_ignore_case},
};

fn next_script_for_ga_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "Prefer `next/script` component when using the inline script for Google Analytics.",
    )
    .with_help("See https://nextjs.org/docs/messages/next-script-for-ga")
    .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NextScriptForGa;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Enforces the use of the `next/script` component when implementing Google Analytics in Next.js applications,
    /// instead of using regular `<script>` tags.
    ///
    /// ### Why is this bad?
    ///
    /// Using regular `<script>` tags for Google Analytics can lead to several issues:

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace the external tag with `<Script id="google-analytics" strategy="afterInteractive" src="https://www.googletagmanager.com/gtag/js?id=G-XXXX" />`.
  2. Move the inline `gtag('config', ...)` init into `<Script id="ga-init" strategy="afterInteractive">{`...`}</Script>` right after it.
  3. In the pages router, place both in `pages/_app.js` so they load once for the whole app.

Example fix

// before
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XX" />

// after
import Script from 'next/script';
<Script id="ga" strategy="afterInteractive" src="https://www.googletagmanager.com/gtag/js?id=G-XX" />
Defensive patterns

Strategy: validation

Validate before calling

// grep for raw GA snippets that bypass next/script:
// rg -n "googletagmanager|google-analytics|gtag\(" -g '*.tsx' src | rg -v "next/script"

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/b674ebcd330fc537. Report an issue: GitHub.