Next.js高级特性:国际化路由

自以来,Next.js内置了对国际化(i18n)路由的支持v10.0.0。您可以提供语言环境,默认语言环境和特定于域的语言环境的列表,Next.js将自动处理路由。

目前的国际化路由支持旨在补充现有的国际化图书馆解决方案,如react-intlreact-i18nextlinguirosetta通过精简路线和区域分析,和其他人。

入门

首先,将i18n配置添加到next.config.js文件中。

语言环境是UTS语言环境标识符,一种用于定义语言环境的标准化格式。

通常,区域设置标识符由用破折号分隔的语言,地区和脚本组成language-region-script。区域和脚本是可选的。一个例子:

  • en-US -在美国使用的英语
  • nl-NL -在荷兰所说的荷兰语
  • nl -荷兰语,无特定区域
// next.config.js
module.exports = {
  i18n: {
    // These are all the locales you want to support in
    // your application
    locales: ['en-US', 'fr', 'nl-NL'],
    // This is the default locale you want to be used when visiting
    // a non-locale prefixed path e.g. `/hello`
    defaultLocale: 'en-US',
    // This is a list of locale domains and the default locale they
    // should handle (these are only required when setting up domain routing)
    // Note: subdomains must be included in the domain value to be matched e.g. "fr.example.com".
    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en-US',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl-NL',
      },
      {
        domain: 'example.fr',
        defaultLocale: 'fr',
      },
    ],
  },
}

区域策略

有两种语言环境处理策略:子路径路由和域路由。

子路径路由

子路径路由会将语言环境放在url路径中。

// next.config.js
module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'nl-NL'],
    defaultLocale: 'en-US',
  },
}

通过上述配置en-US,,frnl-NL可以被路由到,并且en-US是默认语言环境。如果您有pages/blog.js以下网址,则可以使用:

  • /blog
  • /fr/blog
  • /nl-nl/blog

默认语言环境没有前缀。

域路由

通过使用域路由,您可以配置要从不同域提供服务的语言环境:

// next.config.js
module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'nl-NL', 'nl-BE'],
    defaultLocale: 'en-US',

    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en-US',
      },
      {
        domain: 'example.fr',
        defaultLocale: 'fr',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl-NL',
        // specify other locales that should be redirected
        // to this domain
        locales: ['nl-BE'],
      },
    ],
  },
}

例如,如果您具有pages/blog.js以下网址,则将可用:

  • example.com/blog
  • example.fr/blog
  • example.nl/blog
  • example.nl/nl-BE/blog

自动区域设置检测

当用户访问应用程序根目录(通常为/)时,Next.js将尝试根据Accept-Language标头和当前域自动检测用户首选的语言环境。

如果检测到默认语言环境以外的语言环境,则用户将被重定向到以下任一位置:

  • 使用子路径路由时:语言环境前缀路径
  • 使用域路由时:指定该语言环境为默认域的域

使用域路由时,如果具有Accept-Language标头的用户fr;q=0.9访问example.com,则他们将被重定向到,example.fr因为该域fr默认处理语言环境。

使用子路径路由时,用户将被重定向到/fr

禁用自动区域设置检测

可以通过以下方式禁用自动区域设置检测:

// next.config.js
module.exports = {
  i18n: {
    localeDetection: false,
  },
}

localeDetection被设定为falseNext.js将不再自动重定向基于所述用户的首选区域和将只提供从任一区域设置基于域或如上所述区域设置路径检测区域设置信息。

访问语言环境信息

您可以通过Next.js路由器访问语言环境信息。例如,使用useRouter()钩子可以使用以下属性:

  • locale 包含当前活动的语言环境。
  • locales 包含所有配置的语言环境。
  • defaultLocale 包含配置的默认语言环境。

当使用或预先呈现页面时,在提供给函数的上下文中提供语言环境信息。getStaticPropsgetServerSideProps

利用时getStaticPaths,在函数的上下文参数中locales和在的defaultLocale中提供了配置的语言环境defaultLocale

语言环境之间的转换

您可以使用next/linknext/router在语言环境之间转换。

对于next/linklocale可以提供一个道具,以从当前活动状态过渡到其他区域。如果没有locale提供道具,locale则在客户端转换期间将使用当前活动的道具。例如:

import Link from 'next/link'

export default function IndexPage(props) {
  return (
    <Link href="/another" locale="fr">
      <a>To /fr/another</a>
    </Link>
  )
}

next/router直接使用方法时,可以locale通过转换选项指定应使用的方法。例如:

import { useRouter } from 'next/router'

export default function IndexPage(props) {
  const router = useRouter()

  return (
    <div
      onClick={() => {
        router.push('/another', '/another', { locale: 'fr' })
      }}
    >
      to /fr/another
    </div>
  )
}

如果您href已经包含一个语言环境,则可以选择不自动处理语言环境前缀:

import Link from 'next/link'

export default function IndexPage(props) {
  return (
    <Link href="/fr/another" locale={false}>
      <a>To /fr/another</a>
    </Link>
  )
}

利用NEXT_LOCALE Cookie

Next.js支持使用NEXT_LOCALE=the-localecookie覆盖accept-language标头。可以使用语言切换器来设置此cookie,然后,当用户返回网站时,它将在重定向/到正确的语言环境位置时利用cookie中指定的语言环境。

例如,如果用户fr在其accept-language标头中首选语言环境,但在访问时NEXT_LOCALE=en设置了cookie,则该用户将被重定向到语言环境位置,直到cookie被删除或过期。en/en

搜索引擎优化

由于Next.js知道用户正在访问哪种语言,它将自动将lang属性添加到<html>标签中。

Next.js不了解页面的变体,因此您可以hreflang使用来添加元标记next/head。您可以hreflangGoogle网站站长文档中了解更多信息。

静态生成如何工作?

请注意,国际化路由不会与之集成,next export因为next export不会利用Next.js路由层。next export完全支持不使用的混合Next.js应用程序。

自动静态优化页面

对于自动静态优化的页面,将为每个语言环境生成页面的版本。

非动态的getStaticProps页面

对于非动态getStaticProps页面,将像上面那样为每个语言环境生成一个版本。被渲染的getStaticProps每个对象locale都被调用。如果您希望退出某个区域设置而无法进行预渲染,则可以从中返回notFound: truegetStaticProps并且不会生成此页面的变体。

export async function getStaticProps({ locale }) {
  // Call an external API endpoint to get posts.
  // You can use any data fetching library
  const res = await fetch(`https://.../posts?locale=${locale}`)
  const posts = await res.json()

  if (posts.length === 0) {
    return {
      notFound: true,
    }
  }

  // By returning { props: posts }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  }
}

动态getStaticProps页面

对于动态getStaticProps页面,需要从中返回希望呈现的页面的任何语言环境变体getStaticPaths。除了params可以为返回的对象外paths,您还可以返回一个locale字段,该字段指定您要呈现的语言环境。例如:

// pages/blog/[slug].js
export const getStaticPaths = ({ locales }) => {
  return {
    paths: [
      { params: { slug: 'post-1' }, locale: 'en-US' },
      { params: { slug: 'post-1' }, locale: 'fr' },
    ],
    fallback: true,
  }
}

作者:terry,如若转载,请注明出处:https://www.web176.com/nextjs/2386.html

(0)
打赏 支付宝 支付宝 微信 微信
terryterry
上一篇 2021年4月7日 下午5:20
下一篇 2021年4月16日 下午6:11

相关推荐

发表回复

登录后才能评论