I18n with TinaCMS


I successfully integrated TinaCMS in my project (Gatsby) and I think it is a great solution for both content maintainers and translators, I couldn’t think of a better solution :star_struck:, so I really like to show it off here.

My current project has to support 7 languages. I figured out that there are basically 2 kinds of translations with JAMStack sites:

  1. Page content: You will have one Markdown or JSON per language per page that contains a translated version of the page’s content structure. This information is bound to a specific page context.
  2. UI Messages: You will have localizable texts like Call to Actions and Link Titles you want to use across several page contexts. You would define those messages in either Markdown or JSON.

To solve problem 1, I simply had to wrap my page templates with remarkForm, add the TinaRemark fragment and define descriptive form fields.

Problem 2 was a bit trickier. I didn’t want to use a global form (because it is modal), but have access to translate UI messages from any page context and see live updates. Furthermore I wanted to have type-safe access in code (I use the graphql type generator for TypeScript).

Also, you can’t import the JSON as a module in code, because then every write to disk would trigger HMR and refresh the page, which makes the messages uneditable.

I ended up writing one hook to fetch the UI messages from JSON with a static query and filter results by localeCode (unfortunately static queries don’t support parameters yet). This hook also provides a type-safe accessor function for the UI messages to use in code. Looks like getJsonMessage(msgs => msgs?.actions?.subscribe).

I then defined another hook for TinaCMS that makes use of the UI messages hook, derives form fields from the JSON structure of the UI messages and calls useLocalJsonForm. I then use that Tina hook in my Layout component to edit the UI messages from any page context.

The result is a super-intuitive interface, that utilizes the actual language switching feature of the site to make it super-easy and a no-brainer for content editors and translators to find and edit the right information. They never have to deal with pageIDs and localeCodes, they just navigate to the content they want to edit and can edit it.


Great writeup! :100:

Good writeup, do you think you could share the config as an starter project? or at least share the relevant config and json files?
Thanks in advance!

This looks awesome! I will need this for one of my sites. I’ve had to edit those markdown files manually for too long already!
Please do share more if you find the time.