Как создать одностраничный сайт с многоязычными маршрутами?

Я использую 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-адреса и перенаправить все на правильный компонент?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
962
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Почему вы используете клиентские маршруты/обертываете все внутри <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 будет автоматически устанавливаться при смене языка.

извините за поздний ответ, моя цель - создать одностраничное приложение, я следовал этому руководству: https://aravindballa.com/writings/gatsby-single-page-app/. Так что всем управляет index.js, но на самом деле языковой префикс в URL не обрабатывается...

sfarzoso 15.12.2020 12:49

Используйте плагин gatsby-plugin-intl, который я предоставил, а затем используйте якорные ссылки. Это добавит префикс всех страниц к языкам, предоставленным на основе правила включения/исключения. Поскольку у вас будет только одна страница, она будет работать на вас.

Ferran Buireu 15.12.2020 13:00

Я уже использую 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>, так почему префикс языка не добавляется?

sfarzoso 15.12.2020 13:08

Я добавил объяснение. По сути, вам нужно всегда добавлять префикс ко всем ссылкам, используя const { locale } = useIntl(). Поскольку это хук, это значение будет меняться при изменении языка сайта, чтобы все ваши ссылки продолжали работать.

Ferran Buireu 15.12.2020 13:24

Возможно ли префикс всех ссылок автоматически?

sfarzoso 15.12.2020 15:22

Нет, не рекомендуется менять ВСЕ ссылки. В этом случае было бы полезно для вашего варианта использования использовать SPA, но вам нужно будет изменить его вручную, используя этот подход. Конечно, вы можете создать функцию, которая анализирует и упаковывает все, чтобы добавить locale, но вам нужно ее разработать.

Ferran Buireu 15.12.2020 15:51

хорошо, спасибо, не могли бы вы просто показать мне, как бы вы справились с такой ситуацией, используя такую ​​​​функцию, как помощник?

sfarzoso 15.12.2020 16:08

Другие вопросы по теме