静态生成的 Next.js 页面中的动态 HTML lang 属性

Mar*_*ner 6 reactjs next.js

我正在 Next.Js 项目中开发多语言静态登录页面。我的目标是具有以下结构:

  • / -> 英文主页
  • /de -> 德语主页
  • /it -> 意大利语主页

我按以下方式构建它:

页面/index.js

export default function Home() {
  return <div>English Homepage</div>
}
Run Code Online (Sandbox Code Playgroud)

页面/de.js

export default function Home() {
  return <div>German page</div>
}
Run Code Online (Sandbox Code Playgroud)

为了使网站可以访问,我想相应地设置 html lang。

页面/_document.js

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

  render() {
    return (
      <Html lang={???}>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

如何指定每页的语言?我尝试过getInitialProps,但这迫使我的网站成为 SSR。

Han*_*dev 5

您的使用确实是正确的getInitialPropsgetInitialProps与普通页面中禁用自动静态优化不同, getInitialPropsin_document.js没有这样的效果。

这是因为Document仅在服务器中呈现。DocumentgetInitialProps函数不会在客户端转换期间调用,也不会在页面静态优化时调用。更多关于其技术细节

这就是为什么您可以使用它向页面注入lang道具,并且仍然可以获得静态优化的好处。

// _document.js
...
static async getInitialProps(ctx) {
  const initialProps = await Document.getInitialProps(ctx);
  const { pathname } = ctx;
  const lang = pathname.startsWith("/de") ? "de" : "en";
  return { ...initialProps, lang };
}
...
Run Code Online (Sandbox Code Playgroud)

lang在客户端转换期间也更新该属性,您还必须设置一个useRouter挂钩_app.js来观察路由更改:

// _app.js
import React, { useEffect } from "react";
import { useRouter } from "next/router";

export default function MyApp({ Component, pageProps }) {
  const { pathname } = useRouter();
  const lang = pathname.startsWith("/de") ? "de" : "en";
  useEffect(() => {
    document.documentElement.lang = lang;
  }, [lang]);

  return <Component {...pageProps} />;
}
Run Code Online (Sandbox Code Playgroud)

我为您创建了这个 CodeSandbox 作为演示。

编辑dynamic-html-lang-property-in-statically- generated-next-js-pages

将其下载到本地计算机并检查代码。之后npm install,跑npm run build。您将从构建日志中看到“/”和“de”都是静态的。运行npm start并查看页面源代码,您将看到langHTML 中的属性已正确设置。