如何在 NextJs Document 上动态设置 HTML lang 属性?
Posted
技术标签:
【中文标题】如何在 NextJs Document 上动态设置 HTML lang 属性?【英文标题】:How to set HTML lang attribute dynamically on NextJs Document? 【发布时间】:2020-08-02 06:28:48 【问题描述】:我有一个多语言网站,需要根据每个页面的语言设置 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>
)
更新: 从页面路由可以推断出每个页面的语言
【问题讨论】:
【参考方案1】:Next 10 支持Internationalized Routing 并将动态添加lang
,为您留下:
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
【讨论】:
【参考方案2】:如果您使用next/head,您可以将语言设置为html标签。您传递给 Head 组件的任何内容都将放置在 或 中。
Next Head 的工作方式类似于 React Helmet,因此对于您的情况,您可以按照以下方式进行操作:
创建一个组件并从“next/head”导入Head 在 Head 标记内,您将 添加到组件中。然后您可以将所需的语言传递给该组件,然后在所需的页面上导入该组件。
import React from "react"
import Head from "next/head"
const Language = (title, lang) => (
<Head>
<html lang=lang />
<title>title</title>
</Head>
)
export default Language
该 html 位将被注入到标签内。
请注意,即使我们像这样注入它,控制台也会记录以下错误:TypeError: n is null
。
【讨论】:
我在控制台上收到此错误:head-manager.js?0ea4:2 警告:缺少下一个头数。 err.sh/next.js/next-head-count-missing。在任何一种情况下,该组织都不是可行的方法。 还要注意 Html 标签是 Head 标签的父标签。我不认为 Head 组件意味着以这种方式使用。 谢谢,这是正确的答案。与 nextjs 文档中提供的相同。 @GabrielLinassi,这与docs 中的不完全相同,它说您应该在_document 中执行此操作。在其他地方做技术上是可行的,但也许你不能依靠它来继续工作,并且它会让控制台减弱Warning: next-head-count is missing
如上所述。
@ArneHugo 没错。感谢您的指正。我在这里检查了我的代码,它也在 _document 上定义。【参考方案3】:
我认为这里最好的解决方案是使用自定义 ./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
更多解释可以在这里找到:https://nextjs.org/docs/advanced-features/custom-document
【讨论】:
【参考方案4】:使用文档对象的 lang 属性可以这样设置:
var language= ...
switch (language)
case en: document.documentElement.lang = 'en-us'; break;
...
这个 lang 属性不会在初始 html 上设置,在页面水合之前,但仍会通过 chrome "hreflang" 审计检查。
【讨论】:
【参考方案5】:我通过将它添加到 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'
我不需要创建自定义 _document.js
【讨论】:
【参考方案6】:您可以使用 React useEffect 挂钩来设置文档的语言,而无需更改 Next.js 自身生成 HTML 标记的方式。
在您的页面组件或其他适当的组件中,包含 useEffect 挂钩:
import useEffect from "react";
然后加上钩子:
const MyPage = () =>
useEffect(() =>
document.documentElement.lang = "en-us";
);
// The rest of your component
这通过了 Lighthouse 对“hreflang”的检查,如果您的网站有多种语言,您可以使用它来设置每个页面的页面语言。
【讨论】:
【参考方案7】:要覆盖默认的 nextjs 设置,请创建文件 ./pages/_document.js 并扩展 Document 类,如下所示:
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>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
export default MyDocument
允许自定义属性作为 props,例如 lang:
<Html lang="en">
您可以在此处阅读有关自定义文档的更多信息:https://nextjs.org/docs/advanced-features/custom-document
【讨论】:
以上是关于如何在 NextJs Document 上动态设置 HTML lang 属性?的主要内容,如果未能解决你的问题,请参考以下文章