Javascript 如何创建具有多语言路由的单页站点?

Javascript 如何创建具有多语言路由的单页站点?,javascript,reactjs,graphql,gatsby,gatsby-plugin,Javascript,Reactjs,Graphql,Gatsby,Gatsby Plugin,我使用的是Gatsby,我想创建一个使用多语言的网站,到目前为止,我已经定义了pages/index.js,其中包含以下内容: import React from "react" import Layout from "../components/layout/layout" import BGTState from "../context/bgt/bgtState" import { Router } from "@rea

我使用的是
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
每个请求都在
index.js
上转发,但存在一个问题。我使用的插件
gatsby plugin intl
在url中添加了一个动态前缀,如:
http://localhost:3001/en/

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

为什么要在
中使用路由/包装所有内容

我不知道在您的场景中,用以下内容更改
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
404页面将由盖茨比自动处理,重定向所有错误请求(在开发中将显示页面列表)。您的其他路由应使用内置的
组件(从React的
@reach/router
扩展)进行管理

要创建动态
链接,正如我所说的,您应该进行页面查询,以获得适当的链接,从而从数据中构建自定义动态

安装了
gatsby plugin intl
插件后,所有页面都会自动加上前缀,但是,要使用
导航来指向这些页面,您需要获取当前语言并加上前缀:

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

  return <Link to={`${locale}/your/path`}>Your Link</Link>;
};
export const YourComponent=props=>{
const{locale}=useIntl();//这里是当前语言
返回你的链接;
};

由于
useIntl()
是插件提供的自定义钩子,因此当您更改语言时,
locale
的值将自动设置。

很抱歉,我的目标是创建一个单页应用程序,我遵循了本教程:
https://aravindballa.com/writings/gatsby-single-page-app/
。所以一切都是由
index.js
管理的,但实际上url中的语言前缀没有处理……使用我提供的
gatsby plugin intl
插件,然后使用锚链接。这将使用基于包含/排除规则提供的语言作为所有页面的前缀。因为你只有一个页面,这对你有用。我已经使用了
gatsby plugin intl
但是当我定义这样的链接时:
test
我有这样一个:
但是应该是
,那么为什么没有添加语言前缀呢?我已经添加了一个解释。基本上,您需要始终使用
const{locale}=useIntl()
作为所有链接的前缀。因为它是一个钩子,这个值会随着你改变网站的语言而改变,所以你所有的链接都会继续工作。不,改变所有的链接不是一个好的做法。在这种情况下,它对于使用SPA的用例非常有用,但是您需要使用这种方法手动更改它。当然,您可以创建一个解析和包装所有内容的函数来添加
区域设置
,但您需要开发它。
const IndexPage = () => {
  return (
    <BGTState>
      <Layout>
        <Link to="/"> // home path
        <Link to="collection/1">
      </Layout>
    </BGTState>
  )
}

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

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