oxc-project/oxc · warning · OxcDiagnostic
Prevent synchronous scripts.
Error message
Prevent synchronous scripts.
What it means
Warning from oxlint rule `nextjs/no-sync-scripts`. A `<script src="...">` without `async` or `defer` blocks HTML parsing and delays hydration; in a hydration framework it also risks the script running before React is ready. The rule requires any raw script tag with a literal `src` to be non-blocking.
Source
Thrown at crates/oxc_linter/src/rules/nextjs/no_sync_scripts.rs:13
use oxc_ast::{
AstKind,
ast::{JSXAttributeItem, JSXAttributeName, JSXElementName},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use rustc_hash::FxHashSet;
use crate::{AstNode, context::LintContext, rule::Rule};
fn no_sync_scripts_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Prevent synchronous scripts.")
.with_help("See https://nextjs.org/docs/messages/no-sync-scripts")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoSyncScripts;
declare_oxc_lint!(
/// ### What it does
///
/// Prevent the use of synchronous `<script>` tags in Next.js applications.
/// Require any `<script>` tag with a `src` attribute to also have either
/// the `async` or `defer` attribute.
///
/// ### Why is this bad?
///
/// Synchronous scripts can block the page rendering and negatively impact performance.
/// In Next.js applications, it's recommended to use `async` or `defer` attributesView on GitHub (pinned to e1e7af627c)
Solutions
- Add `async` (independent script) or `defer` (order-dependent) to the tag.
- Prefer `<Script src="..." />` from `next/script`, which defaults to `afterInteractive` and handles ordering for you.
Example fix
// before <script src="https://widget.example/sdk.js" /> // after import Script from 'next/script'; <Script src="https://widget.example/sdk.js" />
Defensive patterns
Strategy: validation
Validate before calling
// raw script tags with src and no async/defer: // rg -n '<script[^>]*src=' -g '*.tsx' src | rg -v 'async|defer|next/script'
Prevention
- Convert vendor embeds to `next/script` (default afterInteractive) instead of raw tags.
- If a raw tag must stay, add `defer` unless ordering demands otherwise.
- Keep the nextjs oxlint rules enabled so pasted snippets get flagged on commit.
When it happens
Trigger: A native `<script>` JSX element with a string-literal `src` attribute and neither `async` nor `defer` present.
Common situations: Embedding vendor widgets (chat, maps, surveys) by copying their default snippet; note that inline scripts without `src` are outside this rule's scope.
Related errors
- A font-display parameter is missing (adding `&display=option
- `{font_display_value}` is not a recommended font-display val
- `rel="preconnect"` is missing from Google Font.
- Do not use `<a>` elements to navigate between Next.js pages.
- Using `<img>` could result in slower LCP and higher bandwidt
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/7c3ac07f4c0e9fce.
Report an issue: GitHub.