Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide internationalization properly using Gatsby + Netlify CMS

I'm trying to make a multi-language site and faced some problems.

Expected behavior:

  1. Language automatically changes depends on browser language

  2. The user can switch language

    example: https://tic-tac-toe-ai.surge.sh/

I saw gatsby-plugin-i18nand 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

like image 746
Ponchique Avatar asked Jun 18 '18 17:06

Ponchique


2 Answers

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:

  • The implementation is really simple and doesn’t require any packages 🙅‍♀️
  • The maintenance is really easy


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


like image 63
Ponchique Avatar answered Oct 24 '22 08:10

Ponchique


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.

like image 29
fool Avatar answered Oct 24 '22 07:10

fool