如何使用i18n到盖茨比?

时间:2018-12-17 16:46:55

标签: reactjs gatsby i18next

我在盖茨比(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 :(得分:1)

也许对您来说不是有效的解决方案,但是..您尝试过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的代码,以了解如何在两种语言之间创建切换器