javascript - 如何创建具有多语言路线的一页网站?
问题描述
我正在使用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
显示组件,因为没有 Route 与 url 匹配。有没有办法为 url 添加前缀并将所有内容重新路由到正确的组件?
解决方案
为什么您使用仅限客户端的路由/将所有内容包装在<Router>
?
我不知道你的场景中改变的目标是什么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 的自定义集合。如果该页面是动态创建的,您应该管理您的自定义gatsby-node.js
,并且在这种情况下,它应该是该场景中的集合模板。
要在页面之间链接,我建议使用页面查询来获取创建组件所需的数据。您的页面应如下所示:
const IndexPage = () => {
return (
<BGTState>
<Layout>
<Link to="/"> // home path
<Link to="collection/1">
</Layout>
</BGTState>
)
}
export default IndexPage
404 页面将由 Gatsby 自动处理,重定向所有错误请求(开发中将显示页面列表)。您的其他路由应使用内置组件(从 React<Link>
扩展)进行管理。@reach/router
如我所说,要使链接动态化<Link to="collection/1">
,您应该进行页面查询,以获取正确的链接以<Link>
从您的数据中构建自定义动态。
安装gatsby-plugin-intl
插件后,您的所有页面都会自动添加前缀,但是要使用它们指向它们,<Link>
或者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
更改语言时会自动设置 的值。
推荐阅读
- racket - 球拍清单问题
- reactjs - React:使用 setState 竞争条件从 firebase 获取数据并存储
- r - 预测包外的分段 lm
- firefox - Firefox 无法打开“libgtk-3.so.0”。如何规避?
- javascript - 带有 chrome 扩展工具的 Winston 记录器
- javascript - 如何在html中多次重复相同的图像?
- json - 每个 Mongo 文档的唯一道具是错误的形式还是会降低性能?
- android - CrashlyticsListener 不是由 JNI 中的崩溃触发的
- git - 如何向最后一个未推送的提交添加新更改?
- android - 在 Android 上转换音频文件