Localization
The default constants are defined in the /shared/defaults.js file.
- The default locale of all components texts is:
nb-NO. - The default currency is:
NOK
Supported component translations
Eufemia components comes with a set of default translated strings for the following locales:
You can easily change one, some or all of them by using a React provider – the Eufemia Provider.
Here are the default strings located:
// Included by defaultimport enGB from '@dnb/eufemia/shared/locales/en-GB'import nbNO from '@dnb/eufemia/shared/locales/nb-NO'import enGB_forms from '@dnb/eufemia/extensions/forms/constants/locales/en-GB'import nbNO_forms from '@dnb/eufemia/extensions/forms/constants/locales/nb-NO'// Additional locales you can addimport svSE from '@dnb/eufemia/shared/locales/sv-SE'import svSE_forms from '@dnb/eufemia/extensions/forms/constants/locales/sv-SE'import svSE_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/sv-SE'// Additional locales you can addimport daDK from '@dnb/eufemia/shared/locales/da-DK'import daDK_forms from '@dnb/eufemia/extensions/forms/constants/locales/da-DK'import daDK_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/da-DK'Use `mergeTranslations` to combine the forms translations (and country translations when needed) before you pass them to `Form.Handler` or `Provider`.import { mergeTranslations } from '@dnb/eufemia/shared'import svSE_forms from '@dnb/eufemia/extensions/forms/constants/locales/sv-SE'import svSE_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/sv-SE'import daDK_forms from '@dnb/eufemia/extensions/forms/constants/locales/da-DK'import daDK_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/da-DK'const translations = mergeTranslations(svSE,svSE_forms,svSE_forms_countries, // if needed// etc. for other locales you want to add)
How to set the locale
In React based apps, use the shared Eufemia provider:
import Provider from '@dnb/eufemia/shared/Provider'const myLocale = 'en-GB'render(<Provider locale={myLocale}><MyApp>Eufemia components</MyApp></Provider>)
For component based locale, you can also make use of the lang attribute – if really needed:
import Provider from '@dnb/eufemia/shared/Provider'render(<Provider locale="en-GB"><MyApp><HelpButton lang="nb-NO" /></MyApp></Provider>)
How to set locale progressively
You can easily enhance or change translated strings progressively:
import Provider from '@dnb/eufemia/shared/Provider'render(<Providerlocale="nb-NO"translations={{'nb-NO': {Modal: { close_title: 'Something' },},}}><MyApp>Eufemia components</MyApp></Provider>)
How to change the locale during runtime
You can even change the locale during runtime. Find more info in the Provider docs.
import { Field } from '@dnb/eufemia/extensions/forms'import Provider from '@dnb/eufemia/shared/Provider'import Context from '@dnb/eufemia/shared/Context'const ChangeLocale = () => {const { setLocale, locale } = React.useContext(Context)return (<Field.Selection value={locale} onChange={(value) => setLocale(value)}><Field.Option value="nb-NO" title="Norsk" /><Field.Option value="en-NO" title="English (NO)" /><Field.Option value="sv-SE" title="Svenska" /><Field.Option value="da-DK" title="Dansk" /><Field.Option value="en-GB" title="English (GB)" /></Field.Selection>)}render(<Provider><MyApp><ChangeLocale /></MyApp></Provider>)
Provide your own translations
You can provide your own translations by using the shared Provider. Translation strings with several levels of depth can be given as a flat object with dot-notation, or as a nested object (cascaded).
import Provider from '@dnb/eufemia/shared/Provider'const nbNO = { myString: 'Min egendefinerte streng' }const enGB = {// Cascaded translationsNested: {stringWithArgs: 'My custom string with an argument: {myKey}',},// Flat translations'Nested.stringWithArgs': 'My custom string with an argument: {myKey}',}const myTranslations = {'nb-NO': nbNO,'en-GB': enGB,}render(<Provider translations={myTranslations} locale="en-GB"><MyApp><MyComponent /></MyApp></Provider>)
Consume translations in your components
You can use the useTranslation hook to get the strings from the shared context. The hook returns an object with the strings and a formatMessage function you can use to get the translated strings with arguments.
import { useTranslation } from '@dnb/eufemia/shared'const myTranslations = {'nb-NO': { myString: 'Min egendefinerte streng' },'en-GB': {// Cascaded translationsNested: {stringWithArgs: 'My custom string with an argument: {myKey}',},// Flat translations'Nested.stringWithLinebreaks':'My custom string with a {br}line-break',},}type Translation = (typeof myTranslations)[keyof typeof myTranslations]const MyComponent = () => {const t = useTranslation<Translation>()// Internal translationsconst existingString = t.Dropdown.title// Your translationsconst myString = t.myString// Use the "formatMessage" function to handle strings with argumentsconst myStringWithArgsA = t.formatMessage(t.Nested.stringWithArgs, {myKey: 'myValue',})// You can also get the string with a key (dot-notation)const myStringWithArgsB = t.formatMessage('Nested.stringWithArgs', {myKey: 'myValue',})// Render line-breaksconst jsxOutput = t.renderMessage(t.Nested.stringWithLinebreaks)return <>MyComponent</>}render(<Provider translations={myTranslations} locale="en-GB"><MyApp><MyComponent /></MyApp></Provider>)
Good to know: You can consume the strings with a dot-notated key, directly from
the formatMessage function:
formatMessage('myGroup.subString')
Formatted messages
For richer inline formatting in your translated strings, you can use the renderWithFormatting helper from @dnb/eufemia/shared. It supports simple markup tokens inside your messages:
{br}inserts a line break (<br />).**bold**wraps content in<strong>by default._italic_wraps content in<em>by default.[label](url)renders an anchor link.- Bare URLs (e.g.
http://…orhttps://…) are automatically linked and use the URL as the label.
- Bare URLs (e.g.
- Backticks render monospace literals. Useful for short, copy‑critical strings like reference IDs, promo codes etc. Example:
`AB12-XYZ9`. You can customize the renderer viarenderWithFormatting(text, { code: (c) => <span className="dnb-code">{c}</span> })if you prefer monospace styling without the semantic<code>tag.
You can also customize the wrappers and the break token.
import {useTranslation,renderWithFormatting,Provider,} from '@dnb/eufemia/shared'const translations = {'en-GB': {'myGroup.subString':'Use **bold** and _italic_ with a {br}line-break.',},}type T = (typeof translations)['en-GB']function MyComponent() {const t = useTranslation<T>()return <>{renderWithFormatting(t.myGroup.subString)}</>}function MyApp() {return (<Provider translations={translations} locale="en-GB"><MyComponent /></Provider>)}
Use without translations
You can also use renderWithFormatting directly, without the translation context. This is handy for static copy or small strings you build at runtime.
import { renderWithFormatting } from '@dnb/eufemia/shared'const text ='Use **bold**, _italic_, `AB12-XYZ9` and a link https://www.dnb.no{br}Next line'export function InlineFormattingExample() {return <>{renderWithFormatting(text)}</>}
Array input and dynamic strings are also supported:
import { renderWithFormatting } from '@dnb/eufemia/shared'function ArrayInputExample() {const parts = ['Hello', '{br}', 'world! See https://example.com']return <>{renderWithFormatting(parts)}</>}function DynamicExample({ refId }: { refId: string }) {const text = `Keep your reference \`${'${refId}'}\` for support.`return <>{renderWithFormatting(text)}</>}
Fallback for missing or partial translations
The shared useTranslation hook will output missing keys when:
- Empty explicit locale: returns pointer strings (e.g.
MyNamespace.label) derived fromfallbackLocale="nb-NO". - Partial explicit locale: merges missing keys as pointer strings, preserving existing ones.
- Non-existent current locale (no explicit entry in your translations): the hook preserves defaults (no pointers).
import { useTranslation, Provider } from '@dnb/eufemia/shared'const translations = {'sv-SE': {}, // empty explicit current-locale'en-GB': { MyNamespace: { label: 'English label' } },}type T = (typeof translations)['en-GB']function Example() {const t = useTranslation<T>({fallbackLocale: 'en-GB', // default: 'nb-NO'})return <>{t.MyNamespace.label /* 'MyNamespace.label' */}</>}render(<Provider locale="sv-SE" translations={translations}><Example /></Provider>)
TypeScript support
import Provider, { Locales } from '@dnb/eufemia/shared/Provider'const nbNO = {myString: 'Min egendefinerte streng',}const enGB = {myString: 'My custom string',} satisfies typeof nbNO // Ensure the types are compatibleconst myTranslations = {'nb-NO': nbNO,'en-GB': enGB,}// Infer the type of the translationstype Translation = (typeof myTranslations)[keyof typeof myTranslations]
How to combine with other tools
You can easily combine the locales support it with other translation tools, like react-intl.
Like, having the Eufemia components strings inside a JSON object/file en.json:
{"Modal.close_title": "Overwrite","other.string": "{foo} ({bar} of {max})"}
and use it like this:
import EufemiaProvider from '@dnb/eufemia/shared/Provider'import nb from './nb.json' // Has to be an JavaScript objectrender(<EufemiaProviderlocale="nb-NO"translations={{'nb-NO': nb,}}><MyApp>Eufemia components</MyApp></EufemiaProvider>)
Cascaded object (flat object, dot-notated keys) support
- Lets say you have your translation files as JSON object/files
en.json:
{"Modal.close_title": "Overwrite","my.string": "string {foo}"}
- and use it with a React hook like this:
import {useTranslation,Provider as EufemiaProvider,} from '@dnb/eufemia/shared'import nb from './nb.json'import en from './en.json'const MyComponent = () => {// Note: no TypeScript support when using an identifier.const str = useTranslation('my.string', {foo: 'bar',})return str}render(<EufemiaProviderlocale="nb-NO"translations={{'nb-NO': nb,'en-GB': en,}}><MyComponent /></EufemiaProvider>)
- or as a React component:
import {Translation,Provider as EufemiaProvider,} from '@dnb/eufemia/shared'import nb from './nb.json'import en from './en.json'render(<EufemiaProviderlocale="nb-NO"translations={{'nb-NO': nb,'en-GB': en,}}><Translation id="my.string" foo="bar" /></EufemiaProvider>)
For TypeScript support, you can use the Translation component with a function. You may also want to make a wrapper, so you can use your own translation types:
import {Translation,TranslationProps,Provider as EufemiaProvider,} from '@dnb/eufemia/shared'const translations = {'nb-NO': { my: { string: 'streng {foo}' } },'en-GB': { my: { string: 'string {foo}' } },}type TranslationType = (typeof translations)[keyof typeof translations]render(<EufemiaProvider locale="nb-NO" translations={translations}><Translation<TranslationType> id={(t) => t.my.string} foo="bar" /></EufemiaProvider>)
Formatting markers inside <Translation />
When using <Translation />, simple inline formatting is applied automatically:
{br}→ line break**bold**,_italic_,`code`[label](https://…)links, and bare URLs become anchors
import {Translation,Provider as EufemiaProvider,} from '@dnb/eufemia/shared'const translations = {'en-GB': {info: 'Use **bold** and _italic_ with a {br}line-break.',},}type TranslationType = (typeof translations)[keyof typeof translations]render(<EufemiaProvider translations={translations} locale="en-GB"><p><Translation<TranslationType> id={(t) => t.info} /></p></EufemiaProvider>)
How to add Eufemia provided locales
Eufemia components
Eufemia provides component translations for the following locales:
To include e.g. sv-SE you can use the following code:
import { Provider } from '@dnb/eufemia/shared'import svSE from '@dnb/eufemia/shared/locales/sv-SE'render(<Provider translations={svSE} locale="sv-SE">Your app</Provider>)
To include e.g. da-DK you can use the following code:
import { Provider } from '@dnb/eufemia/shared'import daDK from '@dnb/eufemia/shared/locales/da-DK'render(<Provider translations={daDK} locale="da-DK">Your app</Provider>)
Eufemia Forms
Eufemia provides forms translations for the following locales:
Note: Only nb-NO and en-GB are included by default.
To support other locales such as sv-SE or da-DK, you need to import and merge the locale translations yourself.
Use mergeTranslations to combine the forms translations (and country translations when needed) before you pass them to Form.Handler or Provider.
import { mergeTranslations } from '@dnb/eufemia/shared'import svSE_forms from '@dnb/eufemia/extensions/forms/constants/locales/sv-SE'import svSE_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/sv-SE'import daDK_forms from '@dnb/eufemia/extensions/forms/constants/locales/da-DK'import daDK_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/da-DK'const translations = mergeTranslations(svSE_forms,svSE_forms_countries, // if neededdaDK_forms, // if neededdaDK_forms_countries // if needed)
You can provide the merged translations for fields and values in a few different ways.
Form.Handler
You can provide forms translations to the translations property within the Form.Handler component like this:
import { Form } from '@dnb/eufemia/src/extensions/forms'import { mergeTranslations } from '@dnb/eufemia/shared'import svSE_forms from '@dnb/eufemia/extensions/forms/constants/locales/sv-SE'import svSE_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/sv-SE'const translations = mergeTranslations(svSE_forms, svSE_forms_countries)render(<Form.Handler translations={translations} locale="sv-SE">Your form</Form.Handler>)
Global translations
However, instead of providing the forms translations per form, you can also provide them globally using the Provider component:
import { Provider, mergeTranslations } from '@dnb/eufemia/shared'import svSE from '@dnb/eufemia/shared/locales/sv-SE'import svSE_forms from '@dnb/eufemia/extensions/forms/constants/locales/sv-SE'import svSE_forms_countries from '@dnb/eufemia/extensions/forms/constants/locales/countries/sv-SE'const translations = mergeTranslations(svSE,svSE_forms,svSE_forms_countries)render(<Provider translations={translations} locale="sv-SE">Your app, including Eufemia Forms</Provider>)
How to add new locales
Create a new file (nn-NO.js) containing all the strings:
export default {'nn-NO': {GlobalError: {404: {title: 'Me finn ikkje sida du leitar etter …',},},},}
And add the file, like so:
import Provider from '@dnb/eufemia/shared/Provider'import myTranslations from './locales/nn-NO'render(<Provider translations={myTranslations}><MyApp>Eufemia components</MyApp></Provider>)
Add or update the locales during runtime
import Provider from '@dnb/eufemia/shared/Provider'import Context from '@dnb/eufemia/shared/Context'import myTranslations from './locales/nn-NO'const ChangeLocale = () => {const { update, locale } = React.useContext(Context)// Add new localesupdate({ locales: myTranslations, locale: 'nn-NO' })return locale}render(<Provider><MyApp>...<ChangeLocale />...</MyApp></Provider>)