martinandert / react-translate-component

A component for React that utilizes the Counterpart module to provide multi-lingual/localized text content.
MIT License
322 stars 31 forks source link

Question: Where to put translations? #30

Open andersravn opened 7 years ago

andersravn commented 7 years ago

Hey.

First of all, nice work. I like how simple your solution to this problem is.

I have created my app with create-react-app and I am using ES2015 features. Where would you propose to put the calls to registerTranslations if not in my index.js file. I would like to have separate files holding my translations, which are then loaded with the app. Also, I'm not too sure how to include these separate files?

Also, do you suggest to load all translations when the app is loaded? Could these become a heavy task with large amounts of text?

Thanks!

martinandert commented 7 years ago

Hi Anders, these are all valid questions. And I'm afraid I have to say for each one of them: it depends.

I'm currently evaluating an idea for the "where to put translations" question. I think it would be nice to keep them with the components (as is the common practice with styles and data fetching nowadays). Here is an example which shows how the PeopleList component from the example/ dir could then be written:

import React, { Component } from 'react';
import Translate, { withTranslations } from 'react-translate-component';
import './PeopleList.css';
import PersonName from './PersonName';

@withTranslations({
  en: {
    headline: 'Listing People',
    person_age_sentence: {
      zero:   '%(firstName)s is not even a year old.',
      one:    '%(firstName)s is one year old.',
      other:  '%(firstName)s is %(count)s years old.'
    },
  },
  de: {
    headline: 'Personenliste',
    person_age_sentence: {
      zero:   '%(firstName)s ist nicht mal ein Jahr alt.',
      one:    '%(firstName)s ist genau ein Jahr alt.',
      other:  '%(firstName)s ist %(count)s Jahre alt.'
    },
  },
})
class PeopleList extends Component {
  render() {
    return (
      <section className="PeopleList">
        <Translate component="h3" content="headline" />
        <ul>{this.renderItems(this.props.people)}</ul>
      </section>
    );
  }

  renderItems(people) {
    return people.map((person) => {
      var name = <PersonName name={person.name} />;

      return (
        <Translate
          component="li"
          className="person"
          content="person_age_sentence"
          with={{ firstName: name, count: person.age }}
          key={person.name}
        />
      );
    });
  }
}

export default PeopleList;

Since create-react-app doesn't support decorators atm, this could also be written as

class PeopleList extends Component {
  // same as above
}

export default withTranslations(PeopleList, {
  // translation data as shown above
});

WDYT?

andersravn commented 7 years ago

Keeping the translations in the component actually seems like a nice solution, if you don't have too much text. And it seems like the React way. My immediate concern is if you want to add a new language later on. You would have to go through each component and make the new translation, potentially missing some. This is where having each translation in a separate file would be nice. You could just open two files side-by-side and start translating.

For my project, I think the component based approach will work. Is there a benefit to doing it the way you outlined above, rather than:

componentWillMount() {
    Counterpart.registerTranslations('en', {
        example: {
            greeting: 'Welcome!',
            about: 'This is the about page!'
        }
    });
}

Also note that I'm pretty new to React and translation in applications. :)