如何在 NextJs 文档上动态设置 HTML lang 属性?

Mig*_*Slv 11 html node.js reactjs next.js

我有一个多语言站点,需要根据每个页面的语言设置 HTML lang 属性。

我尝试在上下文中传递值,但在页面更改时不更新。

这是当前的代码:

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

}

更新:可以从页面路由推断出每个页面的语言

Joe*_*rty 32

我相信最好的解决方案是使用自定义./pages/_document.js文件并覆盖文档本身。

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
Run Code Online (Sandbox Code Playgroud)

更多解释可以在这里找到:https ://nextjs.org/docs/advanced-features/custom-document


小智 23

如果您使用next/head您可以将语言设置为 html 标签。传递给 Head 组件的任何内容都将被放置在<head>或中<html>

Next Head 的工作原理与 React Helmet 类似,因此对于您的情况,您可以按照以下方式执行操作:

  • 创建一个组件并从“next/head”导入Head
  • 在 Head 标签内,将 添加<html lang={lan} />到组件中。

然后,您可以将所需的语言传递给该组件,然后将该组件导入到所需的页面上。

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

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

export default Language
Run Code Online (Sandbox Code Playgroud)

该 html 位将被注入到<html>标签内。

请注意,即使我们像这样注入它,控制台也会记录以下错误:TypeError: n is null

  • 我在控制台上收到此错误:head-manager.js?0ea4:2 警告:next-head-count 丢失。https://err.sh/next.js/next-head-count-missing。无论哪种情况,这种历史都不是一条出路。 (8认同)
  • 另请注意,Html 标记是 Head 标记的父标记。我不认为 Head 组件意味着以这种方式使用。 (7认同)
  • @GabrielLinassi,这与[文档](https://nextjs.org/docs/advanced-features/custom-document)中的不太一样,它说你应该在_document中执行此操作。在其他地方执行此操作从技术上讲是可行的,尽管您可能不能依赖它来继续工作,并且它会导致控制台出现“警告:下一个头计数丢失”,如上所述。 (7认同)

小智 8

在“pages”文件夹中创建_document.js并使用:

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;
Run Code Online (Sandbox Code Playgroud)

供本地化使用next.config.js

{
 i18n: {
    locales: ['en', 'fr', 'de',],
    defaultLocale: 'en',
  },
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*das 7

Next 10 支持国际化路由,并将lang动态添加给您:

<Html>
  <Head />
  <body>       
    <Main />
    <NextScript />
  </body>
</Html>
Run Code Online (Sandbox Code Playgroud)

  • 对于未来的读者,如果您通过“next export”使用 SSG - [参考](https://github.com/vercel/next.js/issues/9160#issuecomment-752713231) 和 [文档](https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static- Generation) (9认同)

小智 6

我通过将其添加到 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' }
Run Code Online (Sandbox Code Playgroud)

我不需要创建自定义 _document.js


Mig*_*Slv 0

使用文档对象,可以像这样设置 lang 属性:

var language= ...
switch (language) {
    case en:  document.documentElement.lang = 'en-us'; break;
    ...
}
Run Code Online (Sandbox Code Playgroud)

在页面水合之前,不会在初始 html 上设置此 lang 属性,但仍会通过 chrome“hreflang”审核检查。