{"record":{"id":"7c3ac07f4c0e9fce","repo":"oxc-project/oxc","slug":"prevent-synchronous-scripts","errorCode":null,"errorMessage":"Prevent synchronous scripts.","messagePattern":"Prevent synchronous scripts\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/nextjs/no_sync_scripts.rs","lineNumber":13,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{JSXAttributeItem, JSXAttributeName, JSXElementName},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\nuse rustc_hash::FxHashSet;\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_sync_scripts_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prevent synchronous scripts.\")\n        .with_help(\"See https://nextjs.org/docs/messages/no-sync-scripts\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoSyncScripts;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prevent the use of synchronous `<script>` tags in Next.js applications.\n    /// Require any `<script>` tag with a `src` attribute to also have either\n    /// the `async` or `defer` attribute.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Synchronous scripts can block the page rendering and negatively impact performance.\n    /// In Next.js applications, it's recommended to use `async` or `defer` attributes","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/nextjs/no_sync_scripts.rs#L1-L31","documentation":"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.","triggerScenarios":"A native `<script>` JSX element with a string-literal `src` attribute and neither `async` nor `defer` present.","commonSituations":"Embedding vendor widgets (chat, maps, surveys) by copying their default snippet; note that inline scripts without `src` are outside this rule's scope.","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."],"exampleFix":"// before\n<script src=\"https://widget.example/sdk.js\" />\n\n// after\nimport Script from 'next/script';\n<Script src=\"https://widget.example/sdk.js\" />","handlingStrategy":"validation","validationCode":"// raw script tags with src and no async/defer:\n// rg -n '<script[^>]*src=' -g '*.tsx' src | rg -v 'async|defer|next/script'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["nextjs","performance","script","lint"],"backgroundTag":"lint-render-blocking-script","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}