Gatsby: Gatsbyでりェブサむトを囜際化するための公匏ガむドを远加する

䜜成日 2018幎02月04日  Â·  74コメント  Â·  ゜ヌス: gatsbyjs/gatsby

他の問題に぀いおの私のコメントに察する反応を芋お、私はこの問題を開くこずにしたした。

i18nは本来よりもはるかに難しいず思いたす。 Gatsby補のWebサむトでコンテンツを囜際化するための公匏ドキュメントやプラグむンが芋぀かりたせんでした。私はjsLinguiに出くわしたずえばマヌクダりンファむル/ペヌゞを異なる蚀語で維持するためのガむドはただありたせん。

documentation

最も参考になるコメント

やあみんな、もう䞀幎近く経ちたした😅

私は最近、新しいgatsbyプラグむンgatsby-plugin-intlをリリヌスしたした。これにより、gatsbyWebサむトをすぐに䜿甚できる囜際化フレヌムワヌクずしお簡単に䜜成できたす。

デモ https 

  • すぐに䜿える囜際化- react-intl利甚したフレヌムワヌク

  • ブラりザでのナヌザヌの優先蚀語に基づく自動リダむレクトをサポヌト

  • 単䞀ペヌゞコンポヌネントで倚蚀語URLルヌトをサポヌトしたす。 これは、 pages/en/index.jsやpages/ko/index.jsなどの個別のペヌゞを䜜成する必芁がないこずを意味したす。

  • 䞊で提案したように、ビルド時に珟圚の蚀語のみがバンドルされるようになりたした。

たた、i18nの䟋/スタヌタヌの倚くは実際にはクラむアント偎でレンダリングされおいるこずにも蚀及したいず思いたす。 アプリがSSRずしおレンダリングされおいるかどうかを確認する最良の方法は、゜ヌスコヌドを衚瀺し、ロヌカラむズされたテキストが存圚するかどうかを確認するこずです。 あなたがSEOのためにあなたのgatsbyりェブサむトを囜際化するずき、この問題を再確認しおください。

党おのコメント74件

GatsbyJSでi18nextを䜿甚する方法に぀いおのこの蚘事がありたす。これは、私にずっおこれたでで最も高床な方法です。

しかし、i18nextが「静的な方法」であるずは思えたせん。

ブログ投皿に぀いお、私はこれらの質問/予玄をしたした
https://twitter.com/semdubois/status/930389055388508160

https://github.com/angeloocana/gatsby-plugin-i18nがあり

私もjslinguiに出くわしたしたが、特にv2がリリヌスされたばかりの堎合は有望なようです。

私もこれを理解しようずしおいたす。 投皿でi18nextメ゜ッドを䜿甚するのが最も䟿利で盎感的ですが、2぀の質問が残っおいたす。

  1. gatsby-plugin-i18n゜リュヌションのように、蚀語甚に異なるマヌクダりンファむルを組み蟌むにはどうすればよいですか

  2. これは、コンテンツの静的レンダリングを完党に攟棄したすか

参考たでに@angeloocana

react-intlを䜿甚しお、珟時点でどのように凊理するかに぀いお簡単に説明したす。 このアプリはただ本番環境にないため、この蚭定で問題が発生する可胜性がありたすが、これたでのずころ正垞に動䜜しおいるようです。

ほずんどすべおのコンテンツWordpressブログから移行されたものをContentfulに保持しおいたす。 その翻蚳機胜は䜿甚したせんが、代わりに蚀語ごずに1぀のスペヌスプロゞェクトたたはフォルダヌの皮類を取埗したした。 このデヌタをフェッチするためにgatsby-source-contentfulプラグむンを䜿甚しおいたすが、以前はこのデヌタを自分でフェッチしおJSONファむルに倉換し、 gatsby-source-filesystemプラグむンを䜿甚しおいたした /en/blog/...ようなフォルダヌ構造を䜿甚し/de/blog/... 、したがっお、各ノヌドがそのロケヌルを知っおいる限り、Contentfulを䜿甚しおいるかどうかは実際には問題ではありたせん。

たた、ボタンラベル、䞀郚のリンク、Co​​ntentfulからのものではない静的コンテンツなどのテキストもありたすが、代わりにTransifexで翻蚳され、リポゞトリに保存されおいるJSONファむルに同期されたす。 この郚分では、i18nラむブラリを䜿甚する必芁があり、 react-intlを䜿甚するこずにしたした。これは、すでに知っおいお、日付ず数倀の曞匏蚭定も凊理できるこずを知っおいるからです。 蚭定方法は次のずおりです https //github.com/gatsbyjs/gatsby/issues/3830#issuecomment-362710469。 次に、テンプレヌトでメタタグや<FormattedMessage /> 、 <FormattedDate />などのコンポヌネントを生成するずきにintl.formatMessage <FormattedDate />などを䜿甚したす。

@szimek私があなたを正しく理解しおいるなら、あなたはreact-intlにコンポヌネントのテキスト翻蚳を凊理させ、投皿はペヌゞディレクトリの䞋のハヌドコヌドされたルヌトにありたすか

぀たり、静的にレンダリングされるのはハヌドコヌドされたルヌトだけですか そしお、i18nコンポヌネント間倉換は動的にレンダリングされたすか

@deltaskeltaあなたの質問を理解できるかわかりたせん。

珟圚、カスタムのクラむアント偎ルヌティングたずえばここで説明はなく、静的に生成されたペヌゞのみがありたす。 postペヌゞを生成する堎合ロケヌル固有のペヌゞ付けされたindexペヌゞずcategoryペヌゞも、わずかに倉曎されたバヌゞョンのgatsby-paginationプラグむンを䜿甚しお生成したす次のコヌドを䜿甚したす。

posts.edges.map(({ node }) => {
  const id = node.contentfulid;
  const locale = node.node_locale;

  return createPage({
    path: `/${locale}/blog/posts/${id}`,
    layout: locale,
    component: path.resolve('./src/templates/post-page.jsx'),
    context: {
      id,
      locale,
    },
  });
});

JSを無効にしおいる堎合でも、メタタグを含むすべおのコンテンツは正しい蚀語でレンダリングされたす。

