Add attribute to i18n strings in React Native
Asked Answered
D

3

6

I've already known how to generate i18n string through react-native-i18n. For example,

// en.js  source
{
  "hello": "Hello, {{name}}."
}

// use
I18n.t("hello", { name: "John" }) 

and it shows Hello, John..

I've also known how to generate attributed string:

<Text>
  This is a <Text style={{fontWeight: 'bold'}}>bold<Text> word.
<Text>

and it shows This is aboldword.

The problem is, how can I add attributes to a i18n template string? Any library for this?

// en.js  source
{
  "hello": "Hello, <b>{{guest}}</b>. I'm {{host}}."
}

// use
I18n.t("hello", { guest: "John", host: "Sam" }) 
  • Expected: Hello,John. I'm Sam.
  • What I got: Hello, <b>John</b>. I'm Sam.
Depose answered 20/6, 2017 at 9:23 Comment(0)
S
2

You can do something like that

const splitTitle = (title, style) => {
    const [left, center, right] = title.split(/<b>|<\/b>/)

    return (
        <Text style={style}>
            {left}
            <Text style={{ fontFamily: 'font-name', fontWeight: 'font-weight' }}>{center}</Text>
            {right}
        </Text>
    )
}

And call it

splitTitle(i18n.t("key"), style)
Steels answered 27/8, 2021 at 22:16 Comment(0)
C
0

You can use react-i18next it supports react content inside its translation component:

<Trans i18nKey="userMessagesUnread" count={count}>
    Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>

In the dictionary,

"userMessagesUnread": "Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>.",
"userMessagesUnread_plural": "Hello <1>{{name}}</1>, you have {{count}} unread messages.  <5>Go to messages</5>.",

Learn more https://react.i18next.com/latest/trans-component#using-with-react-components

Canberra answered 3/7, 2017 at 20:9 Comment(4)
Am I missing something here? Doesn't this solution make it so that you have hard coded English translations in your component?Hartmunn
Such a confused componentInculpate
The question is for React NativeHoang
This doesn't work in react native.Astute
O
0

This is my manual solution that works in React-Native with I18next.

1. Store this function somewhere in your code.

export function withBoldStyle(phrase, boldPart) {
  //get index of bold part in phrase
  const startIndex = phrase.indexOf(boldPart);
  const endIndex = startIndex + boldPart.length;

  //split the long sentence into parts
  const preBold = phrase.slice(0, startIndex);
  const bold = phrase.slice(startIndex, endIndex);
  const postBold = phrase.slice(endIndex);

  //give the bold part to a bold Text component
  return [
    preBold,
    <Text style={{fontWeight: 'bold'}}>{bold}</Text>,
    postBold,
  ].filter(part => part !== '');
}

2. Use it like below:

//get your translation like the way you already do
const translation = I18n.t('hello', {guest: params.guest}); 

//in your render method, give the translation and guest name to the styling function
...
  <Text style={styles.passHint}>{withBoldStyle(translation, params.guest)}</Text>
...

note: this function is limited to receive 1 substring as bold part. I will try to improve it so it can handle array of bold parts.

Orville answered 24/9 at 19:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.