A Simple Way to Internationalize in Go with go-i18n

Today we are going to explore another internationalization library in Go called go-i18n. It's a library that can help by providing a convenient API over some common localization tasks from organizing translation in files up to automating procedures.

In the past, we’ve seen how to do i18n with Go using the  golang.org/x/text  package. Although it’ a very extensive library, it’s also very difficult to use in practice and the documentation lacks clarity. For an easier way to localize our Go apps, we have another solution called go-i18n.

go-i18n supports:

  • Pluralized strings for all 200+ languages
  • Strings with named variables
  • Message files of any format (e.g. JSON, TOML, YAML, etc.).
  • Well documented

However for the time being it does not support gender rules or complex template variables, but for a lot of cases, it should be enough to localize existing apps. In this tutorial, we will see some practical examples and also try to integrate Phrase’s in-context editor in the process. All the code examples are hosted also on Github. Let’s get started.

Defining and Translating Messages

Before we use this library we need to download and install it to our $GOPATH. Let’s do that now:

Now create a new file to test some translations:

File: example.go

The first step is to create a Locale Bundle that will contain the list of supported locales and the default locale. Let’s create one with default as English

Now in order to perform translations, we need to create an instance of a Localizer passing a list of locales we want to translate. If we have a list of translated locales it will pick the right locale based on the language tags

As we haven’t got any messages we can add them now.

We can see the usage of Plural rules here and the usage of template variables.

In the final step we need to perform a translation:

The MustLocalize method will panic if there is an error. There is an associated Localize method that will return an error instead.

In the code above its crucial that we pass the messagesCount in both the TemplateData and in the PluralCount property to properly translate the plural rule.

Defining delimiters

We have an option to define different delimiter characters just in case we dislike the double brackets. We only need to define the LeftDelim and RightDelim properties and change the message strings to include them.

Loading messages from files

We also have the option to load translations from files. To do that we need to first register an Unmarshal Function in our bundle and load the messages from a file.

The contents of the JSON files are:

File: el.json

File: en.json

With the complete program try to run it and see the translations happening.

Using the command line tool

This library also comes with a command line tool to help to automate the process of extracting and merging translation files.
First, we need to install it

Currently, there are 2 commands provided:

  • extract: Extracts messages from sources and outputs to a file with a specific format
  • merge: Merges messages from 2 or more files with a specific format

Let’s see some examples of both

Create a file named messages.go

File: messages.go

Use the extract command to export the messages in JSON format.

File: out/active.en.json

Now using the existing translation files lets merge them together:

File: out/active.en.json

As you can see we have all the messages conveniently in a single file.

Integrating Phrase In-Context Editor

Phrase’s In-Context editor is a translation tool that helps the process by providing useful contextual information which improves overall translation quality. You simply browse your website and edit text along the way.

Although there is no integration for go-i18n if can follow this guide:


and we can register our own template filter and integrate into our app.

Let’s see how we can do that in simple steps.

Create a new file named inContext.go and add the following code.

File: inContext.go

This will create a web server and it will serve a page with a default language. If you open the browser and navigate to localhost:8080/?lang=el  you will see the Greek translations.

Now in order to integrate Phrase in-context editor we need to wrap the Template variables within the {{__phrase_  and  __}} delimiters and load the javascript agent.

We can utilize the https://golang.org/pkg/text/template/#Template.Funcs functionality to register our own translation filter and wrap that parameter once we configure it. Let’s do that now.

File: inContext.go

Here we add the translate function to be configured based on the phraseApp parameter config.

Now we only need to add this filter to each template parameter and add the Phrase script.

Update the template to include the apiToken parameter.

If you haven’t done that already, navigate to https://phrase.com/ signup to get a trial version.

Once you set your account up, you can create a project and navigate to Project Setting to find your projectId key.

Use that to assign the PHRASE_APP_TOKEN  environment variable before you start the server.

When you navigate to the page you will see a login modal and once you are authenticated you will see the translated strings change to include edit buttons next to them. The In-Context editor panel will show also.

From there you can manage your translations easier.


In this article, we have seen how to translate go applications using the go-i18n library. We’ve also seen how can we integrate Phrase’s In-Context Editor in our workflow. If you have any other questions left, don’t hesitate to post a comment or drop me a line. Thank you for reading and see you again next time!

A Simple Way to Internationalize in Go with go-i18n
4.4 (88%) 10 votes
Theo Phrase Content Team