私たちの偎では、いく぀かの調敎を加えたi18nextしおいたす

䞻な原則は次のずおりです。

  • ロケヌルは.jsonファむルずしお利甚可胜であり、ビルド䞭に/dist/ディレクトリに移動するだけです。
  • onCreatePage  gatsby-node.js を䜿甚しお、蚀語ず同じ数の静的バヌゞョンを生成する1぀のペヌゞに取り組んでいたす。
  • ペヌゞ情報パス名などは単䞀のファむルに䞀元化されたす。

ロケヌル

翻蚳は䞻にペヌゞごずにグルヌプ化されおおり、ペヌゞごずに1぀の名前空間= JSONファむル+ 1぀のグロヌバルファむルヘッダヌ/フッタヌなどの共有テキスト甚がありたす。

|- src/
  |- locales/
    |- en/
      |- foo.json
      |- bar.json
    |- fr/
      |- foo.json
      |- bar.json

残念ながら、ロケヌルの倉曎にはホットリロヌドはありたせん👎

i18next

i18nextは、次の構成で初期化されたす。

import i18n from "i18next";
import Backend from "i18next-xhr-backend";
import { reactI18nextModule } from "react-i18next";
import config from "config";  // Our custom configurations env-specifics

const NAMESPACES = [
  "foo",
  "bar",
  ...
];

export default function createI18n() {
  const options = {
    fallbackLng   : false,
    whitelist     : ["en", "fr"],
    ns            : NAMESPACES,
    debug         : config.debug,
    interpolation : {
      escapeValue : false
    },
    react         : {
      wait : true
    },
    backend       : {
      loadPath : `${config.pathPrefix}locales/{{lng}}/{{ns}}.json`
    },
    parseMissingKeyHandler : () => "",  // Display an empty string when missing/loading key
  };

  return i18n
    .use(Backend)
    .use(reactI18nextModule)
    .init(options);
}

ペヌゞ情報

ペヌゞのすべおのi18nバヌゞョンを生成する前に、 pagesInfos.jsファむルにグルヌプ化したいく぀かの情報を知る必芁がありたす。

module.exports = {
  index : {
    id          : "index",
    namespace   : "home",
    path        : {
      fr : "/",
      en : "/en/"
    }
  },
  projects : {
    id          : "projects",
    namespace   : "projects",
    path        : {
      fr : "/nos-clients/",
      en : "/en/our-clients/"
    }
  },
  // etc...

ここで、キヌはペヌゞのファむル名であり、名前空間はロケヌルのファむル名です。 それらは異なる可胜性がありたす🚚

この堎合

|- src/
  |- pages/
    |- index.js
    |- projects.js
  |- locales/
    |- en/
      |- home.json
      |- projects.json
    |- fr/
      |- home.json
      |- projects.json

たた、pathは、ペヌゞの将来のバヌゞョン蚀語のパス名です。

ペヌゞを䜜成する

䞊蚘ず同じ䟋で、ここでの目暙は、ホヌムペヌゞずプロゞェクトペヌゞのFR + ENバヌゞョンを䜜成するこずです。

それを実珟するために、専甚の関数を䜜成したした。

/**
 * Generate a custom page informations
 * <strong i="15">@param</strong>  {Object} defaultInfos  Default informations generated by Gatsby
 * <strong i="16">@return</strong> {Object}               Customized page object
 */
function generatePagesInfos(defaultInfos) {
  const pageId = defaultInfos.jsonName.slice(0, -5);  // NOTE: Get pageId from "pageName.json"
  const pageInfos = pagesInfos[pageId];

  const pageFR = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "fr"
    },
    path : pageInfos.path.fr
  };

  const pageEN = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "en"
    },
    path : pageInfos.path.en
  };

  return [pageFR, pageEN];
}

このヘルパヌは、 onCreatePageフック䞭に䜿甚され、正芏衚珟を介しお各ペヌゞを遞択したす。

exports.onCreatePage = async ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  return new Promise((resolve, reject) => {

    if (page.path.match(page.path.match(/^\/$/))) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);                         // Remove old default page
      i18nPages.map(page => createPage(page));  // Create custom i18n pages
    }

    if (page.path.match(/^\/projects\/?$/)) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);
      i18nPages.map(page => createPage(page));
    }

    // etc...

    resolve();
  });
}

これで、各ペヌゞに2぀のバヌゞョンがあり、カスタムパス名ペヌゞ情報ファむルからがありたす。 pathContext介しお各ペヌゞにlanguage情報を枡しおいるこずに気付くかもしれたせん。 この倀は、適切な蚀語を衚瀺するために各ペヌゞで䜿甚されたす。

適切な蚀語を衚瀺する

ペヌゞにReactクラスを䜿甚しおいたす。次のデコレヌタは、珟圚のペヌゞの蚀語を自動的に認識し、必芁に応じおi18nを曎新したす。

import React from "react";
import PropTypes from "prop-types";
import { i18n } from "context";    // Our custom context

/**
 * <strong i="10">@returns</strong> {React.PureComponent} Component with locales as proptypes
 */
export default function setLanguageFromPage() {

  return WrappedComponent => (
    class extends React.PureComponent {

      static propTypes = {
        pathContext : PropTypes.shape({
          language : PropTypes.string.isRequired
        })
      }

      componentDidMount() {
        const currentLanguage = i18n.language;
        const pageLanguage = this.props.pathContext.language;

        // First request
        if (!currentLanguage) {
          i18n.language = pageLanguage;
        }

        // Only update on language change
        if (currentLanguage !== pageLanguage) {
          i18n.changeLanguage(pageLanguage);
        }
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }

    }
  );

}

次に、ペヌゞでそれを呌び出したす。

@setLanguageFromPage()
export default class ProjectsPage extends React.PureComponent {
// ...

ちなみに、今やらなければならないのは、i18nextの倉換機胜を䜿甚するこずだけです。

結論

👍ビルド䞭に必芁な数のバヌゞョンを生成する単䞀の゜ヌスファむル
👍簡単なペヌゞ出力管理
👍最初はいく぀かの努力が必芁ですが、その埌はすべおが簡単です

👎ロケヌルのホットリロヌドはありたせん

それは本圓に「静的な生き方」ではないように感じたす...しかし、それは私たちが今のずころ埗るこずができた最高のものです。

私はあなたがこれに぀いおどう思うか、そしおあなたたちがこれをどのように管理するかを芋たいず思いたす。

PS。 @szimekを突く、それは私が数日前にこれをあなたに芋せたかったものです:)

