Content Splitting

Content splitting

Learn how to use tags to segment string content and optimize bundle size of downloaded translations over the air.

Content segmentation is useful when you have a large Native resource but various parts of the app are not using the whole content. For example imagine a React website that is using 5K strings, but a specific part of the website is only using 600 strings. Wouldn't be awesome if you could only fetch the 600 strings instead of the whole 5K bundle? This is where splitting content using tags comes into play.

Content can be tagged either directly into the code, for example:

import React, { Component } from 'react';

import { T } from '@transifex/react';

class Example extends Component {
  render() {
    const user = 'Joe';
    return (
      <div>
        <T _str="Hello world" _tags="homepage" />
        <T _str="Hello {username}" username={user} _tags="homepage" />
      </div>
    );
  }
}
$ txjs-cli push src/

or by using the --append-tags parameter in the @transifex/cli, for example:

$ txjs-cli push src/home/ --append-tags="homepage"
$ txjs-cli push src/signin/ --append-tags="signin"
$ txjs-cli push src/subscription/ --append-tags="subscription"

When content is pushed via the cli, tags are always appended to existing string's tags on Transifex. Deleting tags is currently only supported via the Transifex Editor.

In the code we can select which content we would like to fetch over the air by passing the appropriate tags in the tx.init function.

tx.init({
  token: 'project_token',
  filterTags: 'homepage',
});

Passing multiple comma separated tags in the filterTags parameter is supported. However, multiple tags will retrieve strings from Transifex when all tags are present in a string. Example:

tx.init({
  token: 'project_token',
  filterTags: 'foo,bar',
});

"Hello" [foo] -> Will not fetch
"Hello" [bar] -> Will not fetch
"Hello" [foo] [bar] -> Will fetch
"Hello" [foo] [bar] [other] -> Will fetch

Lazy loading

Transifex Native exposes some methods to support lazy loading of translations based on tags. For example, let's say that you have already initialized the SDK to fetch the homepage translations, tagged as follows:

tx.init({
  token: 'project_token',
  filterTags: 'home',
});

You can lazy load translations later in the application using the following method:

tx.fetchTranslations(tx.getCurrentLocale(), {
  filterTags: 'settings',
});

For React apps, this functionality is exposed using the useTranslationshook. For example:

tx.init({ token: ..., filterTags: 'home' });

export default function App() {
  return (
    <>
      <T _str="This will be translated as soon as possible" _tags="home" />
      {someCondition() && <Inner />}
    </>
  );
}

function Inner() {
  useTranslations('inner');
  return <T
    _str="This will be translated when the inner component is rendered"
    _tags="inner" />;
}

See more on React documentation.

Branches

Content splitting can also be used as a way to segment content across feature branches. A developer can push the strings of a feature branch by tagging content, wait for localization, test it and then deploy it to production. Example:

Pushing and tagging content from feature branch:

$ git checkout -b new-login-page
$ txjs-cli push src/ --append-tags="new-login-page"

Fetching content in a feature branch, while testing it on a staging server:

tx.init({
  token: 'project_token',
  filterTags: 'new-login-page',
});

Pushing and tagging content from the main branch after feature branch is merged:

$ git checkout main
$ txjs-cli push src/ --append-tags="main"

Fetching content in the main branch, while deployed to production:

tx.init({
  token: 'project_token',
  filterTags: 'main',
});