Skip to content

useTranslation

Import

import { Form } from '@dnb/eufemia/extensions/forms'
// Use Form.useTranslation

Description

The Form.useTranslation is a hook that returns the translations for the current locale.

import { Form } from '@dnb/eufemia/extensions/forms'
function MyComponent() {
const { Field } = Form.useTranslation()
const { errorRequired } = Field
return <>MyComponent</>
}
render(
<Form.Handler locale="en-GB">
<MyComponent />
</Form.Handler>,
)

Additional utilities

In addition to all internal translations, you also get;

  • formatMessage - a function you can use to get a specific translation based on a key (flattened object with dot-notation).
  • renderMessage - a function you can use to render a string with line-breaks. It converts {br} to a JSX line-break.
import { Form } from '@dnb/eufemia/extensions/forms'
function MyComponent() {
const { formatMessage, renderMessage } = Form.useTranslation()
const errorRequired = formatMessage('Field.errorRequired')
return <>MyComponent</>
}
render(
<Form.Handler locale="en-GB">
<MyComponent />
</Form.Handler>,
)

Custom translations

You can also extend the translations with your own custom translations.

import { Form } from '@dnb/eufemia/extensions/forms'
const myTranslations = {
'nb-NO': { myString: 'Min egendefinerte streng' },
'en-GB': {
// Cascaded translations
Nested: {
stringWithArgs: 'My custom string with an argument: {myKey}',
},
// Flat translations
'Nested.stringWithLinebreaks':
'My custom string with a {br}line-break',
},
}
const MyComponent = () => {
const t = Form.useTranslation<typeof myTranslations>()
// Internal translations
const existingString = t.Field.errorRequired
// Your translations
const myString = t.myString
// Use the "formatMessage" function to handle strings with arguments
const 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-breaks
const jsxOutput = t.renderMessage(t.Nested.stringWithLinebreaks)
return <>MyComponent</>
}
render(
<Form.Handler translations={myTranslations}>
<MyComponent />
</Form.Handler>,
)

Using the <Translation />

Instead of using the hook, you can also, use the <Translation /> component to consume your translations:

import { Form } from '@dnb/eufemia/extensions/forms'
import { Translation, TranslationProps } from '@dnb/eufemia/shared'
const myTranslations = {
'nb-NO': { 'custom.string': 'Min egendefinerte streng' },
'en-GB': { 'custom.string': 'My custom string' },
}
type TranslationType = (typeof myTranslations)[keyof typeof myTranslations]
render(
<Form.Handler translations={myTranslations}>
<Form.MainHeading>
<Translation<TranslationType> id="custom.string" />
</Form.MainHeading>
<Form.SubHeading>
<Translation<TranslationType> id={(t) => t.custom.string} />
</Form.SubHeading>
</Form.Handler>,
)

Formatting markers inside <Translation />

<Translation /> automatically applies simple formatting markers in strings (using the shared renderWithFormatting):

  • {br} inserts a line break
  • **bold**, _italic_, `code`
  • links [label](https://…) and bare URLs https://…
import { Translation } from '@dnb/eufemia/shared'
const translations = {
'en-GB': {
info: 'Use **bold** and _italic_ with a {br}line-break.',
},
}
render(
<Form.Handler translations={translations} locale="en-GB">
<p>
<Translation id={(t: any) => t.info} />
</p>
</Form.Handler>,
)

Use the shared Provider to customize translations

import { Form, Field } from '@dnb/eufemia/extensions/forms'
import { Provider, Translation } from '@dnb/eufemia/shared'
const myTranslations = {
'nb-NO': {
'PhoneNumber.label': 'Egendefinert',
'custom.string': 'Min egendefinerte streng',
},
'en-GB': {
'PhoneNumber.label': 'Custom',
'custom.string': 'My custom string',
},
}
type TranslationType = (typeof myTranslations)[keyof typeof myTranslations]
render(
<Provider translations={myTranslations}>
<Heading>
<Translation<TranslationType> id={(t) => t.custom.string} />
</Heading>
<Form.Handler>
<Field.PhoneNumber />
</Form.Handler>
</Provider>,
)

Fallback for missing or partial translations

Form.useTranslation will output missing keys when:

  • Empty explicit locale: returns pointer strings (e.g. MyNamespace.label) derived from fallbackLocale="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 { Form } from '@dnb/eufemia/extensions/forms'
const translations = {
'sv-SE': {}, // empty explicit current-locale
'en-GB': { MyNamespace: { label: 'English label' } },
}
type T = (typeof translations)['en-GB']
function MyField() {
const t = Form.useTranslation<T>({
fallbackLocale: 'en-GB', // default: 'nb-NO'
})
return <>{t.MyNamespace.label /* 'MyNamespace.label' */}</>
}
render(
<Form.Handler locale="sv-SE" translations={translations}>
<MyField />
</Form.Handler>,
)

Formatted messages

For richer inline formatting inside form translations, use the renderWithFormatting helper from @dnb/eufemia/shared.

More info about the supported formatting in the renderWithFormatting documentation.

import { Form } from '@dnb/eufemia/extensions/forms'
import { renderWithFormatting } from '@dnb/eufemia/shared'
const translations = {
'en-GB': {
'Field.info': 'Fill out the **form** and _submit_ {br}when ready.',
},
}
type T = (typeof translations)['en-GB']
function MyComponent() {
const t = Form.useTranslation<T>()
return <>{renderWithFormatting(t.Field.info)}</>
}
function MyApp() {
return (
<Form.Handler translations={translations} locale="en-GB">
<MyComponent />
</Form.Handler>
)
}