I'm trying to make a multi-language site and faced some problems.
Expected behavior:
Language automatically changes depends on browser language
The user can switch language
example: https://tic-tac-toe-ai.surge.sh/
I saw gatsby-plugin-i18n
and followed the recommendations how to use it, but my problem is I create pages automatically via Netlify CMS and can't get a proper file name, as needed: page.lang.md
I'm getting page-lang.md
.
I was wondering if anyone got a working approach already, or can tell me what am I doing wrong and maybe gatsby-plugin-i18n
doesn't fit this stack at all
Thanks in advance
It’s been a while ago when I was last working on it.
Seems like this topic is more-less still getting people interested, so I decided to share the approach I used to make an internationalization possible with Netlify CMS and Gatsby.
The Advantages:
But If you already have the working Gatsby/Netlify CMS project and want to add languages it be required to change a structure.
It’s really clean and easy especially when on creating a page in the specific language different people work on.
In my case I have only EN and DE. And two content managers for each language.
Since I need to create a pages in English and German only via CMS I simply created 2 collections in config.yml
#Blog-Post EN
- name: "blogEn"
label: "Blog (english)"
folder: `${your_folder}/blog`
filter: { field: contentType, value: blog }
create: true
slug: "{{slug}}"
identifier_field: slug
fields:
- {label: Template Key, name: templateKey, widget: hidden, default: templates/blog-post}
- {label: Slug, name: slug, widget: string}
- {label: Language, name: language, widget: hidden, default: en }
- {label: Content Type, name: contentType, widget: hidden, default: blog}
#Blog-Post DE
- name: "blogDe"
label: "Blog (deutsch)"
folder: `${your_folder}/de/blog`
filter: { field: contentType, value: blog }
create: true
slug: "{{slug}}"
identifier_field: slug
fields:
- {label: Template Key, name: templateKey, widget: hidden, default: templates/blog-post}
- {label: Slug, name: slug, widget: string}
- {label: Language, name: language, widget: hidden, default: de }
- {label: Content Type, name: contentType, widget: hidden, default: blog}
You might have noticed the collections are pretty much the same, so that means you are also able to create one single collection and replace language’s field widget hidden
with select
and put two options into it.
The output should be:
ENGLISH
---
templateKey: templates/blog-post
slug: my little slugy
language: en
contentType: blog
title: My little Posty
---
GERMAN
---
templateKey: templates/blog-post
slug: my little slugy
language: de
contentType: blog
title: My little Posty
---
Note* the slug of the same page in different languages should be the same as this is a key for our future Switcher (and good for SEO as far as I understand)
From this point gatsby-node should filter the pages by language, sanitize the input string and transform it to a valid slug.
We want these slugs for the pages:
/my-little-slugy/
/de/my-little-slugy/
And our sanitizing and kebabing looks like:
if (language === 'de') {
return _.kebabCase(slug).length === 0 ? '/de/' : `/de/${_.kebabCase(slug)}/`
} else {
return _.kebabCase(slug).length === 0 ? '/' : `/${_.kebabCase(slug)}/`
}
Don't worry - Lodash
and _.kebabCase()
comes with gatsby-starter-netlify-cms
, so still no additional packages.
The next step is fetching the language filed into your templates/blog-post.js
along with other data you need
and passing language
into the LanguageSwitcher component where gatsby link will redirect you from /my-little-slugy/
to /de/my-little-slugy/
and vice versa depends on current language passed in.
I didn’t put the whole logic of the template and Component here because it’s pretty heavy as has a lot of other features. But I hope you’ve got my idea. 

If people are still interested I will create an example repository.
Regarding redirection depending on location - as far as I understand it's fine for SEO to use a default language at the start(but I can be wrong), and if user wants to read in German - go and hit Switcher.
UPD
Here is the example repo where I do the same with pages and posts
Here is demo where you can see how it works
Here is a medium post where I describe how to do the same with pages
Since NetlifyCMS currently lacks direct localization support as of this writing, you'll currently have to edit a separate copy of each document with changed content by country. Once you have that, if you edit them all in separate folders (e.g. you have /blogposts/en
and /blogposts/de
- the CMS supports two directories but no automatic forcing of authors to make both versions or update both versions), you could then use netlify's geo redirects to make sure that someone in Germany gets /blogposts/de/ when they try to visit your blog, and someone in au,uk,ie,us,nz gets the /blogposts/en version of the posts:
/blogposts/* /blogposts/en/:splat 301! country=au,uk,ie,us,nz
/blogposts/* /blogposts/de/:splat 301! country=de
This means you can link to the posts as /blogposts/title and visitors will automatically be redirected with an HTTP 301 to the appropriate language.
You should consider having a "default" version for visitors from other nonspecified countries. Those would live in /blogposts/title and be shown with the above configuration ONLY if the visitor is not from ANY of the listed countries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With