Migration guide from 2.x to 3.x
Check out the @lingui/codemods package for semi-automatic migration of your codebase.
Backward incompatible changes
Minimal required versions are:
- Node.js: 10.x
- React: 16.8
- Babel: 7
@lingui/react
-
<I18n>render-prop component was removed in favor ofuseLinguihook. -
In
I18nProvider,defaultRenderprop was renamed todefaultComponent, and now only accepts Custom Components -
In
Trans,defaultsprop was renamed tomessageanddescriptiontocomment. -
In
Trans,renderprop only accepts render-prop function which is used to render translation. -
In
Trans, new propcomponentaccepts React component which is used to render translation. -
In
Trans,componentsis now an object, not an array. When using the low level API, it allows to name the component placeholders:<Trans id="Read <a>the docs</a>!" components={{ a: <a href="/docs" /> }} /> -
NumberFormatandDateFormatcomponents were removed. Importi18nfrom@lingui/corepackage and usei18n.date()andi18n.number()instead.
Removed I18nProvider declarative API
LinguiJS started as a React library. After @lingui/core package was introduced, there were two ways how to switch active locales and manage catalogs in React: either using I18nProvider declarative API or using setupI18n imperative API.
In the same spirit as @apollo/react and react-redux, the I18nProvider is simplified and accepts i18n manager, which must be created manually:
import { I18nProvider } from '@lingui/react'
import { i18n } from "@lingui/core"
+ import { en } from 'make-plural/plurals'
import { messages } from './locale/en/messages.js'
+ i18n.loadLocaleData('en', { plurals: en })
+ i18n.load('en', messages)
+ i18n.activate('en')
function App() {
return (
- <I18nProvider locale="en" catalogs={{ en: catalogEn }}>
+ <I18nProvider i18n={i18n}>
<App />
</I18nProvider>
)
}
@lingui/core
-
Package now exports default
i18ninstance. It's recommended to use it unless you need customized instance.+ import { i18n } from "@lingui/core"
- import { setupI18n } from "@lingui/core"
- const i18n = setupI18n()
i18n.activate('en')NoteIf you decide to use custom
i18ninstance, you also need to setruntimeConfigModule. Macros automatically importi18ninstance and must be aware of correct import path. -
i18n.t,i18n.plural,i18n.selectandi18n.selectOrdinalmethods were removed in favor of macros. -
i18n.usewas removed. Using two locales at the same time isn't common use-case and can be solved in user land by having two instances ofi18nobject. -
Signature of
i18n._method has changed. The third parameter now accepts default message inmessageprop, instead ofdefaults:- i18n._('Welcome / Greetings', { name: 'Joe' }, { defaults: "Hello {name}" })
+ i18n._('Welcome / Greetings', { name: 'Joe' }, { message: "Hello {name}" }) -
i18n._also accepts a message descriptor as a first parameter:i18n._({
id: string,
message?: string,
comment?: string
})
i18n.load loads a catalog for a single locale
i18n manager is the single source of truth and there's no need to keep all catalogs loaded outside this object. To make loading easier, i18n.load now accepts catalog for a single locale or multiple catalogs at once.
import { i18n } from "@lingui/core"
import catalogEn from './locale/en/messages.js'
- i18n.load({ en: catalogEn })
+ i18n.load('en', catalogEn.messages)
You can still use i18n.load to load all catalogs at once:
// i18n.js
import { i18n } from "@lingui/core";
import catalogEn from "./locale/en/messages.js";
import catalogFr from "./locale/fr/messages.js";
i18n.load({
en: catalogEn.messages,
fr: catalogFr.messages,
});
@lingui/macro
-
plural,selectandselectOrdinalaccepts value as a first parameter:- plural({ value, one: "# book", other: "# books" })
+ plural(value, { one: "# book", other: "# books" })
@lingui/cli
- command
lingui initwas removed - command
lingui add-localewas removed
Whitespace
Whitespace handling in plugins had few bugs. By fixing them, there might be few backward incompatible changes. It's advised to run extract and inspect changes in catalogs (if any).
-
Spaces before
{variables}in JSX aren't preserved. This is how React handles whitespaces in JSX. Leading whitespace is always removed:<Trans>
"
{variable}
"
</Trans>
// Becomes: "{variable}" -
Forced newlines are preserved. Sometimes it's useful to keep newlines in JSX. If that's your case, you need to force it in the same was as spaces are forced before variables or elements:
<Trans>
1. Item{"\n"}
2. Item
</Trans>
// Becomes: 1. Item\n2. Item
Plugins/Presets
Plugins are replaced with macros. Presets are removed completely because they aren't needed anymore.
-
Uninstall plugins/presets, remove them from Babel config and replace them with
macros:- npm
- Yarn
- pnpm
npm uninstall @lingui/babel-preset-react
npm install --dev @lingui/macro babel-plugin-macrosyarn remove @lingui/babel-preset-react
yarn add --dev @lingui/macro babel-plugin-macrospnpm remove @lingui/babel-preset-react
pnpm add --dev @lingui/macro babel-plugin-macros{
"presets": [
- "@lingui/babel-preset-react"
],
"plugins": [
+ "macros",
]
} -
Import
Trans,Plural,SelectandSelectOrdinalfrom@lingui/macro:- import { Trans } from "@lingui/react"
+ import { Trans } from "@lingui/macro"NoteIf you used
Transcomponent without children, then keep the import from@lingui/react:import { Trans } from "@lingui/react";
const CustomID = () => <Trans id="msg.id" />;
const DynamicID = () => <Trans id={msgId} />; -
i18n.t,i18n.plural,i18n.selectandi18n.selectOrdinalmethods are removed and replaced with macros.These macros automatically binds message to default
i18nobject:import { i18n } from "@lingui/core"
+ import { t } from "@lingui/macro"
- i18n.t`Hello World`
+ t`Hello World`
New features
i18n.load
i18n.load can now accept one catalog for specific locale. Useful for incremental loading of catalogs.
import { i18n } from "@lingui/core";
// Lingui v2 and v3
i18n.load({
en: require("./locale/en/messages"),
cs: require("./locale/cs/messages"),
});
// Lingui v3 only
i18n.load("en", require("./locale/en/messages"));
i18n.load("cs", require("./locale/cs/messages"));
i18n.on('change', callback)
Event change is fired anytime new catalogs are loaded or when locale is activated.
Native TypeScript support
Lingui now supports TypeScript out of the box, don't forget to remove the @types/lingui packages from your project.