How to set the document language in Next.js (Pages Router) v16

Declare page language for browsers and screen readers

Problem

Web pages need to declare their primary language to browsers, search engines, and assistive technologies. Without an explicit language declaration, these tools must guess the content's language. Screen readers default to the user's system language, which causes incorrect pronunciation when the content language differs. Browsers cannot confidently offer translation features because they lack source language information. Search engines struggle to index pages for the correct language audience, reducing discoverability for users searching in that language.

Solution

Set the lang attribute on the root <html> element to declare the page's primary language. In Next.js Pages Router, this is done by creating a custom Document component that wraps your application's HTML structure. The lang attribute accepts a standard language code that tells browsers, assistive technologies, and search engines which language the content uses, enabling correct pronunciation, appropriate translation offers, and accurate indexing.

Steps

1. Create a custom document file

Create a file named _document.js (or _document.tsx for TypeScript) in your pages directory. This file allows you to customize the HTML document structure that wraps every page in your application.

import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

The Html component from next/document accepts a lang prop that sets the language attribute on the root HTML element. Replace "en" with your content's language code.

2. Use the appropriate language code

Language codes follow the UTS Locale Identifiers standard format: language-region-script, where region and script are optional. For most cases, use the two-letter ISO 639-1 language code.

import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="fr">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Common examples include "en" for English, "es" for Spanish, "fr" for French, "de" for German, and "ja" for Japanese. You can include regional variants like "en-US" or "en-GB" when needed.

3. Set dynamic language based on locale

If your application supports multiple locales through Next.js i18n routing, access the current locale from the router context to set the language dynamically.

import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
  DocumentInitialProps,
} from "next/document";

export default class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext,
  ): Promise<DocumentInitialProps> {
    const initialProps = await Document.getInitialProps(ctx);
    return initialProps;
  }

  render() {
    return (
      <Html lang={this.props.locale}>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

When using Next.js's built-in i18n configuration, the framework automatically provides the locale and updates the lang attribute. The locale prop is available on the Document component when i18n is configured in next.config.js.