Localise Your Go App With Package Text | by Cheikh seck | Aug, 2022

Build your app to reach the world

Image by author

Localisation, in essence, enables an application to reach multiple Global markets. Localisation “is the process of adapting software to both the culture and language of an end user.” This involves making design and UX changes to appeal to the end user. This ranges from appropriate text translation or even removing potentially offensive content.

For example, Arabic countries write from right-to-left, whereas most western countries write left-to-right. Go has a localisation library; it is part of its sub-repositories. This module has a path I’ll refer to it as the text package in this post. Package textenables developers to add localisation following a functional or OO programming model. It supports printing formatted strings, which is a game changer.

It can also recognise individual words and translate them. In this post, I’ll detail my approach to implementing a localised program.

For my use case, I’ll write Go code that will translate English to French. As a native speaker of both languages, I understand that machine-translated text can sometimes be incoherent. This will be apparent as you read along the post. Here is the initial code:

package mainimport (
func main(){ message.SetString(
"The %m car",
"La voiture %m",

For this example, I’m taking the functional approach to adding localisation. I call message’s SetString function to teach the program how to translate a particular string. The verb %m will display translated text. If you noticed the verb %m switches position for the french translation. This illustrates how a simple sentence is restructured in another language. I want a verb %m to display a color, however the program does not know about French colors. To teach the program, I’ll add the following lines:


Unlike my previous invocation to SetString , I’m only adding one word. This demonstrates the power of the package, as I don’t need to add multiple variants of the sentence The %m car . To display localised text, I’ll run the code below:

p := message.NewPrinter(language.French)
fmt.Println( p.Sprintf("The %m car", "green") ) // prints La voiture vert
fmt.Println( p.Sprintf("The %m car", "red") ) // prints La voiture red

This is the output from the terminal:

If you noticed the second line printed as La voiture red . I haven’t taught the program to translate the word red yet. I also effortlessly manage sentence structure, another benefit of the package. This is the basic example. Here is a complex one.

I have often built and seen programs that “misgenerate text.” For example, I was once building an alert component, and the header of the component would sometimes read You have 1 notifications left . This sentence is not correct, as notification is pluralised. text has a feature just for this, and it’ll be my next example. Instead of invoking SetString , I will use the function Set to correct the plurality issue stated above. This example will not involve any translation. Here is Set’s function signature:

func Set(tag language.Tag, key string, msg ...catalog.Message) error

The function is quite similar to SetString , except for the msg argument. This is how I’ll be able to tell the program how to handle plural words. This is the initial code:

package mainimport (
func main(){

message.Set(language.English, "You are %d minute(s) late.",
plural.Selectf(1, "",
plural.One, "You are 1 minute late.",
plural.Other, "You are %d minutes late."),

p2 := message.NewPrinter(language.English)
fmt.Println( p2.Sprintf("You are %d minute(s) late.", 1 ) )
fmt.Println( p2.Sprintf("You are %d minute(s) late.", 5 ) )

If you noticed above, there is a package function invoked with the name Selectf . “Selectf returns the first case for which its selector is a match.” In this case, there are two selectors:

  • plural.One to indicate a case where the integer provided is 1.
  • plural.Other to denote any other integer value.

Here is the code in action:


Here is the function signature of Selectf :

func Selectf(arg int, format string, cases ...interface{}) catalog.Message

While defining cases, you would define the selector, and the following argument would be the text for that selector. For example, to add text for when integer 1 is passed would be Selectf(...,plural.One, "Format for one",...)

Here is the icing on the cake for this library. It can extract all the text you have in a program automatically. This removes the need to manually look for each text that should be localised. It also has a command to automatically replace all fmt invocations with a localised text printer. However, the program does not support Go 1.18, so I won’t be demoing it in this post.

In a highly globalised world, developers must localise their application to penetrate certain markets. Localising your application will make sure consumers running your program understand it. The package text is a localisation implementation from the Go team. The latest release of this package was in August 2021, forcing me to ponder its stability.

It is important to note that there are open source alternatives to package text . This was my attempt to bring light to an interesting yet powerful localisation package. There are other ways to implement the package. This was my take on the subject. You can find a link to the package below.

News Credit

%d bloggers like this: