{"record":{"id":"027f0a4c94f876fe","repo":"oxc-project/oxc","slug":"do-not-use-a-elements-to-navigate-between-next","errorCode":null,"errorMessage":"Do not use `<a>` elements to navigate between Next.js pages.","messagePattern":"Do not use `<a>` elements to navigate between Next\\.js pages\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/nextjs/no_html_link_for_pages.rs","lineNumber":12,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{JSXAttributeItem, JSXAttributeName, JSXAttributeValue, JSXElementName},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_html_link_for_pages_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Do not use `<a>` elements to navigate between Next.js pages.\")\n        .with_help(\"Use `<Link />` from `next/link` instead for internal navigation. See https://nextjs.org/docs/messages/no-html-link-for-pages\")\n        .with_label(span.label(\"Replace with `<Link>` from `next/link`\"))\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoHtmlLinkForPages;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prevents the usage of `<a>` elements to navigate between Next.js pages.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using `<a>` elements for internal navigation in Next.js applications can cause:\n    /// - Full page reloads instead of client-side navigation\n    /// - Loss of application state\n    /// - Slower navigation performance","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/nextjs/no_html_link_for_pages.rs#L1-L30","documentation":"Warning from oxlint rule `nextjs/no-html-link-for-pages`. Internal links rendered as plain `<a href=\"/...\">` force a full document reload, losing client-side navigation, prefetching, and scroll restoration. The rule flags anchor tags whose string `href` targets an internal route.","triggerScenarios":"A JSX `<a>` element whose `href` is a string literal starting with `/` (no scheme or host), i.e. an app-internal URL.","commonSituations":"Migrating server-rendered HTML with hard-coded links; linking between routes in landing pages. Note: upstream this rule is deprecated since Next 13 (Link no longer needs an `<a>` child), but plain internal anchors are still worth converting.","solutions":["`import Link from 'next/link'` and use `<Link href=\"/about\">About</Link>`.","Keep `<a>` only for external URLs (full `https://...`) or non-navigation anchors (`#`, mailto, downloads)."],"exampleFix":"// before\n<a href=\"/about\">About</a>\n\n// after\nimport Link from 'next/link';\n<Link href=\"/about\">About</Link>","handlingStrategy":"validation","validationCode":"function isInternalHref(href: string): boolean {\n  return href.startsWith('/') && !href.startsWith('//');\n}\n// review flagged: rg -n '<a [^>]*href=\"/\"?' -g '*.tsx' src","typeGuard":"function isInternalHref(href: string): boolean {\n  return href.startsWith('/') && !href.startsWith('//');\n}","tryCatchPattern":null,"preventionTips":["Use `<Link>` by default for any href starting with `/`.","Reserve `<a>` for external URLs, `#anchors`, mailto, and file downloads.","Keep the nextjs oxlint plugin on so reviewers do not have to eyeball every anchor."],"tags":["nextjs","routing","performance","lint"],"backgroundTag":"lint-use-client-routing","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"}