Reputation: 13393
I am trying to add multi-language to this gatsbyjs template using the gatsby-plugin-intl.
Field level translation: Each field marked by translatable will have a translation and you have a single content item for all translations.
Multi-tree translation: Each translation will have it's own content item and the translations are saved in different folders.
The pages in the pages
folder use Field level translation and work completely as should. The pages in the content
folder uses Multi-tree translation using markdown files, but do not work entirely as desired/ should. Their routing is off.
Basically I would like to have these pages follow this routing:
/en/mypage/
should give english version/ko/mypage/
should give korean versionHowever I now get for the markdown source pages following:
/en/mypage/en/
and /ko/mypage/en/
give english version/en/mypage/ko/
and /ko/mypage/ko/
give korean versionI tried renaming of the slug in one of the hooks (onCreatePage, onCreateNode, createPages), but no success so far. When trying it seems one of the versions (en/ko) gets overwritten so then you end up with just one language for both routes. How to solve this?
E.g. amsterdamfurniturelab.nl/en/bear-desk/en
turns into amsterdamfurniturelab.nl/nl/bear-desk/en
but does not show nl-translation.
Upvotes: 2
Views: 1333
Reputation: 3209
gatsby-plugin-intl
only supports field-level translations, passing JSON translation keys via Context.
From the plugin's README:
you don't have to create separate pages such as
pages/en/index.js
orpages/ko/index.js
[...] the plugin will create static pages for every language
So if you have 2 languages, say NL and EN, the plugin will generate 3 pages for each slug. So if you have a /bear-desk/
page, you will get:
"/en/bear-desk/" <-- EN locale
"/nl/bear-desk/" <-- NL locale
"/bear-desk/" <-- default: either redirects or renders the default locale based on plugin settings
In the repo you provided, you're using both gatsby-plugin-intl
and "manual" translations using two separate pages.
Since /bear-desk/en/
and /bear-desk/nl/
are seen as two different pages by the plugin, you're actually generating 6 pages for each slug:
For your /bear-desk/en/ page (no JSON translations found, all will be in EN)
"/en/bear-desk/en/"
"/nl/bear-desk/en/"
"/bear-desk/en/"
For your /bear-desk/nl/ page (no JSON translations found, all will be in NL)
"/en/bear-desk/nl/"
"/nl/bear-desk/nl/"
"/bear-desk/nl/"
If you wanted to change this behavior, you would create pages manually using Gatsby's createPage
API in gatsby-node.js
and make sure that you're creating the right pages at the right URLs.
There are multiple ways to do this. If you need inspiration, one example that seems close to your case is described in Building a multi-lingual static site with Gatsby on Hiddentao.
If other issues come up during your implementation, feel free to open a new question and I'll be happy to help!
I've been able to create the right URLs in the onCreatePage
API:
/*
here's what we want to do:
- for /nl/<slug>/nl/ create both /<slug>/ and /nl/<slug>/
- for /en/<slug>/en/ create /en/<slug>/
- for the rest of pages including <slug>, delete
*/
// note: optimally you would grab slugs from the fs or via graphql
const slugs = ["bear-desk", "cnc-explained"]
exports.onCreatePage = async ({
page,
actions: { createPage, deletePage },
}) => {
slugs.forEach(slug => {
if (page.path === `/nl/${slug}/nl/`) {
// create page in the default language (NL) at /slug
const defaultPage = { ...page, path: `/${slug}/` }
createPage(defaultPage)
console.log(`Created default page in NL at ${defaultPage.path}`)
// create a page for /nl/slug
const nlPage = { ...page, path: `/nl/${slug}/` }
createPage(nlPage)
console.log(`Created NL page at ${nlPage.path}`)
// delete the page with duplicate locale
deletePage(page)
console.log(`Deleted ${page.path}`)
}
else if (page.path === `/en/${slug}/en/`) {
// create a page for /en/slug
const enPage = { ...page, path: `/en/${slug}/` }
createPage(enPage)
console.log(`Created EN page at ${enPage.path}`)
// delete the page with duplicate locale
deletePage(page)
console.log(`Deleted ${page.path}`)
}
else if (page.path.includes(slug)) {
// delete all other pages with that slug
deletePage(page)
console.log(`Deleted ${page.path}`)
}
})
}
You'll get the routes you want:
"/en/<slug>/" <-- EN locale
"/nl/<slug>/" <-- NL locale
"/<slug>/" <-- default (NL locale in your case)
Although this creates the correct pages at the right routes, there is a major limitation: gatsby-plugin-intl
is not aware of it. This means that you need to manually implement language switching and linking to the right locale.
This is obviously not the best solution, but since the plugin doesn't support this type of localization, I'm not sure there's a more integrated way to do this (maybe others will have better ideas).
One more thing I would suggest is to make a feature request on the repo. Good luck!
Upvotes: 2