Я использую 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-адреса и перенаправить все на правильный компонент?
🤔 А знаете ли вы, что...
JavaScript позволяет создавать собственные серверные приложения с использованием платформы Node.js.
Почему вы используете клиентские маршруты/обертываете все внутри <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
, или пользовательской коллекцией с определенным идентификатором. Если эта страница создается динамически, вы должны управлять настройками в своей 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>
(расширенного от @reach/router
из React).
Чтобы сделать ссылку <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
будет автоматически устанавливаться при смене языка.