Gatsby와 Contentful이 포함된 다국어 웹사이트 - 2부

⚠️ 때때로 graphQL이 intl에 있는 intl 데이터를 찾지 못하는 경우가 있습니다. gatsby clean 명령을 실행하여 캐시를 제거하세요 🙂

전제 조건


  • 튜토리얼의 첫 번째 부분이 작동해야 합니다! 우리는 이전에 Gatsby와 Contentful을 함께 연결했습니다 🙂




  • 반응 국제 설정



    먼저 웹 사이트 번역을 제공하는 react-intl 기반 플러그인을 설치해야 합니다.

    ⚠️ 저는 프랑스인이므로 다른 로케일을 fr로 정의합니다.
  • 플러그인 설치: npm install --save gatsby-plugin-intl
  • 이제 구성 파일을 구성합니다. gatsby-config.js

  • {
        resolve: `gatsby-plugin-intl`,
        options: {
            // language JSON resource path
            path: `${__dirname}/src/intl`,
            // supported language
            languages: [`en`, `fr`],
            // language file path
            defaultLanguage: `en`,
            // option to redirect to `/en` when connecting `/`
            redirect: true,
        },
    },
    


  • intl 폴더를 src에 만들고 로케일에 해당하는 두 개의 파일을 만들 수 있습니다.

  • // src/intl/en.json
    {
        "title": "Gatsby English",
        "description": "Project description",
        "author": "@louisbertin",
        "hello": "Hi people!",
        "welcome": "Welcome to your new Gatsby site.",
        "title_page2": "Page two",
        "hello_page2": "Hi from the second page",
        "go_page2": "Go to page 2",
        "welcome_page2": "Welcome to page 2",
        "go_back": "Go back to the homepage",
        "footer_build": "Built with",
        "notfound": {
            "header": "NOT FOUND",
            "description": "You just hit a route that doesn't exist... the sadness."
        }
    }
    



    // src/intl/fr.json
    {
        "title": "Gatsby French",
        "description": "Project description",
        "author": "@louisbertin",
        "hello": "Salut les gens!",
        "welcome": "Bienvenue sur votre nouveau site Gatsby",
        "title_page2": "Page deux",
        "hello_page2": "Salut depuis la seconde page",
        "go_page2": "Aller à la page 2",
        "welcome_page2": "Bienvenue sur la page 2",
        "go_back": "Retour à la page d'accueil",
        "footer_build": "Construit avec",
        "notfound": {
            "header": "NOT FOUND",
            "description": "Vous voulez accéder à une route qui n'existe pas..."
        }
    }
    


    다국어 블로그 구축


  • intl 폴더에 있는 모든 키를 사용하려면 react-intl과 함께 작동하도록 모든 반응 구성 요소와 페이지를 변경해야 합니다. 인덱스 페이지로 예를 들어 보겠습니다.

  • // pages/index.js
    import React from "react"
    import { graphql } from "gatsby"
    
    import Layout from "../components/layout"
    import SEO from "../components/seo"
    
    import { injectIntl, Link, FormattedMessage } from "gatsby-plugin-intl"
    
    const IndexPage = ({ data, intl }) => (
        <Layout>
            <SEO title={intl.formatMessage({ id: "title" })} />
            <h1>
              <FormattedMessage id="hello" />
            </h1>
            <p>
              <FormattedMessage id="welcome" />
            </p>
    
            <br />
            <Link to="/page-2">
              <FormattedMessage id="go_page2" />
            </Link>
          </Layout>
    )
    
    export const query = graphql `
          query ContentFulPosts($locale: String) {
            allContentfulPost(filter: { node_locale: { eq: $locale } }) {
              nodes {
                contentful_id
                title
                path
              }
            }
          }
    `
    
    export default injectIntl(IndexPage)
    


    그리고 구성 요소 페이지로 🙂

    import React from "react"
    import PropTypes from "prop-types"
    import { useStaticQuery, graphql } from "gatsby"
    
    import Header from "./header"
    import "./layout.css"
    
    import { injectIntl, FormattedMessage } from "gatsby-plugin-intl"
    
    const Layout = ({ children, intl }) => {
      const data = useStaticQuery(graphql`
        query SiteTitleQuery {
          site {
            siteMetadata {
              title
            }
          }
        }
      `)
    
      return (
        <>
          <Header siteTitle={data.site.siteMetadata.title} />
          <div
            style={{
              margin: `0 auto`,
              maxWidth: 960,
              padding: `0px 1.0875rem 1.45rem`,
              paddingTop: 0,
            }}
          >
            <main>{children}</main>
            <footer>
              © {new Date().getFullYear()}, <FormattedMessage id="footer_build" />{" "}
              {` `}
              <a href="https://www.gatsbyjs.org">Gatsby</a>
            </footer>
          </div>
        </>
      )
    }
    
    Layout.propTypes = {
      children: PropTypes.node.isRequired,
    }
    
    export default injectIntl(Layout)
    


  • 데이터를 검색하기 전에 블로그 게시물 템플릿을 만들어야 합니다. 이 템플릿은 올바른 데이터를 얻기 위해 현재 로케일을 가져와야 합니다.

  • import React from "react"
    import { graphql } from "gatsby"
    
    import Layout from "../components/layout"
    
    const BlogPost = ({ pageContext, data }) => (
        <Layout>
            <h1>{data.contentfulPost.title}</h1>
          </Layout>
    )
    
    export const query = graphql `
          query ContentFulPost($slug: String, $locale: String) {
            contentfulPost(path: { eq: $slug }, node_locale: { eq: $locale }) {
              path
              node_locale
              title
            }
          }
        `
    
    export default BlogPost
    


  • 이제 gatsby-node 파일을 사용하여 각 로케일에 대한 게시물 페이지를 생성할 차례입니다!

  • const path = require(`path`)
    
    // pages locale
    exports.onCreatePage = ({ page, actions }) => {
        const { createPage, deletePage } = actions
        deletePage(page)
        // You can access the variable "locale" in your page queries now
        createPage({
            ...page,
            context: {
                ...page.context,
                locale: page.context.intl.language,
            },
        })
    }
    
    // blog posts
    exports.createPages = ({ graphql, actions }) => {
        const { createPage } = actions
        const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)
        // Query for markdown nodes to use in creating pages.
        // You can query for whatever data you want to create pages for e.g.
        // products, portfolio items, landing pages, etc.
        // Variables can be added as the second function parameter
        return graphql(
            `
              query MyQuery {
                allContentfulPost {
                  edges {
                    node {
                      path
                    }
                  }
                }
              }
            `
        ).then(result => {
            if(result.errors) {
                throw result.errors
            }
    
            // Create blog post pages.
            result.data.allContentfulPost.edges.forEach(edge => {
                const path = edge.node.path
    
                createPage({
                    // Path for this page — required
                    path: path,
                    component: blogPostTemplate,
                    context: {
                        slug: path,
                    },
                })
            })
        })
    }
    


  • 그런 다음 인덱스에서 graphQL 쿼리를 업데이트하여 올바른 게시물을 표시합니다.

  • export const query = graphql `
          query ContentFulPosts($locale: String) {
            allContentfulPost(filter: { node_locale: { eq: $locale } }) {
              nodes {
                contentful_id
                title
                path
              }
            }
          }
    


  • 마지막으로 게시물에 액세스할 수 있고 다국어가 작동하는 것 같습니다. 하지만 필요한 모든 것을 테스트하려면 언어 전환기가 있어야 합니다!
    따라서 Language.js라는 구성 요소를 만들고 프로젝트의 components 폴더에 배치합니다.

  • import React from "react"
    import { IntlContextConsumer, changeLocale } from "gatsby-plugin-intl"
    
    const languageName = {
      en: "English",
      fr: "Français",
    }
    
    const Language = () => (
      <div>
        <IntlContextConsumer>
          {({ languages, language: currentLocale }) =>
            languages.map(language => (
              <a
                key={language}
                onClick={() => changeLocale(language)}
                style={{
                  color: currentLocale === language ? `yellow` : `white`,
                  margin: 10,
                  textDecoration: `underline`,
                  cursor: `pointer`,
                }}
              >
                {languageName[language]}
              </a>
            ))
          }
        </IntlContextConsumer>
      </div>
    )
    
    export default Language
    


    예를 들어 헤더 구성 요소에서 언어 구성 요소를 호출할 수 있으며 모든 것이 작동해야 합니다!

    다음 포스트에서



    다음 게시물에서는 Netlify에 다국어 블로그를 배포하는 방법에 대해 설명하겠습니다!

    그건 그렇고, Github에서 내 코드를 찾을 수 있습니다!

    좋은 웹페이지 즐겨찾기