Я использую 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 [JS]](https://i.imgur.com/WsjO6zJb.png)


Почему вы используете клиентские маршруты/обертываете все внутри <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 будет автоматически устанавливаться при смене языка.
Используйте плагин 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>, но должно быть <a href = "/en/categories/archive"><p class = "bg-title--l text-white">archivio</p></a>, так почему префикс языка не добавляется?
Я добавил объяснение. По сути, вам нужно всегда добавлять префикс ко всем ссылкам, используя const { locale } = useIntl(). Поскольку это хук, это значение будет меняться при изменении языка сайта, чтобы все ваши ссылки продолжали работать.
Возможно ли префикс всех ссылок автоматически?
Нет, не рекомендуется менять ВСЕ ссылки. В этом случае было бы полезно для вашего варианта использования использовать SPA, но вам нужно будет изменить его вручную, используя этот подход. Конечно, вы можете создать функцию, которая анализирует и упаковывает все, чтобы добавить locale, но вам нужно ее разработать.
хорошо, спасибо, не могли бы вы просто показать мне, как бы вы справились с такой ситуацией, используя такую функцию, как помощник?
извините за поздний ответ, моя цель - создать одностраничное приложение, я следовал этому руководству:
https://aravindballa.com/writings/gatsby-single-page-app/. Так что всем управляетindex.js, но на самом деле языковой префикс в URL не обрабатывается...