How To Translate EmberJS Apps

This step-by-step guide will show you how to localize EmberJS apps. Prerequisites Create a new, blank EmberJS application.

This step-by-step guide will show you how to localize EmberJS apps.

Prerequisites

Create a new, blank EmberJS application:

ember new demoapp

Switch to the newly created demo app directory and install the i18n add-on:

npm install ember-cli-i18n --save-dev

Next, create two language files, Englisch (en) and German (de):

ember generate locale en
ember generate locale de

Language Files

Language files (locales) hold all translatable strings that are used in your application code and templates. The format is simple:

// app/locales/en.js
export default {
  "greeting": "Hello User",
  "task-create": "Create new task",
  "task-delete": "Delete task",
  "task-open": "You have open tasks"
};

Strings can also be grouped:

// app/locales/en.js
export default {
  greeting: "Hello User",
  "task": {
    "create": "Create new task",
    "fail": "Delete task",
    "open": "You have open tasks"
  }
};

You can use Placeholders…

// app/locales/en.js
export default {
  "greeting": "Hello %@",
  "task": {
    "create": "Create new task",
    "fail": "Delete task",
    "open": "You have %@ open tasks"
  }
};

… and Pluralization (CLDR pluralization format):

// app/locales/en.js
export default {
  "greeting": "Hello %@",
  "task": {
    "create": "Create new task"
    "fail": "Delete task"
    "open": {
      "zero": "Nothing to do",
      "one": "One open task",
      "other": "You have %@ open tasks"
    }
  }
};

Using Language Files

Set a default language that is used as a fallback in config/enviroment.js:

// config/enviroment.js
var ENV = {
  APP: {
    // ...
    defaultLocale: 'en',
  }
};

And in your main app/app.js, set the current locale to be used:

// app/app.js
var App = Ember.Application.extend({
  // ...
  locale: 'de'
});

In your templates and app code you can use the ‘t’ helper function (‘t’ for translate) for loading strings from the current locale. The t function is available in all templates, controllers, components, routes, and models.

You can load translated strings into your templates:

<h1>{{t 'greeting'}}</h1>
<h2>{{t 'task.create'}}</h2>
<h2>{{t 'task.delete'}}</h2>

Or in your code:

alert(this.t('task.open', 42));

Managing Translations

Working with the .js language files can be tricky and translating strings in a text editor also isn’t a very convenient workflow.

Phrase is a translation management tool that addresses some of these issues. It features a powerful In-Context Editor (Demo), making the process of translating web apps more convenient. Integrating the Phrase In-Context Editor in your EmberJS apps is easy.

Install the Phrase add-on:

npm install ember-cli-phraseapp --save-dev

Add some Phrase configuration to your app/app.js:

// app/app.js
var ENV = {
  APP: {
    // ...
    defaultLocale: 'en',
    locale: 'de',
    phraseEnabled: true,
    phrasePrefix: '{{__',
    phraseSuffix: '__}}'
  }
};

Then include the JavaScript snippet into your templates:

<script>
    window.PHRASEAPP_CONFIG = {
        projectId: "YOUR-PROJECT-ID"
    };
    (function() {
        var phraseapp = document.createElement('script'); phraseapp.type = 'text/javascript'; phraseapp.async = true;
        phraseapp.src = ['https://', 'phraseapp.com/assets/in-context-editor/2.0/app.js?', new Date().getTime()].join('');
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(phraseapp, s);
    })();
</script>

You can find your Project-ID in the Phrase Translation Center.

ember-cli-phraseapp acts as a replacement for ember-cli-i18n. When phraseEnabled is set to true, string keys are exposed to the to the In-Context-Editor.

Wrapping Up

We hope this short introductory guide was helpful to you. To get deeper into the EmberJS framework, make sure to go take a look at the official EmberJS website and the ember-cli-i18n GitHub repo.
If you feel like venturing a bit and exploring what software internationalization can look like in other JavaScript frameworks, feel free to drop by the following tutorials:

Be sure to subscribe and receive all updates from the Phrase blog straight to your inbox. You’ll receive localization best practices, about cultural aspects of breaking into new markets, guides and tutorials for optimizing software translation and other industry insights and information. Don’t miss out!

Keep exploring

Photo-realistic sheet music featuring developer-style translation code in place of musical notes. The staff lines show snippets like t('auth.signin.button') and JSON structures, combining the aesthetics of musical notation with programming syntax to illustrate the idea of “composable localization.”

Blog post

Localization as code: a composable approach to localization

Why is localization still a manual, disconnected process in a world where everything else is already “as code”? Learn how a composable, developer-friendly approach brings localization into your CI/CD pipeline, with automation, observability, and Git-based workflows built in.

A woman in a light sweater sits in a home office, focused on her laptop, representing a developer or content manager working on WordPress localization tasks in a calm, professional environment.

Blog post

How to build a scalable WordPress i18n workflow

WordPress powers the web, but translating it well takes more than plugins. Discover how to build a scalable localization workflow using gettext, best practices, and the Phrase plugin.

Blog post

Localizing Unity games with the official Phrase plugin

Want to localize your Unity game without the CSV chaos? Discover how the official Phrase Strings Unity plugin simplifies your game’s localization workflow—from string table setup to pulling translations directly into your project. Whether you’re building for German, Serbian, or beyond, this guide shows how to get started fast and localize like a pro.

Blog post

Internationalization beyond code: A developer’s guide to real-world language challenges

Discover how language affects your UI. From text expansion to pluralization, this guide explores key i18n pitfalls and best practices for modern web developers.

A digital artwork featuring the Astro.js logo in bold yellow and purple tones, floating above Earth's horizon with a stunning cosmic nebula in the background. The vibrant space setting symbolizes the global and scalable nature of Astro’s localization capabilities, reinforcing the article’s focus on internationalization in web development.

Blog post

Astro.js localization part 2: dynamic content localization

Learn how to localize your Astro.js website with static and dynamic content translation. Explore Astro’s built-in i18n features and Paraglide for handling UI elements, navigation, and dynamic text seamlessly.