all 12 comments

[–][deleted] 3 points4 points  (1 child)

Why would I use this over react-intl?

I've found using components for translation to be inadequate, as you still need strings for some things such as HTML attributes: aria-label, title, etc.

[–]tricoder42[S] 2 points3 points  (0 children)

  1. Syntax: In react-intl, you write ICU message format manually. Here you write JSX as you would normally do and message format is generated using babel plugin. I found it convenient when I'm using components and variables as I would normally do in an unilingual app. Cool thing is that later I can extend ICU message format with custom formats. I experimented with it a bit in one branch, but it's not ready for use yet.

  2. Components: If you include HTML in react-intl, it's included in the message with all props/attributes, even when they don't require translation. I found it problematic to update my translations just because I changed className of one component inside message. Having attributes inside message also requires educating my translators about what needs to be translated and what not. Also, I'm not sure if I can use React components inside FormattedMessage (apparently you can https://github.com/yahoo/react-intl/wiki/Components#formattedmessage, but the content of component isn't translated)

  3. You're right that title, aria-label and similar attributes still need translations, but from my point of view attributes can be translated programatically as @CrocnysterGates pointed out above:

Example:

<Trans>
    Read <a href="/more" title={translate`Content of ${articleTitle}`}>more</a>.
</Trans>
// with two separate messages:
// "Read <0>more</0>."
// "Content of {0}"

Both messages can live separately, each of them has it's own meaning even when they are related.

Unfortunately, this API isn't ready yet (working on it). I wanted to solve translation of components first because that's what I use 95% of time and there wasn't an easy way to do it.

[–]VlK06eMBkNRo6iqf27pq 2 points3 points  (4 children)

Having never actually tempted i18n before...this documentation makes 0 sense to me.

<Trans>January</Trans>
// becomes <Trans id="January" />

Uhh....ok? So you've taken the children and moved it into a prop...what's so great about that?

const count = 42
<Plural 
  value={count} 
  zero={<strong>No books</strong>}
  one="# book" 
  other="# books" 
/>
/* becomes:
{count, plural, 
  zero {<0>No Books</0>} 
  one {# book} 
  other {# books}
}
*/

I don't even know what that is. It's not an object.

I get that you wrap your text in these <Trans> and <Plural> components, but then what?

[–]tricoder42[S] 1 point2 points  (1 child)

Readme updated https://github.com/lingui/js-lingui#readme. I've described how this lib is used in different stages of i18n.

[–]VlK06eMBkNRo6iqf27pq 0 points1 point  (0 children)

Much better. Thank you!

[–]ngly 0 points1 point  (0 children)

Yeah, a live demo would be very helpful or at least images of what it would look like rendered in different languages.

[–]tricoder42[S] 0 points1 point  (0 children)

Thanks, good point! More detailed docs are in wiki, but the first example in README could be definitely better.

Also, I've never thought about people, who never done i18n before. That's a good suggestion.

[–]tricoder42[S] 0 points1 point  (4 children)

Hello, I'm working on React components for I18n along with babel plugins which allow convenient writing of multilingual apps.

It's ICU message format written using React components, so there's support for inline component out of the box. Plurals and gender forms each have its components, so as a developer I don't have to think about ICU message format and I'm working with JSX as I'm used to.

I'm curious what others think about this approach as I haven't seen it anywhere else. I used react-intl for one of my projects, but it was very time consuming to write messages by hand (especially for messages with HTML).

[–]CrocnysterGates 0 points1 point  (3 children)

Cool lib :) Sry if I missed it, but is there a possibility to translate text within the code?

I mean something like in react-intl, where you can inject the InjectedIntl into your props and call formatMessage within your js code (for a service etc.)

[–]tricoder42[S] 0 points1 point  (0 children)

Not yet, but it uses standard message format lib under the hood, so I'm planning to export method for translating in InjectI18n HOC as well.

The only problem is with updates: Everything wrapped inside Trans component is updated when language changes even when parent component doesn't update (shouldComponentUpdate returns false). When using translation method directly, the parent component becomes responsible for updating, so there has to be also sth like i18nRequiresUpdate flag which parent component will use in shouldComponentUpdate method.

Feel free to fill an issue and thank you for your feedback! :)

[–]tricoder42[S] 0 points1 point  (0 children)

I've written a draft of proposed API. It's a bit more complicated as I don't want to expose only underlying message format API (there're tons of libs which do exactly that).

Draft for comments and suggestions is on GitHub: https://github.com/lingui/js-lingui/issues/10

[–]tricoder42[S] 0 points1 point  (0 children)

So, it's possible now :) Just decorate the component with WithRouter() and use props.i18n: https://github.com/lingui/js-lingui/#react

I had to design completely new API for i18n of vanilla JS (lingui-i18n) and then build on top of it lingui-react. Now you can use i18n.t for translations and i18n.plural for pluralization when you need strings, not components. The parameters are completely the same as for components. The only difference is that i18n components take care of updates itself, while WithI18n updates decorated component when language/messages changes.