oxc-project/oxc · warning · OxcDiagnostic

Do not use `<head>` element. Use `<Head />` from `next/head`

Error message

Do not use `<head>` element. Use `<Head />` from `next/head` instead.

What it means

Warning from oxlint rule `nextjs/no-head-element`. In the pages router, a raw HTML `<head>` element is not managed by Next.js: tags inside it are neither deduplicated nor updated during client-side navigation. The rule (app-directory files are exempt) tells you to use the framework component instead.

Source

Thrown at crates/oxc_linter/src/rules/nextjs/no_head_element.rs:14

use oxc_ast::{AstKind, ast::JSXElementName};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{
    AstNode,
    context::{ContextHost, LintContext},
    rule::Rule,
    utils::is_in_app_dir,
};

fn no_head_element_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Do not use `<head>` element. Use `<Head />` from `next/head` instead.")
        .with_help("See https://nextjs.org/docs/messages/no-head-element")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Prevents the usage of the native `<head>` element inside a Next.js application.
    ///
    /// ### Why is this bad?
    ///
    /// A `<head>` element can cause unexpected behavior in a Next.js application.
    /// Use Next.js' built-in `next/head` component instead.
    ///
    /// ### Examples

View on GitHub (pinned to e1e7af627c)

Solutions

  1. `import Head from 'next/head'` and wrap your tags: `<Head><title>...</title></Head>`.
  2. For fonts and meta use dedicated APIs (`next/font`, app-router `metadata`) instead of raw head markup.

Example fix

// before
<head><title>Home</title></head>

// after
import Head from 'next/head';
<Head><title>Home</title></Head>
Defensive patterns

Strategy: validation

Validate before calling

// native head elements in pages/components:
// rg -n '<head[> ]' pages components app -g '!**/_document.*'

Prevention

When it happens

Trigger: A native lowercase `<head>` JSX element in any page or component outside `pages/_document.js` and outside the app directory.

Common situations: Hand-writing `<head><title>...</title></head>` in a page; converting plain HTML mockups into JSX; not knowing the pages router expects `<Head>` from `next/head`.

Related errors


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