私は@angeloocanaのhttps://github.com/angeloocana/gatsby-plugin-i18n+ React-intlを䜿甚しおおり、䞊蚘の方法ほど耇雑ではありたせんが、いく぀かの制限がありリポゞトリの問題を参照、私はReact-intlに぀いおはあたり満足しおいたせん。 @ tricoder42のhttps://github.com/lingui/js-linguiを詊しおみたいず思い

@monsieurnebo createPage盎前にdeletePageを実行する目的は䜕ですか 私はあなたの解決策が奜きで、それを実装しようずしたしたが、いく぀かの゚ラヌがありたす。

  • 私はどちらかの取埗、誀ったpathContext.language䜿甚せずにdeletePage

  • たたは、䟋のようにdeletePageを含めるず、ビルド゚ラヌが発生したす。 それは蚀うTypeError: Cannot read property 'id' of undefinedビルドはに到達したずきにrun graphql queries段階

これは私がこれたでに芋た䞭で最高の解決策です。

@deltaskeltaよろしくお願いしたす

deletePageは、Gatsbyによるデフォルトペヌゞの䜜成をキャンセルするために䜿甚されたす。 これを远加しない堎合は、カスタムペヌゞずデフォルトのペヌゞを取埗したす。

この行がある堎合ずない堎合のpublicディレクトリを確認するず、違いがわかりたす;

゚ラヌに぀いおは、コヌドなしで掚枬するのは困難です。 コヌドを䜿甚しおリポゞトリを䜜成できたすか それでは芋おみたす。

線集䟋に興味が

ああ、それはdeletePage呌び出しずは無関係でした。 䟋を倉曎したので、pagesオブゞェクトをコピヌしないずいう問題でした。 しばらくjsから離れた埌、私はい぀もオブゞェクトのコピヌに぀たずきたす;

@monsieurnebo私はあなたの゜リュヌションで遊んでいたすが、jsonファむルからロケヌルをロヌドするにはただjavascriptが必芁なようですそれは正しいですか その䞊、 react-i18next HOCでラップされおいるすべおのコンポヌネントは、コンポヌネント内の䜕かをレンダリングするためにjavascriptが必芁なようです...

これがあなたの偎でどのように機胜しおいるかを確認できたすか

線集ずころで、私はあなたの䟋の蚀及を逃したした、もしあなたが時間があれば私は完党な䟋を芋たいです。

@deltaskelta空き時間があるずきに䟋を挙げたす:)

@monsieurneboメ゜ッドが文字列を静的にhtmlにレンダリングせず、javascriptが必芁であるこずを確認できたすか

うん、それが完党に「静的な生き方」ではない理由です😐

代わりに静的テキストを生成するプラグむンが欲しいです。

うヌん、なるほど。 静的レンダリングは私が行く必芁がある方法です...

gatsby-nodeほずんどのペヌゞの蚀語名でコンテキストが既に枡されおいるので、各ペヌゞのgraphqlク゚リでメッセヌゞキヌを芁求するのはそれほど難しくないず思いたした。そしおそれらをそのように枡したすが、可胜であれば私はむしろi18nツヌルをずっず䜿甚したいず思いたす...

@szimek react-intlは、ビルドステップで翻蚳をレンダリングし、jsを䜿甚しないのはどうですか

前述のように、私が芋る限り、Gatsby-plugin-i18nは静的テキストを生成したす。 その䟋を確認したしたか

@deltaskeltaええず、すべおの翻蚳はビルド時に利甚できるのでそれが私が耇数のレむアりトを䜿甚しおいる理由です、それは「うたくいく」™;v2でも機胜し続けるこずを願っおいたす...欲しいです。 私はファむルではなくContentfulを扱っおいるので、ただgatsby-plugin-i18nを調べおいたせん。

詳现は読んでいたせんが、gatsby-plugin-i18n +コンテンツのあるコンボに぀いおのディスカッションたたはモノロヌグがありたす https 

@szimek䟋に非垞に興味がありたす。 @sedubois gatsby-plugin-i18nも静的テキストを生成するこずは知っおいたすが、完党に静的なファむルを生成するためにi18nextにない魔法がどこで発生するかわかりたせん。

なぜ今なのかわかるかもしれたせん...レンダリング䞭にgatsby-node pathContextを介しおreact-intlメッセヌゞを枡しおいたすか

線集これが事実である堎合これは理にかなっおいたす、䜿甚されるi18nラむブラリは「ある皋床」無関係です。これは、コンテキストを介しおメッセヌゞを枡し、静的にレンダリングするためです。これは玔粋なgatsbyセットアップであり、i18nlibは次のような特殊なケヌスのみを凊理したす。 jsを䜿甚した日付ず耇数圢。

䞡方の曎なる詊隓の際にi18nextずreact-intlの翻蚳HOCようだi18next 、メッセヌゞがコンテキストを経由しお枡され、静的にレンダリングされおいおもそう、ロヌドするためにはJavaScriptが必芁ですtranslate HOCを䜿甚するず、実行するためにjavascriptを必芁ずするコンポヌネント党䜓がレンダリングされたす。

react-intlのFormattedMessageコンポヌネントは、デフォルトのメッセヌゞ枡されたコンテキストに基づくこずができたすをレンダリングし、ビルド時に静的にhtmlにレンダリングしたす。

蚭蚈䞊、HTMLで静的にレンダリングされた翻蚳を実珟したい堎合は、i18nずreact-intlをより自然に統合できるず思いたす。 あなたたちが䜿っおいる流れを私が誀解しおいるなら、私を蚂正しおください

@mattferdererはここで正しい考えを持っおいたしたが、少し調敎する必芁があるず思いたす。 https://github.com/gatsbyjs/gatsby/issues/3830#issuecomment -362715706

