Migration from v5 to v6
Over 3 years passed since 5.0.0 had been released on May 2020. Unfortunately, whether the merged pull requests resulted in a feature, bug fix, or breaking change hasn't been documented well. (We will do a better job going forward.)
The lists below describe what you may encounter when updating ember-intl from 5.7.2, the last stable release. If there is a missing item, please create a pull request to help complete this page.
IMPORTANT
6.0.0 had been released by accident and isn't a stable version. Version 6.1.0 marks the beginning of the 6.x series.
Breaking changes
Minimum requirements
Projects with these versions are supported when issues arise.
- Ember 3.28 and above
- Node 16 and above
- TypeScript 4.8 and above
In addition, ember-auto-import@v2 is required.
Missing setupIntl results in a runtime error
If a rendering test (also called an integration test) depends on ember-intl (e.g. because you used the {{t}} helper in the template, injected the intl service in the backing class, or rendered another component that depends on ember-intl), then you must add setupIntl to your test. Otherwise, you will encounter the runtime error,
You attempted to update `_locale` on ..., but it had already been used previously in the same computation.The fix is manual. To see which tests are missing setupIntl, you can run your tests (e.g. ember test --server) and check the error messages in the console.
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
+ import { setupIntl } from 'ember-intl/test-support';
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
module('Integration | Component | hello', function (hooks) {
setupRenderingTest(hooks);
+ setupIntl(hooks);
test('it renders', async function (assert) {
await render(hbs`
<Hello @name="Zoey" />
`);
assert.ok(true);
});
});Missing other clause results in a build error
If a translation message has an argument of the plural type, then it must have the other clause. Otherwise, you will see the build error,
Build Error (TranslationReducer)
An error occurred (MISSING_OTHER_CLAUSE) when extracting ICU arguments for ...The fix is manual. Find translations with the keyword plural, then define other.
- message: You have {itemCount, plural, =0 {no items} one {# item}}.
+ message: You have {itemCount, plural, =0 {no items} one {# item} other {# items}}.Renamed re-export for the intl service
In v5.5.0, the intl service class had been re-exported in the "barrel" file (the index file). However, the name of the re-exported class, Service, happened to collide with the name of the Service class from @ember/service.
To prevent people from using the wrong Service class and help IDE suggestions pick the correct import path, the re-exported class is now named IntlService.
- import { Service } from 'ember-intl'; // Bug
+ import Service from '@ember/service';
this.owner.register('service:api', class Api extends Service {
// ...
});Type-only re-export for the intl service
If you had used the value re-export of the intl service class, inject the service instead. The type re-export can be used to type the injected service, if you don't want to follow the service registry approach.
import { service } from '@ember/service';
import Component from '@glimmer/component';
import type { IntlService } from 'ember-intl';
export default class Example extends Component {
@service declare intl: IntlService;
}Features
Dynamically set named arguments
v6.0.0-beta.3 introduced the ability to dynamically set named arguments. You can pass an object (a POJO) to the first positional argument.
{{t "say.hello" @user}}For more information, visit Passing data.
Glint support
v6.0.0-beta.5 added a template registry to support Glint. This removes the need for @gavant/glint-template-types for typing ember-intl's helpers.
import '@glint/environment-ember-loose';
import type EmberIntlRegistry from 'ember-intl/template-registry';
declare module '@glint/environment-ember-loose/registry' {
export default interface Registry extends EmberIntlRegistry, /* other addon registries */ {
// local entries
}
}Two ways to type the intl service
v5.5.0 introduced TypeScript support. You might have retrieved the type IntlService from 'ember-intl/services/intl', a long path to remember and type.
import { service } from '@ember/service';
import Component from '@glimmer/component';
import type IntlService from 'ember-intl/services/intl';
export default class Example extends Component {
@service declare intl: IntlService;
}In v6, ember-intl recommends importing the type in one of two ways.
Import
IntlServicefrom the "barrel" file (theindexfile):tsimport { service } from '@ember/service'; import Component from '@glimmer/component'; import type { IntlService } from 'ember-intl'; export default class Example extends Component { @service declare intl: IntlService; }Use the service registry:
tsimport { type Registry as Services, service } from '@ember/service'; import Component from '@glimmer/component'; export default class Example extends Component { @service declare intl: Services['intl']; }
The registry pattern may be preferred if you need to inject multiple services and want to avoid having many import statements.