如何使用 i18n 到 gatsby?

how to use i18n to gatsby?

我的 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标签进行翻译,谢谢

也许对您来说不是一个有效的解决方案,但是。你试过gatsby-plugin-i18next了吗?在我找到它之前,我使用 gatsbyjs 的第一个项目是一场噩梦般的语言交易。在我看来,它真的很好用。您必须使用 npm/yarn 安装它并进行一些配置。您可以删除包装器 IntlProvider 并且可以在任何需要的地方进行翻译(pages/templates 或组件)。

此处是从您的代码中提取的示例(英语和西班牙语)。该插件负责 URL,将 /es/en 放入每个 pages/templates:

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)

盖茨比-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
  • 您必须在每个 pages/templates
  • 中注入 graphql 查询
  • 您可以查看 starter 的代码,了解如何在语言之间创建切换器