{"id":15060172,"url":"https://github.com/octri/ember-i18next","last_synced_at":"2025-08-08T15:48:25.388Z","repository":{"id":26439505,"uuid":"29890279","full_name":"OCTRI/ember-i18next","owner":"OCTRI","description":"Integrates i18next into Ember CLI apps.","archived":false,"fork":false,"pushed_at":"2023-08-22T21:01:00.000Z","size":5571,"stargazers_count":8,"open_issues_count":16,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-07T21:18:03.775Z","etag":null,"topics":["addon","ember","ember-cli","i18n","i18next","javascript","translation"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OCTRI.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-27T00:55:52.000Z","updated_at":"2022-09-21T16:35:43.000Z","dependencies_parsed_at":"2024-06-21T14:19:05.456Z","dependency_job_id":"350876b6-2f3c-4306-b0f1-e0ddb2dd9416","html_url":"https://github.com/OCTRI/ember-i18next","commit_stats":{"total_commits":384,"total_committers":13,"mean_commits":29.53846153846154,"dds":0.59375,"last_synced_commit":"b1b35cba2241c64c07b402d73cb81f7ae00a8f40"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OCTRI%2Fember-i18next","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OCTRI%2Fember-i18next/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OCTRI%2Fember-i18next/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OCTRI%2Fember-i18next/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OCTRI","download_url":"https://codeload.github.com/OCTRI/ember-i18next/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166881,"owners_count":21058479,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["addon","ember","ember-cli","i18n","i18next","javascript","translation"],"created_at":"2024-09-24T22:54:04.118Z","updated_at":"2025-04-10T05:45:56.186Z","avatar_url":"https://github.com/OCTRI.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ember-i18next\n![Build Status](https://github.com/OCTRI/ember-i18next/workflows/CI/badge.svg)\n\n## About\n\nAn [Ember CLI](http://www.ember-cli.com/) addon for internationalizing Ember.js applications using the [i18next](http://i18next.com/) library. The addon provides an Ember service that wraps i18next and a Handlebars helper for displaying localized text in templates.\n\n## Compatibility\n\nember-i18next supports current Ember (release, beta, canary) and the last two LTS releases.\n\n## Installation\n\nTo install with Ember CLI:\n\n```bash\nember install ember-i18next\n```\n\n## Configuration\n\n### Configuring i18next\n\nTo configure the [i18next options](https://www.i18next.com/configuration-options.html) and the [XHR backend options](https://github.com/i18next/i18next-xhr-backend#backend-options), add them to your `environment.js`:\n\n```javascript\n// ...\nlet ENV = {\n  // ...\n  i18nextOptions: {\n    // any options supported by i18next\n    backend: {\n      // any options supported by i18next-xhr-backend\n    },\n    // set to true if you want to catch errors when initializing i18next\n    rejectError: false\n  },\n  APP: {\n    // ...\n  }\n}\n```\n\nIf you do not specify any options, the default i18next options will be used.\n\n### Initializing i18next\n\nTo initialize the i18next library, call the i18n service's `initLibraryAsync` method. This method returns a promise that resolves when the library finishes initializing, so if you call it in one of the model hook methods (`beforeModel`, `model`, `afterModel`), the application will enter the loading substate until i18next is initialized. The application route may be a good place to do this.\n\n#### Handling Initialization Errors\n\nBy default, this addon will catch any initialization errors and display a warning in the console. If you want to catch and handle the errors, set the `rejectError` option to true and handle the errors in a `catch` block.\n\n```javascript\n// app/routes/application.js\nimport Route from '@ember/routing/route';\n\nexport default Route.extend({\n\n  beforeModel() {\n    return this.get('i18n')\n      .initLibraryAsync()\n      // only if `rejectError` option is set to true\n      .catch(errors =\u003e this.transitionTo('my-error-page', errors));\n  }\n\n});\n```\n\n### Including Locale Files\n\nBy default, i18next loads locale files from the server asynchronously from the server path configured using the XHR backend's [`loadPath`](https://github.com/i18next/i18next-xhr-backend#backend-options) configuration option. To copy your application's locale resources from your source tree to the expected path during build, modify the application's `ember-cli-build.js`:\n\n```javascript\nconst EmberApp = require('ember-cli/lib/broccoli/ember-app');\nconst funnel = require('broccoli-funnel');\n\nmodule.exports = function(defaults) {\n  const app = new EmberApp(defaults, {\n    // build options\n  });\n\n  const locales = funnel('app/locales', {\n    srcDir: '/',\n    destDir: '/locales'\n  });\n\n  // other configuration, app.import() calls, etc. ...\n\n  return app.toTree(locales);\n}\n```\n\nIn this example, [Broccoli Funnel](https://github.com/broccolijs/broccoli-funnel) recursively copies locale files from the application's `app/locales/` directory to `dist/locales/` when the application is built.\n\n## Use\n\n### Service\n\nIf you need to produce translated strings in routes, components or controllers, you can [inject the `i18n` service](https://guides.emberjs.com/v3.17.0/applications/dependency-injection/#toc_ad-hoc-injections). This will then give access to [i18next's `t()` function](https://www.i18next.com/essentials.html) in your code. For example:\n\n```javascript\n// app/components/example-component.js\nimport Component from '@ember/component';\nimport { computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\n\nexport default Component.extend({\n  i18n: service(),\n  messages: someObject,\n\n  messageCount: computed('messages', function () {\n    const i18n = this.get('i18n');\n    const count = this.get('messages.count');\n    return i18n.t('messages.count', { msgCount: count });\n  }\n});\n```\n\nFor convenience, a mixin is provided that injects the i18n service and adds a `t()` function to the including class. For example, the above could be accomplished using the mixin like this:\n\n```javascript\n// app/components/example-component.js\nimport Component from '@ember/component';\nimport { computed } from '@ember/object';\n\nimport I18nMixin from 'ember-i18next/mixins/i18n';\n\nexport default Component.extend(I18nMixin, {\n  messages: someObject,\n\n  messageCount: computed('messages', function () {\n    const count = this.get('messages.count');\n    return this.t('messages.count', { msgCount: count })\n  });\n});\n```\n\n### Handlebars Helper\n\nYou can access your app's translations in templates using the `t` helper:\n\n```handlebars\n\u003cbutton type=\"button\"\u003e{{t 'button.text'}}\u003c/button\u003e\n```\n\nPass values to be interpolated into the translation as [hash arguments](http://handlebarsjs.com/guide/expressions.html#helpers-with-hash-arguments). For example, for a translation that includes an interpolated `{{count}}` value:\n\n```handlebars\n\u003cdiv\u003e{{t 'messages.count' count=model.messageCount}}\u003c/div\u003e\n```\n\n### Macro\n\nYou can create computed properties that watch for locale changes:\n\n```js\nimport { translationMacro as t } from \"ember-i18next\";\n\nexport default Ember.Component.extend({\n  // A simple translation.\n  title: t('user.edit.title'),\n\n  followersCount: 1,\n  count: Ember.computed.alias('followersCount'),\n\n  // A translation with interpolations. This computed property\n  // depends on `count` and will send `{ count: this.get('count') }`\n  // in to the translation.\n  followersTitle: t('user.followers.title', 'count')\n});\n```\n\nThe macro relies on this.get('i18n') being the `service:i18n`. Make sure it is injected somehow.\n\n### Current Locale\n\nThe current locale is exposed via i18n service's `locale` property. To change the language that the application is displayed in, simply set this property, and all of the text displayed using the `t` helper will be updated. For example, triggering the following controller action would update all of the text to Thai:\n\n```javascript\n// app/controllers/example-controller.js\nimport Controller from '@ember/controller';\nimport I18nMixin from 'ember-i18next/mixins/i18n';\n\nexport default Controller.extend(I18nMixin, {\n  actions: {\n    showThai() {\n      this.set('i18n.locale', 'th-TH');\n    }\n  }\n});\n```\n\n### Pre- and Post-Init Actions\n\nChanging the locale causes i18next to be reinitialized, which can destroy state. For example, if you have used `addResources` to load additional localization strings, they will be lost during initialization. To handle management of state around library initialization, you can register actions to perform before and after library initialization with the i18n service using the `registerPreInitAction` and `registerPostInitAction` methods.\n\n```javascript\nimport Route from '@ember/routing/route';\nimport I18nMixin from 'ember-i18next/mixins/i18n';\n\nexport default Route.extend(I18nMixin, {\n  init() {\n    this._super();\n    const i18n = this.get('i18n');\n\n    // my-fancy-action is a name that can be used to unregister the action later\n    i18n.registerPostInitAction('my-fancy-action', oldLang =\u003e {\n      // do preloading\n    });\n  }\n}\n```\n\nPre- or post-init actions may return a promise. If any of the actions returns a promise, the service will wait for the promises to resolve before moving on. If pre-init actions return promises, the service will wait for them to resolve before initializing i18next. If post-init actions return promises, the service will wait for them to resolve before notifying the application about the change in locale.\n\nThe new locale is passed as a parameter to pre-init actions and the old locale to post-init actions. These parameters are `undefined` when the the i18n service's `initLibraryAsync` method is called.\n\nFinally, actions may be unregistered using the `unregisterPreInitAction` and `unregisterPostInitAction` methods. To unregister the post-init action from the previous example, you would do the following:\n\n```javascript\n// ...\ni18n.unregisterPostInitAction('my-fancy-action');\n// ...\n```\n\n## Testing\n\n### Acceptance Tests\n\nNo special configuration is required for acceptance testing, although it may be convenient to configure the default locale and preload locales for use in the tests. For example:\n\n```javascript\n// in environment.js\nif (environment === 'test') {\n  // ...\n  ENV.i18nextOptions.lng = 'en-US';\n  ENV.i18nextOptions.preload = ['en-US', 'th-TH'];\n}\n```\n\n### Component Integration Tests\n\nIf you need to make assertions about the text rendered in component integration tests, you can [initialize the i18n service in a `beforeEach` hook](https://github.com/OCTRI/ember-i18next/issues/31).\n\n```javascript\nmoduleForComponent('some-component', 'Integration | Component | some component', {\n  integration: true,\n\n  beforeEach(assert) {\n    const done = assert.async();\n    this.inject.service('i18n');\n    this.get('i18n').initLibraryAsync().then(done);\n  }\n});\n```\n\n### Unit Tests\n\nUnit tests for objects that inject the i18n service or use the `{{t}}` helper should add them to the `needs` array.\n\n```javascript\nmoduleForComponent('other-component', 'Unit | Component | other component', {\n  unit: true,\n  needs: ['service:i18n', 'helper:t'],\n});\n```\n\n## Collaborating\n\nContributions are happily accepted. Make sure that your pull request includes tests and your JavaScript source is styled as described in the [Ember.js JavaScript style guide](https://github.com/emberjs/ember.js/blob/master/STYLEGUIDE.md).\n\n## Acknowledgements\n\nEarly versions of this addon were strongly influenced by the  [ember-cli-i18n](https://github.com/dockyard/ember-cli-i18n) addon.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foctri%2Fember-i18next","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foctri%2Fember-i18next","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foctri%2Fember-i18next/lists"}