如何创建具有多语言路线的一页网站?

Posted

技术标签:

【中文标题】如何创建具有多语言路线的一页网站?【英文标题】:How to create one page site with multi languages routes? 【发布时间】:2021-03-24 23:12:47 【问题描述】:

我正在使用Gatsby,我想使用多语言创建一个站点,到目前为止,我已经定义了pages/index.js,其中包含以下内容:

import React from "react"
import Layout from "../components/layout/layout"

import BGTState from "../context/bgt/bgtState"
import  Router  from "@reach/router"
import Home from "../components/pages/home"
import Collection from "../components/pages/collection"
import NotFound from "../components/pages/404"

const IndexPage = () => 
  return (
    <BGTState>
      <Layout>
        <Router>
          <Home path="/" />
          <Collection path="collection/:id" />
          <NotFound default />
        </Router>
      </Layout>
    </BGTState>
  )


export default IndexPage

我已将gatsby-node.js 修改为:

// Implement the Gatsby API onCreatePage. This is
// called after every page is created.
exports.onCreatePage = async ( page, actions ) => 
  const  createPage  = actions

  if (page.path === "/") 
    page.matchPath = "/*"
    createPage(page)
  

每个请求都转发到index.js,但是有问题。我正在使用插件gatsby-plugin-intl,它会在 url 中添加一个动态前缀,例如:http://localhost:3001/en/

如果我访问http://localhost:3001/en/,则会显示NotFound 组件,因为没有与url 匹配的路由。有没有办法为 url 添加前缀并将所有内容重新路由到正确的组件?

【问题讨论】:

【参考方案1】:

为什么你使用client-only 路由/将所有内容包装在&lt;Router&gt; 中?

我不知道在您的方案中更改 gatsby-node.js 的目标是:

// Implement the Gatsby API onCreatePage. This is
// called after every page is created.
exports.onCreatePage = async ( page, actions ) => 
  const  createPage  = actions

  if (page.path === "/") 
    page.matchPath = "/*"
    createPage(page)
  

如果您不使用仅限客户端的路由,则可以将其删除。

这是一个宽泛的问题,但只需定义您的语言和翻译文件即可。在你的gatsby-config.js:

plugins: [
  
    resolve: `gatsby-plugin-intl`,
    options: 
      // language JSON resource path
      path: `$__dirname/src/intl`,
      // supported language
      languages: [`en`,`es`],
      // language file path
      defaultLanguage: `en`,
      // option to redirect to `/en` when connecting `/`
      redirect: true,
    ,
  ,
]

useIntl 钩子将捕获内部请求,因此,您只需要担心视图,忘记路由:

import React from "react"
import  useIntl, Link, FormattedMessage  from "gatsby-plugin-intl"

const IndexPage = () => 
  const intl = useIntl()
  return (
    <Layout>
      <SEO title=intl.formatMessage( id: "title" )/>
      <Link to="/page-2/">
       <FormattedMessage id="go_page2" />
      </Link>
    </Layout>
  )

export default IndexPage

您的Collection 组件应该是一个页面,包含在/page 文件夹中,或者是具有特定ID 的自定义集合。如果是 page is dynamically created,您应该在 gatsby-node.js 中管理自定义,在这种情况下,它应该是该场景中的集合模板。

要在页面之间链接,我建议使用page-queries 来获取创建组件所需的数据。您的页面应如下所示:

const IndexPage = () => 
  return (
    <BGTState>
      <Layout>
        <Link to="/"> // home path
        <Link to="collection/1">
      </Layout>
    </BGTState>
  )


export default IndexPage

404 页面将由 Gatsby 自动处理,重定向所有错误请求(开发中将显示页面列表)。您的其他路由应使用内置的 &lt;Link&gt; 组件(从 React 的 @reach/router 扩展)进行管理。

如我所说,要使&lt;Link to="collection/1"&gt; 链接动态化,您应该进行页面查询,以获取正确的链接以从您的数据中构建自定义动态&lt;Link&gt;

一旦您安装了gatsby-plugin-intl 插件,您的所有页面都会自动添加前缀,但是,要使用&lt;Link&gt;navigate 指向它们,您需要获取当前语言并为其添加前缀:

export const YourComponent = props => 
  const  locale  = useIntl(); // here you are getting the current language

  return <Link to=`$locale/your/path`>Your Link</Link>;
;

因为useIntl()是插件提供的自定义钩子,所以locale的值会随着你改变语言而自动设置。

【讨论】:

抱歉回复晚了,我的目标是创建一个单页应用程序,我遵循了这个教程:https://aravindballa.com/writings/gatsby-single-page-app/。所以一切都由index.js管理,但实际上url中的语言前缀没有处理... 使用我提供的gatsby-plugin-intl 插件,然后使用锚链接。这将为所有页面添加基于包含/排除规则提供的语言的前缀。由于您只有一页,因此适合您。 我已经使用 gatsby-plugin-intl 但是当我定义这样的链接时:&lt;Link to=/categories/$ctg.slug&gt;test&lt;/Link&gt; 我有这个:&lt;a href="/categories/archive"&gt;&lt;p class="bg-title--l text-white"&gt;archivio&lt;/p&gt;&lt;/a&gt; 但应该是 @987654352 @ 那为什么不加语言前缀呢? 我已经添加了解释。基本上,您需要始终使用const locale = useIntl() 为所有链接添加前缀。因为它是一个钩子,所以这个值会随着您更改网站的语言而改变,因此您的所有链接都会继续工作。 不,更改所有链接不是一个好习惯。在这种情况下,它对您使用 SPA 的用例很有用,但您需要使用这种方法手动更改它。当然,您可以创建一个解析和包装所有内容的函数以添加locale,但您需要开发它。

以上是关于如何创建具有多语言路线的一页网站?的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何创建一个多语言网站

Kentico多语言网站

Laravel 5 多语言网站,网址中带有语言前缀

使用 django 创建多语言网站

如何在单个EXE中嵌入多语言* .resx(或* .resources)文件?

网站多语言切换插件