@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
336 lines (268 loc) • 8.1 kB
Markdown
---
title: 'Form.useTranslation'
description: '`Form.useTranslation` is a hook that returns the translations for the current locale.'
version: 10.104.0
generatedAt: 2026-04-17T18:46:12.399Z
checksum: 090b7d977ba4be5e2c4c04d199a30a4048416c59f443a56985df2f80629d9c40
---
```tsx
import { Form } from '@dnb/eufemia/extensions/forms'
// Use Form.useTranslation
```
The `Form.useTranslation` is a hook that returns the translations for the current locale.
```tsx
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>
)
```
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.
```tsx
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>
)
```
You can also extend the translations with your own custom translations.
```tsx
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>
)
```
Instead of using the hook, you can also, use the `<Translation />` component to consume your translations:
```tsx
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>
)
```
`<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://…`
```tsx
import { Form } from '@dnb/eufemia/extensions/forms'
import { Translation } from '@dnb/eufemia/shared'
const myTranslations = {
'en-GB': {
info: 'Use **bold** and _italic_ with a {br}line-break.',
},
}
type TranslationType = (typeof myTranslations)[keyof typeof myTranslations]
render(
<Form.Handler translations={myTranslations} locale="en-GB">
<Translation<TranslationType> id={(t) => t.info} />
</Form.Handler>
)
```
```tsx
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>
)
```
`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).
```tsx
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>
)
```
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](/uilib/usage/customisation/localization/
```tsx
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>
)
}
```
```tsx
const MyField = () => {
type Translation = {
Custom: {
translation: string
}
}
const { Custom, formatMessage } = Form.useTranslation<Translation>()
const myTranslation = formatMessage(Custom.translation, {
myKey: 'value!',
})
console.log('Custom', myTranslation)
return <>{myTranslation}</>
}
const MyForm = () => {
return (
<Form.Handler
locale="en-GB"
translations={{
'en-GB': {
Custom: {
translation: 'My translation with a {myKey}',
},
},
}}
>
<MyField />
</Form.Handler>
)
}
render(<MyForm />)
```
```tsx
const MyField = () => {
type Translation = {
Custom: {
translation: string
}
}
const { formatMessage } = Form.useTranslation<Translation>()
const myTranslation = formatMessage('Custom.translation', {
myKey: 'value!',
})
const errorRequired = formatMessage('Field.errorRequired')
console.log(errorRequired)
return <>{myTranslation}</>
}
const MyForm = () => {
return (
<Form.Handler
locale="en-GB"
translations={{
'en-GB': {
Custom: {
translation: 'My translation with a {myKey}',
},
},
}}
>
<MyField />
</Form.Handler>
)
}
render(<MyForm />)
```