Over a million developers have joined DZone.

Internationalization With Play Framework (2.6.x)

DZone's Guide to

Internationalization With Play Framework (2.6.x)

Learn the basics of application/website internationalization and ensure that your content can be read by anyone, anywhere in the world.

· Web Dev Zone ·
Free Resource

Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

In this blog, I will demonstrate how your application can support different languages using Play Framework 2.6.0.

What Is Application/Website Internationalization?

Application/Website Internationalization can be defined as a process of developing and designing an application that supports not only a single (human) language but also different languages so that it can be easily adapted by the users from any country or region of the world. It ensures that the code base of your application is flexible enough to serve a new audience without completely rewriting the code or keeping your text separate from the code base.

Let us start the implementation step by step.

1. Specifying Languages for Your Application

In order to specify languages for your application, you need Language tags, which are specially formatted strings that indicate specific languages such as “en” for English, “fr” for French, or a specific regional dialect of a language such as “en-AU” for English as used in Australia.

First, you need to specify the languages in the conf/application.conf file. Language tags will be used to create play.api.i18n.Lang instances.


 play.i18n.langs = [“en”, “fr”] 

2. Externalizing Messages

Go to your conf/messages.xxx files. Here we have two language-specific message files: messages.en for English and message.fr for French. If you don’t specify any message file for any specific language, then the default conf/messages file matches all languages.
You can provide messages in each language specific file like this:

default.message = Play Framework Example 

3. Message With Controller

Created a controller (MySupportController) that extends the I18nSupport trait.

The I18nSupport trait adds the following methods to a request:

  • request.messages returns the instance of messages, using the implicit MessagesAPI.
  • request.lang returns the preferred language, using the implicit MessagesAPI.

messagesApi.preferred method: By using this method, the preferred language is extracted from the Accept-Language header and the matching one from the MessageAPI supported languages.

The I18nsupport trait also adds two language cookies, with supported methods, to the Result:

  • result.withLang(lang: Lang) is used to set the language for future requests by storing it in cookies.
  • result.clearingLang is used to discard the language cookies set by withLang.
class MySupportController @Inject()(component: ControllerComponents,
                                    langs: Langs) extends AbstractController(component) with I18nSupport {
  val lang: Lang = langs.availables.head
  implicit val messages: Messages = MessagesImpl(lang, messagesApi)

  def index = Action { implicit request =>
    val messages: Messages = messagesApi.preferred(request)   // get the messages for the given request
    val message: String = messages("default.message")

  def homePageInFrench = Action {
    Redirect("/").withLang(Lang("fr"))    // set french language in the Play's language cookie for future requests 

  def homePageWithDefaultLang = Action {
    Redirect("/").clearingLang           // discarding the language cookie set by withLang

4. Messages With Twirl Template

@(message: String, style: String = "scala")(implicit messages: MessagesProvider)

@defining(play.core.PlayVersion.current) { version =>
        <div class="wrapper">
            @if(messages.messages.lang.language.equals("en")) {
                <a class = "button" href="@routes.MySupportController.homePageInFrench()">fr</a>
            } else {
                <a class = "button" href="@routes.MySupportController.homePageWithDefaultLang()">en</a>

    <div id="content" class="wrapper doc">

Here, Twirl templates take a MessageProvider, and it is assumed that a MessageProvider is passed into the template as an implicit parameter.

You can get the source code from here.

I hope this blog is helpful to you!



Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

web dev ,internationalization ,play framework

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}