как использовать i18n для Гэтсби? - PullRequest
0 голосов
/ 17 декабря 2018

У меня проблема с переводами на моем сайте gatsby.

Я использую плагин i18n для выполнения переводов, но если я добавлю свой тег index.jsx два FormattedMessage, он сломает мой index.jsx.

Я могу найти свою проблему в Google, но не могу понять, как ее решить.

Мой index.jsx

import React from 'react'
import { FormattedMessage } from 'react-intl'

import Layout from '../components/Layout'


const IndexPage = ({ pathContext: { locale } }) => (
  <Layout locale={locale}>
    <FormattedMessage id="hello" />
    <FormattedMessage id="hello" />
  </Layout>
)

export default IndexPage

и мой макет:

import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { StaticQuery, graphql } from 'gatsby'

import Header from './header'
import './layout.css'

import { IntlProvider, addLocaleData } from 'react-intl'

// Locale data
import enData from 'react-intl/locale-data/en'
import ptData from 'react-intl/locale-data/pt'
import esData from 'react-intl/locale-data/es'

// Messages
import en from '../i18n/en.json'
import pt from '../i18n/pt.json'
import es from '../i18n/es.json'

const messages = { en, pt, es }

addLocaleData([...enData, ...ptData, ...esData])

const Layout = ({ locale, children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Helmet
          title={data.site.siteMetadata.title}
          meta={[
            { name: 'description', content: 'Sample' },
            { name: 'keywords', content: 'sample, something' },
          ]}
        >
          <html lang="en" />
        </Helmet>
        <Header lang="/^\/eng/" />
        <div
          style={{
            margin: '0 auto',
            maxWidth: 960,
            padding: '0px 1.0875rem 1.45rem',
            paddingTop: 0,
          }}
        >
          <IntlProvider locale={locale} messages={messages[locale]}>
            {children}
          </IntlProvider>
        </div>
      </>
    )}
  />
)

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

Надеюсь, вы не можете помочь мне использовать более одного тега FormattedMessage для переводов, спасибо.

1 Ответ

0 голосов
/ 13 февраля 2019

Возможно, это неправильное решение для вас, но .. Вы пробовали gatsby-plugin-i18next ?Мои первые проекты с gatsbyjs - это была кошмарная сделка с языками, пока я ее не нашел.На мой взгляд, это работает действительно хорошо.Вы должны установить с помощью npm / yarn и немного настроить.Вы можете удалить обертку IntlProvider и выполнять переводы в любом месте (страницы / шаблоны или компоненты).

Здесь и пример извлечен из вашего кода (английский и испанский языки).Плагин заботится о URL, помещая / es & / en на каждой странице / шаблоне:

src / pages / index.jsx

import React from 'react'; 
import { I18n } from 'react-i18next'; 
import { withI18next } from 'gatsby-plugin-i18next';
import Layout from '../components/index'

const IndexPage = props => (<I18n>{t => (
    <Layout{...props}>
        <p>{t('hello')}</p>
        <p>{t('hello')}</p>
    </Layout>
)}</I18n>);

export const query = graphql`
query($lng: String!){
    locales: allLocale(filter: { lng: { eq:$lng }, ns: { eq: "messages" } }) {
      ...TranslationFragment
    }
  }
`;

export default withI18next()(IndexPage);

src / components / index.jsx

Обратите внимание, что вы также должны изменить шлем.Я перевожу метаданные, чтобы показать, как можно переводить в компонентах (не на страницах и не в шаблонах).

import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { Head } from 'gatsby-plugin-i18next';
import { StaticQuery, graphql } from 'gatsby'

import Header from './header'
import './layout.css'

const Layout = ({children, t }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Head hreflang>
           <title>{data.site.siteMetadata.title}</title>
           <meta name="description" content="{t('metaDescription')}" />
           <meta name="keywords" content="{t('metaKeywords')}" />
        </Head>
        <Header lang="/^\/eng/" />
        <div
          style={{
            margin: '0 auto',
            maxWidth: 960,
            padding: '0px 1.0875rem 1.45rem',
            paddingTop: 0,
          }}
        >
        {children}
        </div>
      </>
    )}
  />
)

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default translate()(Layout)

gatsby-config.js Вы можете отлаживать плагин только во время разработки;)

const defaultLanguage = "en";
const languages: ["en", "es"];
const siteUrl: "https://domain-where-the-gatsby-are-published.com/",

module.exports = {
    ...,
    plugins: [
        ...,
        {
            resolve: `gatsby-plugin-i18next`,
            options: {
                availableLngs: languages,
                fallbackLng: defaultLanguage,
                debug: process.env.NODE_ENV === 'development',
                siteUrl
            },
        }
    ],
}

locale / en / messages.json

{
  "hello": "Hi!",
  "metaDescription": "Sample page with i18n translations",
  "metaKeywords": "i18n, gatsbyjs, english"
}

locale / es / messages.json

{
  "hello": "Hola!",
  "metaDescription": "Página de ejemplo con traducciones i18n",
  "metaKeywords": "i18n, gatsbyjs, spanish"
}

В качестве дополнительных комментариев:

  • Не забудьте изменить все ссылки, импортированные из gatsby на gatsby-plugin-i18next
  • Вы должны вводить запрос graphql на каждой странице / шаблоне
  • Вы можете увидеть код starter , чтобы увидеть, как вы можете создать переключатель между языками
...