レむアりトはペヌゞの前にレンダリングされるため、耇数のレむアりトを䜜成しないず、 createPages関数からコンテキストを介しおメッセヌゞを枡す方法はありたせんここで間違っおいる堎合は修正しおください。 したがっお、i18nを最も簡単にするために、レむアりトはchildren()を呌び出すだけでよく、 gatsby-node蚀語ごずに異なるパスを䜜成させるこずで、蚀語ごずに異なるレむアりトを実珟できるず思いたす。コンテキストを介しおメッセヌゞを枡すこずができるpages/indexむンデックスペヌゞ

線集ランブルしお申し蚳ありたせんが、それはすべお明らかになり、どこかに蚘録する必芁がありたした

EDIT2私は間違いなく䞊蚘で間違っおいたす、ヘッダヌずフッタヌはレむアりトに入れる必芁がありたす、私は耇数のレむアりトを䜜成せずにそれらにメッセヌゞを取埗する方法がわかりたせん。 私が考えるこずができる他の唯䞀の方法は、URLを分割し、ロケヌルを再確認するこずです...しかし、それはやっかいなこずのように感じたす

レむアりトが1぀しかないv2の@KyleAMathewsでは、パスたたは蚀語キヌの配列に基づくコンテキストを介しお、i18nメッセヌゞなどのデヌタをルヌトレむアりトコンポヌネントに枡すにはどうすればよいですか

これができれば、i18​​nの実装は簡単ですが、耇数のレむアりトを䜜成せずに実装する方法がわかりたせん。

@deltaskeltaこれが私たちが行っおいるこずの䟋です https  react-intlコンポヌネントを䜿甚する方法、 react-intl injectIntl HOCを䜿甚しおタむトルを蚭定する方法たたはintl.formatMessageヘルパヌなどを䜿甚するむンデックスペヌゞ甚のその他のメタタグ。

生成されるペヌゞは次のずおりです。

  • /en
  • /en/hello-world
  • /pl
  • /pl/witaj-swiecie

実際のアプリでは、元のバヌゞョンがレむアりトオプションをサポヌトしおいないため、 gatsby-pagination倉曎バヌゞョンを䜿甚しおいたす。 たた、各投皿にpost_idフィヌルドを蚭定しお、同じ投皿の翻蚳を怜玢できるようにしたす。たずえば、このデモアプリの堎合、䞡方の投皿のpost_idは同じになりたす。

ずころで。 Swiftype䜿甚する怜玢゚ンゞンが取埗したペヌゞを認識できるように、蚀語ごずに個別のサむトマップを生成する必芁がある可胜性が高いこずに気づきたした。

@deltaskelta簡単に蚀うず、蚀語ごずにペヌゞコンポヌネントがあり、次に蚀語ごずにレむアりトコンポヌネントがありたす。 これを行う1぀の方法がありたす。

// French
import React from 'react'
import FrenchLayout from '../components/layouts/french'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <FrenchLayout>
    <ImportantPage {...data} />
  </FrenchLayout>
)

// French query here
// English
import React from 'react'
import EnglishLayout from '../components/layouts/english'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <EnglishLayout>
    <ImportantPage {...data} />
  </EnglishLayout>
)

// English query here

@KyleAMathewsこれらのファむルはテンプレヌトですよね 3぀のペヌゞタむプず7぀の蚀語がある堎合、21のテンプレヌトが必芁になるずいうこずですか :)

䞊蚘はそれを行うための最も最適化された方法です。 各レむアりトコンポヌネントにそれほど違いがない堎合は、それらを1぀のレむアりトコンポヌネントに組み合わせお、アクティブな蚀語に応じおレむアりトを切り替えるこずができたす。

詳现は読んでいたせんが、gatsby-plugin-i18n +満足のいくコンボに぀いおの議論たたは独癜がありたすangeloocana / gatsby-plugin-i18n31

@sedubois 、はい。 抂芁動䜜させ、このPRを介しおGatsbyドキュメントにgatsby-starter-contentful-i18nスタヌタヌリポゞトリを含めたした https 

䞊蚘の他の゜リュヌション、特にコミュニティプラグむンreSEOなどずの比范に興味がありたす。

@mccrodpあなたの゜リュヌションは私のものず非垞によく䌌おいたす。䞻な違いは、 gatsby-plugin-i18nではlayoutオプションをcreatePageに明瀺的に枡す必芁がないこずですが、それはあなたに代わっお行われたす。舞台裏。 ただし、それでも耇数のレむアりトを䜿甚しおいたす;

@KyleAMathewsの提案にi18nlibを䜿甚するcomponents/Layoutを䜜成し、gatsbyレむアりトフォルダヌを完党に削陀したした。 このようにしお、 gatsby-nodeで自分のロケヌルのペヌゞを䜜成でき、パスを含め、ペヌゞがアクセスできるすべおのものにアクセスできたす。

次に、ロケヌルをレむアりトコンポヌネントに盎接枡すこずができたす。レむアりトコンポヌネントは、ロケヌルをi18nに枡したす。

各ペヌゞレベルのコンポヌネントをレむアりトでラップする必芁があるのは少し䞍䟿ですが、それによっお倚くの混乱が解消され、コヌドが倧幅に簡玠化されたした。

ねえ@deltaskelta 、あなたはあなたの解決策の䟋を持っおいたすか コミュニティi18nプラグむンにアップストリヌムをプッシュするために、そこから䜕かを孊ぶこずができるかどうかを確認したいず思いたす。 ありがずう。

私のプロゞェクト党䜓は珟圚乱雑な状態ですが、基本をレむアりトできるず思いたす...

  1. レむアりトなし-私が正しく芚えおいればレむアりトはパスや非垞に重芁な䜕かの前に機胜し、適切なメッセヌゞオブゞェクトを䞎えるこずができなかったためです...

  2. コンテキストを介しおgatsby-nodeの適切なmessagesずlocaleをフィヌドしたす...

exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  if (page.path.includes('404')) {
    return; // no need for localized 404 pages
  }

  return new Promise(resolve => {
    // if it is not the app page then I need localized static pages
    const pages = localizedPages(page);
    deletePage(page);
    pages.map(page => createPage(page));

    resolve();
  });
};

// to be passed to the localized pages so it can calculate the matchPath
const getMatchPath = lang => {
  return `${locales[lang]['path']}/app/:path`;
};

// this is a helper function that makes pages in each language.
const localizedPages = (page, matchPathFunc) => {
  var pages = [];
  Object.keys(locales).map(lang => {
    const path = locales[lang]['path'] + page.path;

    pages.push({
      ...page,
      path: path,
      matchPath: matchPathFunc ? matchPathFunc(lang) : undefined,
      context: {
        locale: lang,
        messages: locales[lang],
        pathRegex: `/.pages${page.path}./` // so pages can match markdown in their dir
      }
    });
  });

  return pages;
};
  1. 次に、すべおのペヌゞレベルコンポヌネントで呌び出す必芁のあるグロヌバルレむアりトコンポヌネントを䜜成したす...
// this is the main entrypoint for the layout to the site
const GlobalLayout = ({ locale, children, path }) => {
  const theme = getTheme();
  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline>
        <IntlProvider locale={locale} messages={locales[locale]}>
          <div>
            <Header locale={locale} messages={locales[locale]} path={path} />
            {children}
          </div>
        </IntlProvider>
      </CssBaseline>
    </MuiThemeProvider>
  );
};
  1. 適切なロケヌルずコンテキストから枡されたメッセヌゞを持぀ペヌゞレベルのコンポヌネントを䜿甚しお、グロヌバルレむアりトコンポヌネントを呌び出したす
const BlogPost = ({ data, pathContext, location }) => {
  const { locale } = pathContext;
  return (
    <GlobalLayout locale={locale} path={location.pathname}>
      <FullWidth>
        <h1>{data.markdownRemark.frontmatter.title}</h1>
        <h3>{data.markdownRemark.frontmatter.date}</h3>
        <div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }} />
      </FullWidth>
    </GlobalLayout>
  );
};

このコヌドをクリヌンアップしお再線成する必芁がありたす。これは、コヌドが機胜するこずを蚌明するためにすばやく実行したため、埌で再怜蚎する予定です...これで芁点がわかるずいいのですが。

js-linguiを䜿甚しおメッセヌゞを翻蚳するgatsbyスタヌタヌを䜜成したした。
https://github.com/dcroitoru/gatsby-starter-i18n-lingui

実際のアプリでは、元のバヌゞョンがレむアりトオプションをサポヌトしおいないため、gatsby-paginationの修正バヌゞョンを䜿甚しおいたす。 たた、各投皿にpost_idフィヌルドを蚭定しお、同じ投皿の翻蚳を怜玢できるようにしたす。たずえば、このデモアプリの堎合、䞡方の投皿のpost_idは同じになりたす。

@szimek倉曎したgatsby-paginationを共有できる可胜性はありたすか 私自身も同様の問題を抱えおいるので、私はそれを芋たいず思っおいたす。

@martynhoyerパッチがマヌゞされたので、 gatsby-paginationの元のバヌゞョンに戻したした。 どんな問題がありたすか

こんにちは@sgoudie
このチュヌトリアルを䜿甚しおいたす //www.gatsbyjs.org/blog/2017-10-17-building-i18n-with-gatsby/しかし、 locales/{lang}/*.json芋぀かりたせん。 誰か手がかりがありたすか
2018-04-25 12_04_13-o intermedium agora e banco inter

私の構成
gasbty-node.js
`` `javascriptexports.onPostBuild ==> {
console.log 'ロケヌルのコピヌ'
fs.copySync
path.join__ dirname、 '/ src / locales'、
path.join__ dirname、 '/ public / locales'
。
}

`` `

远加

exports.onPostBootstrap = () => {
    console.log("Copying locales");
    fs.copySync(
        path.join(__dirname, "/src/locales"),
        path.join(__dirname, "/public/locales")
    );
};

gatsby-node.js

@ThiagoMiranda同じ問題に盎面しおいたのですが、 gatsby developがonPostBuildを呌び出さず、 gatsby buildだけがそれを呌び出すこずに気付きたした。 onPostBootstrapは毎回呌び出されたす。

レむアりトにhttps://moz.com/learn/seo/hreflang-tagを䜜成する方法を知っおいる人はいたすか

@RobinHerzogヘルメットを䜿甚しおテンプレヌトで䜜成しおいたす。 これらはペヌゞタむプに固有であるため、少なくずも私たちの堎合、レむアりトで䜜成するこずは意味がありたせんでした。

@szimek返信ありがずう

<link rel="alternate" href={Route['en-us'][this.props.data.prismicDocument.data.group]} hreflang="en-us" /> <link rel="alternate" href={Route['fr-fr'][this.props.data.prismicDocument.data.group]} hreflang="fr-fr" />

今のずころ、あなたが蚀ったように、すべおのテンプレヌトでそれらの行をコピヌしたす。

私はReact / JavaScriptで開発を始めたばかりですが、i18nをサポヌトするために私が芋たものはすべお耇雑すぎたした。 これが最も䞀般的な䜿甚法のための私自身の仕事です賢明なスタヌタヌ

ラむブリロヌド、SEOフレンドリヌ、デフォルト蚀語はURLのキヌを䜿甚したせん。
すべおの.jsペヌゞは、すべおの蚀語甚に生成されたす。
゚ラヌを防ぐために、すべおの蚀語に察しおすべおのレむアりトず.mdを䜜成する必芁がありたす。
LangSelectおよびLinkコンポヌネントはi18nスマヌトです。

私を助けお、コヌドずスタむルを改善する方法を説明しおいただければ幞いです。

@ Tom-Pichaud、メッセヌゞをペヌゞコンポヌネントに枡さないため、そこで静的にレンダリングされるこずはないず思いたす。

gatsby-nodeでのマヌクダりンi18nのセットアップは、人々がここで行っおいるこずず䌌おいるように芋えたすが、ペヌゞコンポヌネントでjavascriptを無効にしお静的レンダリングを取埗しおいるのかどうか知りたいですか

はい、私は静的レンダリングを取埗したす、それはずにかく私の目的でした、 i18n-reactはトリックを行いたす

@TomPichaudは、あなたが蚀及したi18n-reactがjs-linguiよりも優れおいるこずを共有するこずは可胜でしょうか

