ä»ã®åé¡ã«ã€ããŠã®ç§ã®ã³ã¡ã³ãã«å¯Ÿããåå¿ãèŠãŠãç§ã¯ãã®åé¡ãéãããšã«ããŸããã
i18nã¯æ¬æ¥ãããã¯ããã«é£ãããšæããŸãã Gatsby補ã®Webãµã€ãã§ã³ã³ãã³ããåœéåããããã®å ¬åŒããã¥ã¡ã³ãããã©ã°ã€ã³ãèŠã€ãããŸããã§ãããç§ã¯jsLinguiã«åºãããããšãã°ããŒã¯ããŠã³ãã¡ã€ã«/ããŒãžãç°ãªãèšèªã§ç¶æããããã®ã¬ã€ãã¯ãŸã ãããŸããã
GatsbyJSã§i18nextã䜿çšããæ¹æ³ã«ã€ããŠã®ãã®èšäºããããŸããããã¯ãç§ã«ãšã£ãŠãããŸã§ã§æãé«åºŠãªæ¹æ³ã§ãã
ããããi18nextããéçãªæ¹æ³ãã§ãããšã¯æããŸããã
ããã°æçš¿ã«ã€ããŠãç§ã¯ãããã®è³ªå/äºçŽãããŸããïŒ
https://twitter.com/semdubois/status/930389055388508160
https://github.com/angeloocana/gatsby-plugin-i18nããã
ç§ãjslinguiã«åºããããŸããããç¹ã«v2ããªãªãŒã¹ãããã°ããã®å Žåã¯ææãªããã§ãã
ç§ããããç解ããããšããŠããŸãã æçš¿ã§i18nextã¡ãœããã䜿çšããã®ãæã䟿å©ã§çŽæçã§ããã2ã€ã®è³ªåãæ®ã£ãŠããŸãã
gatsby-plugin-i18nãœãªã¥ãŒã·ã§ã³ã®ããã«ãèšèªçšã«ç°ãªãããŒã¯ããŠã³ãã¡ã€ã«ãçµã¿èŸŒãã«ã¯ã©ãããã°ããã§ããïŒ
ããã¯ãã³ã³ãã³ãã®éçã¬ã³ããªã³ã°ãå®å šã«æŸæ£ããŸããïŒ
åèãŸã§ã«@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ã¯ã次ã®æ§æã§åæåãããŸãã
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ãã©ã°ã€ã³ã«ã¢ããã¹ããªãŒã ãããã·ã¥ããããã«ãããããäœããåŠã¶ããšãã§ãããã©ããã確èªããããšæããŸãã ããããšãã
ç§ã®ãããžã§ã¯ãå šäœã¯çŸåšä¹±éãªç¶æ ã§ãããåºæ¬ãã¬ã€ã¢ãŠãã§ãããšæããŸã...
ã¬ã€ã¢ãŠããªã-ïŒç§ãæ£ããèŠããŠããã°ïŒã¬ã€ã¢ãŠãã¯ãã¹ãéåžžã«éèŠãªäœãã®åã«æ©èœããé©åãªã¡ãã»ãŒãžãªããžã§ã¯ããäžããããšãã§ããªãã£ãããã§ã...
ã³ã³ããã¹ããä»ããŠ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;
};
// 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>
);
};
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
èŠã€ãããŸããã 誰ãæãããããããŸããïŒ
ç§ã®æ§æïŒ
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ã¹ã¿ãŒã¿ãŒãè¿œå ããŸããã ïŒãã¢ïŒ
ç¹åŸŽïŒ
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ã®ãããªä»ã®æ¬åœã«çŽ æŽããããœãªã¥ãŒã·ã§ã³ãã泚æãããããŸããç解ããäžç·ã«çµã¿ç«ãŠãªããã
ç§ã¯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ãã¡ã€ã«ã®è©³çŽ°ãããã³ãã®ã¹ã¬ããã®ã»ãšãã©ã®ãœãªã¥ãŒã·ã§ã³ãæé©åãããŠããªãçç±ãç¥ãããå Žåã¯ããã®åé¡ã圹ç«ã€ããšãããããŸãã
æãåèã«ãªãã³ã¡ã³ã
ããã¿ããªãããäžå¹Žè¿ãçµã¡ãŸããð
ç§ã¯æè¿ãæ°ããgatsbyãã©ã°ã€ã³gatsby-plugin-intlããªãªãŒã¹ããŸãããããã«ãããgatsbyWebãµã€ããããã«äœ¿çšã§ããåœéåãã¬ãŒã ã¯ãŒã¯ãšããŠç°¡åã«äœæã§ããŸãã
ãã¢ïŒ https ïŒ
ããã«äœ¿ããåœéå-
react-intl
å©çšãããã¬ãŒã ã¯ãŒã¯ãã©ãŠã¶ã§ã®ãŠãŒã¶ãŒã®åªå èšèªã«åºã¥ãèªåãªãã€ã¬ã¯ãããµããŒã
åäžããŒãžã³ã³ããŒãã³ãã§å€èšèªURLã«ãŒãããµããŒãããŸãã ããã¯ã
pages/en/index.js
ãpages/ko/index.js
ãªã©ã®åå¥ã®ããŒãžãäœæããå¿ èŠããªãããšãæå³ããŸããäžã§ææ¡ããããã«ããã«ãæã«çŸåšã®èšèªã®ã¿ããã³ãã«ãããããã«ãªããŸããã
ãŸããi18nã®äŸ/ã¹ã¿ãŒã¿ãŒã®å€ãã¯å®éã«ã¯ã¯ã©ã€ã¢ã³ãåŽã§ã¬ã³ããªã³ã°ãããŠããããšã«ãèšåããããšæããŸãã ã¢ããªãSSRãšããŠã¬ã³ããªã³ã°ãããŠãããã©ããã確èªããæè¯ã®æ¹æ³ã¯ããœãŒã¹ã³ãŒãã衚瀺ããããŒã«ã©ã€ãºãããããã¹ããååšãããã©ããã確èªããããšã§ãã ããªããSEOã®ããã«ããªãã®gatsbyãŠã§ããµã€ããåœéåãããšãããã®åé¡ãå確èªããŠãã ããã