Skip to content

Allow components as placeholder replacements #51

Description

@timkraut

Hi,

we are using your library via react-redux-i18n in a project. It works fine, except for 1 use case: It is currently only possible to pass strings (with or without HTML) into placeholders. Passing components is not possible.

Example

Let's say I have the following translation key defined:

I18n.setTranslations({
  en: {
    placeholderString: 'lorem %{myReplacement} ipsum',
  },
})

✅ Replace with string (works fine):

<Translate
  value="placeholderString"
  myReplacement="hello world"
>

Result:

<span>lorem hello world ipsum</span>

✅ Replace with HTML (works fine):

<Translate
  value="placeholderString"
  dangerousHTML
  myReplacement="<a href='example.com'>hello world</a>"
>

Result:

<span>lorem <a href="example.com">hello world</a> ipsum</span>

⛔ Replace with component (doesn't work):

<Translate
  value="placeholderString"
  dangerousHTML
  myReplacement={<MyComponent />}
>

Custom component:

export const MyComponent = () => (
  <span className="my-component">hello world</span>
)

Expected result:

<span>lorem <MyComp /> ipsum</span>

Use case

We have dedicated components for certain types of links/buttons which we would like to use inside of a translated text, e.g.: 'some text <OpenModalButton /> more text'.
Other use cases I can think of include basically any dedicated "inline" component (if one does not want to rely on <strong>...</strong> or other native HTML tags).

Proposed algorithm

I've been looking through the source code and I think I would be able to create a PR which adds this functionality with roughly the following algorithm:

  1. Loop through every replacement passed to <Translate />and convert it into an object of the following structure: { value, isComponent: true|false}.
  2. If t() receives an array of objects, it ignores all objects where isComponent === true and translates everything else. If I18n.t(...) is used directly, nothing changes.
  3. <Translate /> loops through the remaining placeholders (which are all component placeholders) and inserts the corresponding components into the translated string.

What do you think? Would you be open for that?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions