Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapping interpolated values in tags #93

Open
james-brndwgn opened this issue Sep 26, 2017 · 9 comments
Open

Wrapping interpolated values in tags #93

james-brndwgn opened this issue Sep 26, 2017 · 9 comments

Comments

@james-brndwgn
Copy link

What is the recommended method to wrap an interpolated value in tags. For example, if I have

polyglot.extend({
  "hello_name": "Hola, %{name}. How are you?"
});

polyglot.t("hello_name", {name: "DeNiro"});
=> "Hola, DeNiro. How are you?"

and would like to bold the name (wrap it in <strong> tags). Is there a recommended way to do this?

@ljharb
Copy link
Collaborator

ljharb commented Sep 26, 2017

This is how Airbnb tends to do it:

polyglot.extend({
  hello_name: 'Hola, ${name_start}${name}${name_end}. How are you?',
});

polyglot.t('hello_name', { name: 'DeNiro', name_start: '<strong>', name_end: '</strong>' });

@ljharb
Copy link
Collaborator

ljharb commented Mar 4, 2018

@dcworldwide it works, but then it produces HTML, which has to be unsafely added to the DOM.

@james-brndwgn
Copy link
Author

Yep. As @ljharb says. It works, but far from ideal. Mixing html with translations would not be a good situation. It's simple enough to drop <strong> tags in. I kept my example simple for the sake of simplicity. However should you need to wrap a link then you'll really end up mixing html with your translations. In the end I ended up writing a little wrapWithTag utility function

export function wrapWithTag (tag, string, attrs = '') {
  if ((tag && typeof tag === 'string') && (string && typeof string === 'string')) {
    return `<${ tag } ${ attrs }>${ string }</${ tag }>`;
  }
}

@ryanacorn
Copy link

ryanacorn commented Feb 19, 2021

This is how Airbnb tends to do it:

polyglot.extend({
  hello_name: 'Hola, ${name_start}${name}${name_end}. How are you?',
});

polyglot.t('hello_name', { name: 'DeNiro', name_start: '<strong>', name_end: '</strong>' });

This doesn't seem to work. I'm getting the literal string tags displayed. (Is it because I'm using it in React?)

@ljharb
Copy link
Collaborator

ljharb commented Feb 19, 2021

Yes. In react, you’d have to use dangerouslySetInnerHTML to make that work.

@spikebrehm
Copy link
Collaborator

At Airbnb, we had a <T> component with an API like:

polyglot.extend({
  hello_name: 'Hola, ${tag_start}${name}${tag_end}. How are you?',
});
<T
  k="hello_name"
  name="DeNiro"
  tag={<strong />
/>

That essentially sliced up the string into an array of React.ReactNode for rendering.

@ljharb
Copy link
Collaborator

ljharb commented Feb 19, 2021

Sadly i haven’t had time to recreate that yet as an open source component.

@Xiphe
Copy link
Contributor

Xiphe commented Jul 5, 2022

Answering the original question:

I advocate keeping markup out of the translation files since these might be generated or created by people or tools that do not know html well.

Therefore I'd recommend using polyglot.t("hello_name", {name: `<strong>DeNiro</strong>` });.

--

With the react discussion since #170 you could also provide a custom replace implementation (see example: https://codesandbox.io/s/admiring-framework-lb367l?file=/src/App.js) to return valid react fragments from polyglot.

@Xiphe
Copy link
Contributor

Xiphe commented Jan 24, 2023

So the newly released v2.5.0 now supports customizing the replace implementation like i've mentioned above.

With that you can create a replace that is able to handle cases like polyglot.t("hello", { name: <h1>Hello</h1> }).

See https://codesandbox.io/s/admiring-framework-lb367l?file=/src/App.js:1209-1257 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants