使用 Gatsby 和 Strapi 进行国际化的最佳方式

jul*_*nsl 9 internationalization reactjs graphql strapi gatsby

在我的公司,我们正在使用 Gatsby 框架和 Strapi headless CMS 构建一个静态网站。

我的问题是如何处理i18n?

首先,我知道这是一个困难的问题,没有一个答案,而是根据上下文不同的答案。所以,我将继续我的研究,希望你能帮助我结束这个话题。:)

第一个想法,最简单的,让我们搜索一个插件!

有一个:gatsby-source-strapi-localized

不幸的是,它没有维护,所以,我不会使用它。:'(

好的,第二件事,让我们看看 Strapi 的建议!

Strapi 目前没有 i18n 功能,计划在 2020 年底在路线图上提供

但是有一个变通方法,在字段末尾使用后缀: medium article(同样的想法,您也可以直接为您的类型添加后缀)

所以,现在我们有了字段或类型的后缀,让我们进入第三部分,Gatsby!

这是一场噩梦。XD

实际上,有不同的解决方案可以解决这个问题,但我没有找到我的。:'(

我找到了这篇关于新 i18n gatsby 主题的文章。我下载了启动器以尝试了解它是如何工作的。我的理解是,由于createPage功能,博客页面会以 2 种不同的语言自动生成。创建了 2 个 mdx 文件来存储数据,LocalizedLink组件用于重定向。

这很有趣,但它不太适合我的问题。那么,让我们告诉你我的想法:

剧透警告!:我不熟悉 i18n 的 React 包,我今天早上才发现它们,这就是为什么我可能没有看到答案 ^^'

第一件事是“如何创建好的网址?”为此,我必须选择:

  1. 在我的页面部分创建 2 个文件夹,一个 FR 和一个 EN,它将添加到我的 URL (mySite.org/FR) 中
  2. 使用gatsby-plugin-i18n,它允许您创建 index.fr.js 和 index.en.js 以生成 mySite.org/fr 或 mySite.org/en

之后,在每个文件中,我可以自定义查询以使用良好的语言询问数据:

allStrapiHomePage {
  edges {
    node {
      mainBanner {
        title_lang
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

或者 :

allStrapiHomePage_lang {
  edges {
    node {
      mainBanner {
        title
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

对于重定向,我可以检查上下文以了解我所在的页面。

我不喜欢的事情是,每页我将有 2 个文件,仅用于查询,页面的其余部分是相同的:/

所以,问题是:如何使用正确的 URL 和正确的查询为每页生成 2 页?(你有 2 小时 è__é....XD)

createPage功能允许您通过在上下文中的变量,它可以帮助我查询。我也可以修改路径,这可以帮助我获取 URL。但是文件夹页面已经由 Gatsby 处理了......我无法修改该过程。

有没有人想澄清这个话题?:)

jul*_*nsl 1

我发现这个话题有点受欢迎,但我从来没有写过答案,让我们解决这个问题!

我不知道它如何与新版本的 Strapi 一起使用,但我们有针对 Strapi 3.0.1 的解决方案:

Strapi 中的每个页面都有两种类型:

  • 主页
  • 首页_CN
  • 关于
  • 关于_En
  • ...

当然,它们具有相同的架构。

在我的 gatsby Pages 文件夹中,我们创建了两个子文件夹:

  • FR
  • zh

在每个文件夹中,您都有所有页面,但是,技巧是:它们在这里只是为了从 Strapi 获取正确的数据,让我们看一个示例:

fr/about.js :

import React from "react"
import { graphql } from "gatsby"
import _get from "lodash/get"
import AboutPage from "../../components/pageComponents/About.js"

export default function About({ data }) {
  const BannerAbout = _get(
    data,
    "allStrapiAbout.edges[0].node.Banner.BackgroundImage.childImageSharp.fluid"
  )
  const TitleBannerAbout = _get(
    data,
    "allStrapiAbout.edges[0].node.Banner.Title"
  )
  const DescriptionBannerAbout = _get(
    data,
    "allStrapiAbout.edges[0].node.Banner.Description"
  )

  return (
    <AboutPage
      BannerAbout={BannerAbout}
      TitleBannerAbout={TitleBannerAbout}
      DescriptionBannerAbout={DescriptionBannerAbout}
    />
  )
}

export const query = () => graphql`
  query {
    allStrapiAbout {
      edges {
        node {
          Banner {
            Title
            Description
            BackgroundImage {
              childImageSharp {
                fluid(maxWidth: 1920) {
                  ...GatsbyImageSharpFluid_withWebp_tracedSVG
                }
              }
            }
          }
        }
      }
    }
  }
`
Run Code Online (Sandbox Code Playgroud)

英语部分也有同样的想法:

en/about.js :

import React from "react"
import { graphql } from "gatsby"
import _get from "lodash/get"
import AboutPage from "../../components/pageComponents/About.js"

export default function About({ data }) {
  const BannerAbout = _get(
    data,
    "allStrapiAboutEn.edges[0].node.Banner.BackgroundImage.childImageSharp.fluid"
  )
  const TitleBannerAbout = _get(
    data,
    "allStrapiAboutEn.edges[0].node.Banner.Title"
  )
  const DescriptionBannerAbout = _get(
    data,
    "allStrapiAboutEn.edges[0].node.Banner.Description"
  )

  return (
    <AboutPage
      BannerAbout={BannerAbout}
      TitleBannerAbout={TitleBannerAbout}
      DescriptionBannerAbout={DescriptionBannerAbout}

    />
  )
}

export const query = () => graphql`
  query {
    allStrapiAboutEn {
      edges {
        node {
          Banner {
            Title
            Description
            BackgroundImage {
              childImageSharp {
                fluid(maxWidth: 1920) {
                  ...GatsbyImageSharpFluid_withWebp_tracedSVG
                }
              }
            }
          }
        }
      }
    }
  }
`
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,他们正在调用相同的 React 组件,这是完整的“关于”页面的组件(当然还有很多子组件),位于组件文件夹中。

因此,之后,您只需使用正确的 props 编写一次代码即可。

它并不完美,但它对我有用,而且我们没有重复的逻辑代码:)

还有一点提示:要小心您的图像数组,两种语言之间经常存在相同的图像,为此使用集合类型而不是上传两次可能会很有趣。

如果其他人有想法,请随时写下您的提示;)

祝大家有美好的一天,别担心,编码快乐!