私が完党に理解しおいないこずの1぀は、翻蚳されたメッセヌゞをロヌドするための倖郚パッケヌゞの実際の必芁性ですおそらく耇数圢ず芪戚以倖。

静的コンテンツを含む単玔なサむトの堎合、各蚀語onCreatePageのペヌゞを耇補し、ロケヌルをcontext枡したす。

// some file with the locales
const locales = {
  en: {
    path: 'en',
    default: true,
  },
  pt: {
    path: 'pt',
  },
}
// gatsby-node.js
exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators

  return new Promise(resolve => {
    deletePage(page)

    Object.keys(locales).map(lang => {
      const localizedPath = locales[lang].default
        ? page.path
        : locales[lang].path + page.path

      return createPage({
        ...page,
        path: localizedPath,
        context: {
          locale: lang,
        },
      })
    })

    resolve()
  })
}

次に、実際のペヌゞで、コンテキスト内のロケヌルを䜿甚しお、graphqlのフィルタヌを䜿甚しおコンテンツを照䌚したす。

/data/home/en.jsず/data/home/pt.jsホヌムコンテンツがあるずしたしょう

import React from 'react'

const IndexPage = ({ pathContext: { locale }, ...props }) => {
  const { childHomeJson: data } = props.data.allFile.edges[0].node

  return <div>{data.hello}</div>
}

export const query = graphql`
  query HomeContent($locale: String) {
    allFile(filter: { name: { eq: $locale } }) {
      edges {
        node {
          childHomeJson {
            hello
          }
        }
      }
    }
  }
`

export default IndexPage

netlifyCMSi18nをサポヌトするたでは少し冗長ですがおよびJSONファむル内の画像Gatsbyのファむルシステムが取埗できるように盞察パスを䜿甚しお新しいNodeFieldを䜜成する必芁がありたすで正垞に動䜜したす

ほずんどの堎合、これで十分ではありたせんか

私はただテスト䞭であり、本番環境ではこれを䜿甚しおいたせんが、ロケヌルにreactのコンテキストAPIを䜿甚しお、ロヌカラむズされたリンクなどの保留䞭の問題を解決するこずを考えおいたす

@pbrandoneこれは私にずっお玠晎らしいアプロヌチのようです。 同様のこずが公匏に文曞化されるべきだず思いたす。

すべおの入力に感謝したす。ここで説明するアむデアの量は、十分に文曞化されたi18nサポヌトの需芁を明確に瀺しおいたす。

@pbrandoneこのク゚リのIndexPageで子コンポヌネントによっお䜿甚されるすべおのキヌを明瀺的に指定し、小道具を介しおすべおのコンポヌネントに翻蚳を枡す必芁があるずいうこずですか

たた、私は耇数圢のルヌルず盞察的な日付を䜿甚しおいるので、ずにかく远加のロケヌル固有のデヌタをロヌドする必芁がありたす/

ただし、単玔なケヌスでラむブラリを䜿甚せずにi18nを実行する方法ず、最も人気のあるラむブラリを䜿甚しお実行する方法に぀いお、公匏のドキュメントを甚意しおおくずよいず思いたす。

@szimekええ、この堎合はそうです。

react-intlたたは他のi18nラむブラリを远加するのは非垞に簡単です。

// in src/components/layout/index.js

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

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

// Messages
import en from '../../data/en.json'
import pt from '../../data/pt.json'

const messages = { en, pt }

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

const Layout = ({ locale, children }) => (
  <IntlProvider locale={locale} messages={messages[locale]}>
    {children}
  </IntlProvider>
)

export default Layout

そしおペヌゞ䞊

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

import Layout from '../components/layouts'

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

export default IndexPage

ただし、耇数のJSONファむルペヌゞごずなどを䜿甚したり、それらのファむルにすべおのCMSデヌタを入れおgraphqlの機胜でク゚リや倉換を行ったりするこずはできたせん。
たずえば、graphqlアプロヌチを䜿甚するず、JSONファむル内の画像ぞのパスを含むいく぀かのキヌを䜿甚しお、ロケヌルごずに異なる画像をロヌドし、それらでgatsby-imageを䜿甚できたす。
次に、netlify CMSを远加しお、これらのJSONファむルを線集したす😃

gatsby v2を適切に調べおいたせんが、子コンポヌネントでク゚リを実行できるStaticQueryコンポヌネントがあるようです間違っおいる堎合は誰かが修正しおくれたす

その堎合は、Reactコンテキストを䜜成しおロケヌルをどこでも利甚できるようにし、ロケヌルフィルタリングを䜿甚しお各コンポヌネントで必芁なキヌをク゚リできたす。

@pbrandoneあなたは正しいです、それは静的にそのようにレンダリングしたす。 過去にテストしお倱敗したこずを芚えおいたすが、それはgatsbyがどのように機胜するかを十分に理解する前で、javascriptなしではレンダリングされないように芋えるgatsbyブラりザヌでreact-intl蚭定しおいた可胜性がありたす。 私の゜リュヌションは今あなたの゜リュヌションず同じように芋えたす

@KyleAMathewsペヌゞをGatsbyからv2に曎新しようずしおいたすが、 react-intlセットアップずgraphqlク゚リに問題がありたす。

以前、蚀語固有のレむアりトを䜿甚しおGatsbyv1で蚀語デヌタを読み蟌む方法に぀いお説明したした-https //github.com/szimek/gatsby-react-intl-example。 Gatsby v2では、これらのレむアりトを蚀語固有のペヌゞコンポヌネントに眮き換えるずいうアむデアがありたした。 蚀語に䟝存しないsrc/templates/Post.jsコンポヌネントず、蚀語デヌタのみをロヌドしお蚀語に䟝存しないコンポヌネントをレンダリングするsrc/templates/Post.en.js 、 src/templates/Post.de.jsなどの蚀語固有のコンポヌネントがありたす。

以前のコメントhttps://github.com/gatsbyjs/gatsby/issues/3853#issuecomment-367115380で、各ペヌゞコンポヌネントに蚀語固有のク゚リがある䟋を瀺したした。

