Next.js
Next.js framework rules from @next/eslint-plugin-next, applied to TypeScript and TSX sources inside Next.js apps.
Checks Next.js-specific conventions that the framework’s runtime treats as load-bearing: pages/app routing, <Head> placement, font and script loading, image and link components.
Source: @next/eslint-plugin-next (MIT).
Rule index
Each rule name links to the detailed section below.
Examples come from the checked lint corpus or package-level rule tests when project layout matters.
nextjs/google-font-display: Require a non-blockingdisplay=value on Google Fonts stylesheet links; rejectauto,block, andfallback.nextjs/google-font-preconnect: Requirerel="preconnect"forfonts.gstatic.comlinks to shave latency off Google Font fetches.nextjs/inline-script-id: Require anidattribute on inline<Script>components fromnext/script.nextjs/next-script-for-ga: Prefer the Next.js Google Analytics integration over hand-writtengtagscript tags.nextjs/no-assign-module-variable: Reject local declarations namedmodule.nextjs/no-async-client-component: Rejectasyncfunction bodies on React Client Components.nextjs/no-before-interactive-script-outside-document: Restrict thenext/scriptstrategy="beforeInteractive"option topages/_document.tsx.nextjs/no-css-tags: Reject raw<link rel="stylesheet">tags.nextjs/no-document-import-in-page: Restrictnext/documentimports topages/_document.tsx,Documentcannot be used in a regular page.nextjs/no-duplicate-head: Reject more than one<Head>element fromnext/documentinpages/_document.tsx.nextjs/no-head-element: Reject raw<head>elements outside theapp/directory, usenext/heador the metadata exports.nextjs/no-head-import-in-document: Rejectnext/headimports insidepages/_document.tsx, usenext/document’sHeadthere.nextjs/no-html-link-for-pages: Prefernext/linkfor internal anchors with a statichref.nextjs/no-img-element: Prefernext/imageover raw<img>elements.nextjs/no-page-custom-font: Reject Google font<link>tags inside regular pages files.nextjs/no-script-component-in-head: Rejectnext/scriptinsidenext/head,<Script>must appear in the JSX tree, not in<Head>.nextjs/no-styled-jsx-in-document: Reject styled-jsx tags insidepages/_document.tsx.nextjs/no-sync-scripts: Requireasyncordeferon external raw<script>tags.nextjs/no-title-in-document-head: Reject<title>insideHeadfromnext/document.nextjs/no-typos: Catch near-miss typos in Next.js data-fetching export names.nextjs/no-unwanted-polyfillio: Reject Polyfill.io script URLs, Next.js already polyfills modern browsers, and Polyfill.io has a checkered history.
Rules
nextjs/google-font-display
Require a non-blocking display= value on Google Fonts stylesheet links; reject auto, block, and fallback, which keep text invisible while the font loads and hurt LCP. Prefer optional or swap.
Example:
// reports: nextjs/google-font-display (error)
const a = (
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter"
/>
);nextjs/google-font-preconnect
Require rel="preconnect" for fonts.gstatic.com links to shave latency off Google Font fetches.
Example:
// reports: nextjs/google-font-preconnect (error)
const a = <link href="https://fonts.gstatic.com" />;nextjs/inline-script-id
Require an id attribute on inline <Script> components from next/script.
Next.js uses the id to track the script across client navigations and to satisfy its loading-strategy budget; an inline script without one is silently dropped on subsequent renders.
Example:
import Script from "next/script";
const a = (
// reports: nextjs/inline-script-id (error)
<Script>{`console.log("hi")`}</Script>
);nextjs/next-script-for-ga
Prefer the Next.js Google Analytics integration over hand-written gtag script tags.
Example:
// reports: nextjs/next-script-for-ga (error)
const a = (
<script
async
src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"
/>
);nextjs/no-assign-module-variable
Reject local declarations named module, which shadow the CommonJS module binding Next.js relies on.
Example:
// reports: nextjs/no-assign-module-variable (error)
const module = {};nextjs/no-async-client-component
Reject async function bodies on React Client Components.
The client-side React runtime can’t await a component’s render, so an async "use client" component returns a pending promise that crashes hydration; do data fetching in a Server Component or in useEffect instead.
Example:
"use client";
// reports: nextjs/no-async-client-component (error)
export async function Page() {
return <div>hi</div>;
}nextjs/no-before-interactive-script-outside-document
Restrict the next/script strategy="beforeInteractive" option to pages/_document.tsx, anywhere else, the strategy is downgraded silently.
Example:
import Script from "next/script";
// reports: nextjs/no-before-interactive-script-outside-document (error)
const a = <Script src="/x.js" strategy="beforeInteractive" />;nextjs/no-css-tags
Reject raw <link rel="stylesheet"> tags.
Next.js handles CSS through its bundler, imported stylesheets, CSS Modules, or next/font, and manual stylesheet links skip the runtime’s critical-CSS extraction and render-blocking heuristics.
Example:
// reports: nextjs/no-css-tags (error)
const a = <link rel="stylesheet" href="/styles.css" />;nextjs/no-document-import-in-page
Restrict next/document imports to pages/_document.tsx, Document cannot be used in a regular page.
Example:
// reports: nextjs/no-document-import-in-page (error)
import Document from "next/document";nextjs/no-duplicate-head
Reject more than one <Head> element from next/document in pages/_document.tsx.
Next.js merges metadata into the single <Head> it renders into the HTML shell; additional instances are dropped silently and any tags inside them never reach the page.
Example:
const a = (
<>
<Head />
{/* reports: nextjs/no-duplicate-head (error) */}
<Head />
</>
);nextjs/no-head-element
Reject raw <head> elements outside the app/ directory, use next/head or the metadata exports.
Example:
// reports: nextjs/no-head-element (error)
const a = (
<head>
<title>Site</title>
</head>
);nextjs/no-head-import-in-document
Reject next/head imports inside pages/_document.tsx, use next/document’s Head there.
Example:
// reports: nextjs/no-head-import-in-document (error)
import Head from "next/head";nextjs/no-html-link-for-pages
Prefer next/link for internal anchors with a static href, since Link performs client-side routing.
Example:
// reports: nextjs/no-html-link-for-pages (error)
const a = <a href="/about">about</a>;nextjs/no-img-element
Prefer next/image over raw <img> elements so the framework can optimize the asset.
Example:
// reports: nextjs/no-img-element (error)
const a = <img src="/hero.png" alt="hero" />;nextjs/no-page-custom-font
Reject Google font <link> tags inside regular pages files, load fonts in _document.tsx (pages router) or via next/font (app router).
Example:
// reports: nextjs/no-page-custom-font (error)
const a = (
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter&display=swap"
/>
);nextjs/no-script-component-in-head
Reject next/script inside next/head, <Script> must appear in the JSX tree, not in <Head>.
Example:
const a = (
<Head>
{/* reports: nextjs/no-script-component-in-head (error) */}
<Script src="/x.js" />
</Head>
);nextjs/no-styled-jsx-in-document
Reject styled-jsx tags inside pages/_document.tsx, which the server renders incorrectly.
Example:
const a = (
<div>
{/* reports: nextjs/no-styled-jsx-in-document (error) */}
<style jsx>{`
div {
color: red;
}
`}</style>
</div>
);nextjs/no-sync-scripts
Require async or defer on external raw <script> tags so loading does not block render.
Example:
// reports: nextjs/no-sync-scripts (error)
const a = <script src="https://example.com/x.js" />;nextjs/no-title-in-document-head
Reject <title> inside Head from next/document. Set the title from the metadata exports instead.
Example:
const a = (
<Head>
{/* reports: nextjs/no-title-in-document-head (error) */}
<title>Site</title>
</Head>
);nextjs/no-typos
Catch near-miss typos in Next.js data-fetching export names (getStaticProps, getStaticPaths, getServerSideProps).
A misspelled export is treated as ordinary module state, so the page silently falls back to client-side rendering with no build-time warning.
Example:
// reports: nextjs/no-typos (error)
export function getstaticprops() {
return { props: {} };
}nextjs/no-unwanted-polyfillio
Reject Polyfill.io script URLs, Next.js already polyfills modern browsers, and Polyfill.io has a checkered history.
Example:
// reports: nextjs/no-unwanted-polyfillio (error)
const a = <script src="https://polyfill.io/v3/polyfill.min.js" />;