UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

336 lines (268 loc) 8.1 kB
--- 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 --- # Form.useTranslation ## Import ```tsx 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. ```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> ) ``` ## 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. ```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> ) ``` ## Custom translations 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> ) ``` ## Using the `<Translation />` 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> ) ``` ### 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://…` ```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> ) ``` ## Use the shared Provider to customize translations ```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> ) ``` ## 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). ```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> ) ``` ### 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](/uilib/usage/customisation/localization/#formatted-messages). ```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> ) } ``` ## Demos ### Custom translations example ```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 />) ``` ### Get translations with a key ```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 />) ```