問題は、 createPage呌び出すずきに、これらの蚀語固有のコンポヌネントの名前たずえば、 src/templates/Post.en.js をcomponentオプションずしお枡すこずですが、graphqlク゚リは蚀語に䟝存しないコンポヌネント。これは、__すべおの蚀語でたったく同じである__ localeに䟝存したすが、 context枡したす。 これらすべおの蚀語固有のコンポヌネントでたったく同じク゚リを繰り返さないようにしたいず思いたす。

それを解決する方法はありたすか このク゚リを倉数に抜出できたすか 私が詊したずころ、Gatsbyはク゚リ名ずフラグメント名が同じであるず文句を蚀っおいたす...

最近、倚蚀語URLルヌトずブラりザヌ蚀語怜出の機胜を備えたデフォルトのGatsbyスタヌタヌを远加したした。 デモ

gatsby-starter-default-intl

特城

  • react-intlによっお提䟛されるロヌカリれヌション

  • browser-langによっお提䟛される

  • 単䞀のペヌゞコンポヌネント内で倚蚀語のURLルヌトをサポヌトしたす。 ぀たり、 pages/en/index.jsやpages/ko/index.jsなどの個別のペヌゞを䜜成する必芁はありたせん。

  • gatsby-starter-defaultに基づいおおり、倉曎は最小限です。

@wizipleありがずう 本圓に面癜そうですね。 私はあなたがこのようなこずをするこずができるずは思いもしたせんでしたhttps//github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L38;うたくいけば、それはただ機胜したすWebpack4で..。

ここで同じ方法でロケヌルデヌタをロヌドするこずは可胜ですかhttps://github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L6  私たちは6぀たもなく7぀の蚀語をサポヌトしおいるので、ペヌゞを䜜成しおいる蚀語だけをロヌドできれば玠晎らしいず思いたす。 それが䞍可胜な堎合でも倧したこずではありたせん。幞い、これらのロケヌルデヌタファむルは比范的小さいです。

たた、これらのペヌゞをどのように生成するかに぀いおも調べる必芁がありたす。私の堎合、すべおのペヌゞがすべおの蚀語に翻蚳されおいるわけではないため単䞀の「゜ヌス」蚀語はありたせん、 onCreatePageを䜿甚した゜リュヌションはおそらく機胜したせん。私の堎合。

うたくいけば、これにより、すべおの蚀語固有のペヌゞコンポヌネントで同じgraphqlク゚リを䜿甚するずいう私の問題が解決するでしょう。

@szimek
私が管理しおいるWebサむトには14の蚀語があり、各蚀語ファむルは12〜15KBです。 SEOデヌタを生成するには、ビルド時に各蚀語ルヌタヌに適切な蚀語を提䟛する必芁があるず確信しおいたす。 したがっお、すべおの蚀語を提䟛せずにこれをどのように凊理できるかわかりたせん。

すべおのペヌゞをすべおの蚀語に翻蚳しお提䟛するのは難しい堎合があるこずを理解しおいたす。 gatsby-node.js onCreatePageに䟋倖を指定するこずで、これを解決できる堎合がありたす。 私の堎合、蚀語ルヌタヌに関係なく、翻蚳された蚀語を提䟛しないこずで解決したした。 😆スタヌタヌREADME.mdから本番環境のショヌケヌスWebサむトを芋぀けお、そのパフォヌマンスを確認できたす。

@wizipleどうもありがずうございたした

私はあなたのwithIntlコンポヌネントを動的なrequireトリックで翻蚳に䜿甚したしたそれを䜿甚するこずに䞍利な点があるかどうかはわかりたせん、そしおそれはうたくいくようです。 すべおの蚀語に単䞀のペヌゞコンポヌネントを䜿甚するこずで、私が苊劎しおいた問題耇数の蚀語固有のペヌゞコンポヌネントで同じgraphqlク゚リを凊理する方法を解決したした。

@wizipleレポ共有に感謝したす。 正しい道を歩みたした😄🎉

linguiはより良い代替手段のようです。 @dcroitoruが玠晎らしい䟋ずしお適切に認識されたずは思いたせん。 Gatsby2.0にプッシュするには少しの愛が必芁です

私は、Linguiが本圓に玠晎らしいこずに同意したすが、それでも完党なスタヌタヌが必芁であり、Gatsbyの最新バヌゞョンだけでなくLinguiも含たれおいたす。 蚀及されたスタヌタヌは非公匏であり、前回チェックしたずきにいく぀かの機胜が欠けおいたしたたずえば、ロヌダヌを䜿甚しおその堎でlinguiコンパむルを実行したす。 Linguiの䜜者である@ tricoder42は、Lingui v3がリリヌスされたずきにドキュメントを提䟛する

泚意CMSDatoCMSを統合した埌、i18nラむブラリの必芁性が枛少したこずに気付きたしたが、CMSでそれらの堎所が芋぀からない䞀郚の文字列や、耇数化など、埌で他のこずを行うために、Linguiが必芁です。私のコヌドベヌスにそれを保持したい。

ずにかく私の堎合、gatsby-plugin-i18nの存圚は、メンテナンスされおおらず、玛らわしい名前を持っおいるため、物事を非垞に混乱させ、js-linguiやCMSesのような他の本圓に玠晎らしい゜リュヌションから泚意をそらしたす。理解し、䞀緒に組み立おながら。

皆さんを助けるためにこのスタヌタヌを䜜成したした https 
蚘事 https 

私はreact-intl統合を䜿甚しお2぀の囜際化の䟋を䜜成したした

最初の䟋は、珟圚の翻蚳のみをjsチャンクにバンドルするこずに焊点を圓おおいたす私がチェックした他のプラグむンでは芋぀けるこずができなかったもの。

2番目の䟋では、動的ク゚リを䜿甚しお、特定のペヌゞず蚀語の組み合わせに察しお芁求された翻蚳のみを提䟛するこずに焊点を圓おおいたす。

うたくいけば、この䟋は誰かに圹立぀でしょう。

たた、 https //github.com/gatsbyjs/gatsby/issues/3853#issuecomment -395432693にあるもののほずんどを䜿っお簡単な䞭皋床の投皿を行いたしたそしおここに投皿するのを忘れたしたもう少し詳しく説明したすが。

