如何创建具有多语言路线的一页网站?
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 路由/将所有内容包装在<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 的自定义集合。如果是 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 自动处理,重定向所有错误请求(开发中将显示页面列表)。您的其他路由应使用内置的 <Link>
组件(从 React 的 @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
的值会随着你改变语言而自动设置。
【讨论】:
抱歉回复晚了,我的目标是创建一个单页应用程序,我遵循了这个教程:https://aravindballa.com/writings/gatsby-single-page-app/
。所以一切都由index.js
管理,但实际上url中的语言前缀没有处理...
使用我提供的gatsby-plugin-intl
插件,然后使用锚链接。这将为所有页面添加基于包含/排除规则提供的语言的前缀。由于您只有一页,因此适合您。
我已经使用 gatsby-plugin-intl
但是当我定义这样的链接时:<Link to=
/categories/$ctg.slug>test</Link>
我有这个:<a href="/categories/archive"><p class="bg-title--l text-white">archivio</p></a>
但应该是 @987654352 @ 那为什么不加语言前缀呢?
我已经添加了解释。基本上,您需要始终使用const locale = useIntl()
为所有链接添加前缀。因为它是一个钩子,所以这个值会随着您更改网站的语言而改变,因此您的所有链接都会继续工作。
不,更改所有链接不是一个好习惯。在这种情况下,它对您使用 SPA 的用例很有用,但您需要使用这种方法手动更改它。当然,您可以创建一个解析和包装所有内容的函数以添加locale
,但您需要开发它。以上是关于如何创建具有多语言路线的一页网站?的主要内容,如果未能解决你的问题,请参考以下文章