¿Cómo configurar el atributo lang HTML dinámicamente en el documento NextJs?

5 minutos de lectura

Avatar de usuario de MiguelSlv
MiguelSlv

Tengo un sitio en varios idiomas y necesito configurar el atributo de idioma HTML según el idioma de cada página.

Intento pasar el valor en contexto, pero no se actualiza cuando cambia la página.

Aquí el código actual:

import Document, { Html, Head, Main, NextScript } from 'next/document'
import GlobalContext , {eLanguage }from '../components/GlobalContext' //my global context 

export default class MyDocument extends Document {

static async getInitialProps(ctx) {

  const initialProps = await Document.getInitialProps(ctx)
  return { ...initialProps }
}
static contextType = GlobalContext;
render() {

  console.debug('Started')
  console.debug('language:'+ this.context.language) 

  return (
    <Html lang={eLanguage[this.context.language]}> //if the first page loaded as lang 'en' it sets 'en' and apply to all other pages.
      <Head>
      </Head>
      <body>       
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

}

Actualización: el idioma de cada página se puede deducir de la ruta de la página

Creo que la mejor solución aquí es usar un personalizado ./pages/_document.js archivar y anular el documento en sí.

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

Más explicación se puede encontrar aquí: https://nextjs.org/docs/advanced-features/custom-document

  • ¿Cómo hago para que esto funcione con Typescript? Importar Typescript parece haberlo roto:/

    –Robby Hoover

    20 de julio a las 1:42

Próximos 10 apoyos Enrutamiento internacionalizado y añadiré lang dejándote dinámicamente con:

<Html>
  <Head />
  <body>       
    <Main />
    <NextScript />
  </body>
</Html>

  • Para futuros lectores, esto no es compatible actualmente si está utilizando SSG a través de next exportReferencia y Documentación

    – Gangula

    15 de enero a las 8:20

Avatar de usuario de FabioRosado
FabioRosado

Si utiliza siguiente/cabeza puede configurar el idioma para la etiqueta html. Todo lo que pase al componente Head se colocará en el <head> o <html>.

Next Head funciona de forma similar a React Helmet, por lo que para tu caso podrías hacer algo así:

  • Cree un componente e importe Head desde “next/head”
  • Dentro de la etiqueta Head, agregas el <html lang={lan} /> al componente.

Luego puede pasar el idioma deseado a ese componente, luego importar el componente en las páginas deseadas.

import React from "react"
import Head from "next/head"

const Language = ({title, lang}) => (
  <Head>
    <html lang={lang} />
    <title>{title}</title>
  </Head>
)

export default Language

Ese bit html se inyectará dentro del <html> etiqueta.

Tenga en cuenta que incluso si lo inyectamos así, la consola registrará el siguiente error: TypeError: n is null.

  • Recibí este error en la consola: head-manager.js?0ea4:2 Advertencia: falta el siguiente recuento. err.sh/next.js/next-head-count-missing. En cualquier caso, ese hist no es un camino a seguir.

    – MiguelSlv

    19 mayo 2020 a las 22:40


  • También tenga en cuenta que la etiqueta Html es padre de la etiqueta Head. No creo que el componente Head signifique ser usado de esta manera.

    – MiguelSlv

    19 mayo 2020 a las 23:06

  • Gracias, esta es la respuesta correcta. Igual que se proporciona en los documentos de nextjs.

    – Gabriel Linassi

    30 mayo 2021 a las 15:25

  • @GabrielLinassi, esto no es exactamente lo mismo que en el documentos, donde dice que debe hacer esto en _document. Técnicamente, hacerlo en otro lugar funciona, aunque tal vez no pueda confiar en que siga funcionando, y le da a la consola un declive Warning: next-head-count is missing como se ha mencionado más arriba.

    – ArneHugo

    3 de septiembre de 2021 a las 12:46


  • @ArneHugo Así es. Gracias por la corrección. Revisé aquí mi código y también está definido en el _document.

    – Gabriel Linassi

    3 sep 2021 a las 12:55

Implementé esto agregando esto al archivo next.config.js:

i18n: {
// These are all the locales you want to support in
// your application
locales: ['en-US'],
// This is the default locale you want to be used when visiting
// a non-locale prefixed path e.g. `/hello`
defaultLocale: 'en-US' }

No tuve la necesidad de crear un _document.js personalizado

Las versiones de Nextjs posteriores a la 10 brindan soporte de localización predeterminado. No tiene que configurar mucho.

Agrega automáticamente el atributo lang a html, pero aún hay sin apoyo hasta ahora con v12 para el atributo dir para incluir que podemos usar este pequeño truco dentro _archivo de documento.

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

function Document(props: any) {

  return (
    <Html dir={props.__NEXT_DATA__.locale === "en" ? "ltr" : "rtl"}>
      <Head></Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

export default Document;

El resultado final sería
ingrese la descripción de la imagen aquí

Avatar de usuario de Pavel Sheremet
Pavel Sheremet

Crear _document.js en la carpeta `pages“ y usa esto:

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

class MyDocument extends Document {
  static async getInitialProps(context) {
    const initialProps = await Document.getInitialProps(context);
    return { ...initialProps };
  }

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

export default MyDocument;

para uso de localización next.config.js

{
 i18n: {
    locales: ['en', 'fr', 'de',],
    defaultLocale: 'en',
  },
}

avatar de usuario de stef
Stef

Puede usar un enlace React useEffect para establecer el idioma del documento sin tener que cambiar la forma en que Next.js genera la etiqueta HTML.

Dentro de su componente de página u otro componente apropiado, incluya el gancho useEffect:

import {useEffect} from "react";

Y luego agrega el gancho:

const MyPage = () => {
  useEffect(() => {
    document.documentElement.lang = "en-us";
  });
  // The rest of your component
}

Esto pasa la verificación de Lighthouse para “hreflang”, y si su sitio tiene varios idiomas, puede usar esto para configurar el idioma de la página por página.

  • esto no es compatible con SEO desafortunadamente

    – itsjavi

    28 de febrero a las 23:41

¿Ha sido útil esta solución?