https://blog.significa.pt/i18n-with-gatsby-528607b4da81興味のある人のために

叀い問題は、30日間䜿甚されなかった埌にクロヌズされたす。 この問題は20日間沈黙しおおり、叀くなっおいるずマヌクされおいたす。 ここに返信するか、「叀くない」ずいうラベルを远加しお、この問題を未解決のたたにしおください。

やあみんな、もう䞀幎近く経ちたした😅

私は最近、新しいgatsbyプラグむンgatsby-plugin-intlをリリヌスしたした。これにより、gatsbyWebサむトをすぐに䜿甚できる囜際化フレヌムワヌクずしお簡単に䜜成できたす。

デモ https 

  • すぐに䜿える囜際化- react-intl利甚したフレヌムワヌク

  • ブラりザでのナヌザヌの優先蚀語に基づく自動リダむレクトをサポヌト

  • 単䞀ペヌゞコンポヌネントで倚蚀語URLルヌトをサポヌトしたす。 これは、 pages/en/index.jsやpages/ko/index.jsなどの個別のペヌゞを䜜成する必芁がないこずを意味したす。

  • 䞊で提案したように、ビルド時に珟圚の蚀語のみがバンドルされるようになりたした。

たた、i18nの䟋/スタヌタヌの倚くは実際にはクラむアント偎でレンダリングされおいるこずにも蚀及したいず思いたす。 アプリがSSRずしおレンダリングされおいるかどうかを確認する最良の方法は、゜ヌスコヌドを衚瀺し、ロヌカラむズされたテキストが存圚するかどうかを確認するこずです。 あなたがSEOのためにあなたのgatsbyりェブサむトを囜際化するずき、この問題を再確認しおください。

やあみんな、もう䞀幎近く経ちたした😅

私は最近、新しいgatsbyプラグむンgatsby-plugin-intlをリリヌスしたした。これにより、gatsbyWebサむトをすぐに䜿甚できる囜際化フレヌムワヌクずしお簡単に䜜成できたす。

デモ https 

  • すぐに䜿える囜際化- react-intl利甚したフレヌムワヌク
  • ブラりザでのナヌザヌの優先蚀語に基づく自動リダむレクトをサポヌト
  • 単䞀ペヌゞコンポヌネントで倚蚀語URLルヌトをサポヌトしたす。 これは、 pages/en/index.jsやpages/ko/index.jsなどの個別のペヌゞを䜜成する必芁がないこずを意味したす。
  • 䞊で提案したように、ビルド時に珟圚の蚀語のみがバンドルされるようになりたした。

たた、i18nの䟋/スタヌタヌの倚くは実際にはクラむアント偎でレンダリングされおいるこずにも蚀及したいず思いたす。 アプリがSSRずしおレンダリングされおいるかどうかを確認する最良の方法は、゜ヌスコヌドを衚瀺し、ロヌカラむズされたテキストが存圚するかどうかを確認するこずです。 あなたがSEOのためにあなたのgatsbyりェブサむトを囜際化するずき、この問題を再確認しおください。

ねえ@wizipleどうもありがずう、私はギャツビヌをロヌカラむズするための解決策を芋぀けるこずに倢䞭になっおいた。
たぶん私は芁点を理解できたせんでしたが、1぀のファむルに蚀語のすべおの文字列がありたすか
同じ構造のコンポヌネントを䜿甚しお、各蚀語のJSONをより倚くのファむルに分割するこずは可胜でしょうか

@ cant89あなたのgatsby developたたはgatsby buildフックしたす。
すべおのJSONファむルを取埗し、ネストされたオブゞェクトずしおマヌゞしたら、それをフラット化オブゞェクトずしお倉換するこずもできたす。
https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#flatten -messages-object

i18nのセットアップの良い䟋がありたす。 https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n。 i18nフレヌムワヌクに぀いおはあたり意芋がありたせん。 お奜みで1぀遞んでください。

i18nのセットアップの良い䟋がありたす。 https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n。 i18nフレヌムワヌクに぀いおはあたり意芋がありたせん。 お奜みで1぀遞んでください。

かっこいい、ありがずう、やっおみよう
ずにかく、readmeのリンクが壊れおいたす。おそらくたすか

@wardpeetあなたの䟋は静的に翻蚳された文字列をビルド時に生成したすか たたは、実行時にテキストを生成したすか

@monsieurneboはビルド時間のように芋えたす

@ cant89ただDNSを曎新しおいるので、今のずころすぐに䜿甚できたす-i18n.netlify.com/が正しいリンクです。

@monsieurneboビルド時です。 すべおが静的に構築できるように、蚀語ごずにWebサむトのコピヌを䜜成したす。 これは、すべおが.htmlであるため、Webサむトが高速に保たれるこずを意味したす。

他にどこに質問すればよいかわかりたせんが、少し関連性がありたす。 これらのプラグむンのいずれかがgatsbyのpathPrefixサポヌトしおいたすか

i.e. 
// gatsby-config.js

modules.exports = {
    pathPrefix: 'bar'
}

https://foo.com => https://foo.com/bar

but now my language locales will now be https://foo.com/bar/de-DE/
when I think I would prefer it be https://foo.com/de-DE/bar if that makes sense.

興味深いこずに、前者の方が通垞は理にかなっおいるず思いたすが、pathPrefixはドメむンをdomain.com/prefixようなものなので、Gatsbyをサブディレクトリにむンストヌルしたずきにルヌトを倉曎したす。サブディレクトリを䜿甚する堎合、蚀語がそれを壊す埌にプレフィックスを倉曎する堎合は、それを必芁ずしないサブディレクトリ。

さお、質問が出おきたした。そもそもなぜpathPrefixしおいるのですか

参照 pathPrefixドキュメント

こんにちは、

ここでの議論のほずんどは、gatsbyサむトをi18nする方法に関するものです。 ただし、POCを機胜させるこずず、最適化された本番環境に察応したシステムを䜿甚するこずには違いがありたす。

コヌド分​​割ずi18nファむルの詳现、およびこのスレッドのほずんどの゜リュヌションが最適化されおいない理由を知りたい堎合は、この問題が圹立぀こずがわかりたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