Skip to content

Latest commit

 

History

History
112 lines (87 loc) · 4.26 KB

i18n.md

File metadata and controls

112 lines (87 loc) · 4.26 KB
ignore_macros
true

Internationalization

ILC comes with built in internationalization support, so you can easily run micro frontends on the websites which require support of the multiple languages.

However, you need to keep in mind that ILC does only part of the job for you. Support of the i18n capabilities from the micro frontends side is required.

Routing

ILC uses 2-tier routing model. It means that:

  1. ILC itself handles only global routing (says which set of apps should be loaded at particular URL)
  2. Micro Frontend has own routing in place which determines component to be rendered.

1st tier - ILC

While having i18n feature enabled - ILC allows you to handle localized URLs at global level. Currently, we support two routing schemes:

  • Prefixing all routes with the locale except those of the default locale
  • Prefixing all routes with the locale

In Registry, you continue to specify all routes in Registry w/o locale information.

2nd tier - Micro Frontend

When dealing with internationalization - we obviously don't want to hardcode localized links in the source code of every micro frontend that we run with ILC. Instead, it's better to separate concerns.

Such approach allows to be flexible in the selection of the localization pattern for your URLs, and you can manage this behaviour from central place.

The other thing that we need to consider - is the fact that process & business logic of actual location.href un-localization before use in the app's router & localization of the URLs before rendering into the DOM should be synchronized across all applications and ILC itself.

To achieve that ILC provides IlcIntl class via App SDK that can be used at CSR & SSR.

Examples:

Synchronized language/currency change

When customer wants to change locale or currency on the website - it's often impossible to immediately render an updated content as loading of the localization files or updated prices is necessary.

If we would only emit locale/currency change event and allow every micro frontend to deal with it on its own - customer would likely see "blinking" of the UI as various parts of it will be re-rendered in different moments of time. To prevent this from happening - ILC uses prepare/execute pattern to synchronize re-rendering of all micro frontends.

Example:

class Root extends React.Component {
    constructor(props) {
        super(props);

        this.state = { links: [] };

        // This is a root React component, so it receives appSdk as property from ILC.
        const lang = this.props.appSdk.intl.get().locale;
        import(`./links/${lang}.json`).then(v => {
            this.setState({links: v.default});
        });
    }

    componentDidMount() {
        this.props.appSdk.intl.onChange(
            (e) => import(`./links/${e.locale}.json`), // Prepare all necessary data
            (e, langModule) => { // Perform language change
                this.setState({links: langModule.default});
            }
        );
    }

    changeLocale(locale, e) {
        e.preventDefault();

        this.props.appSdk.intl.set({ locale });
    }

    render() {
        return (
            <div className='navbar-app'>
               {
                   this.state.links.map((link) => {
                       return (
                           <NavLink key={link.href}
                                    to={this.props.appSdk.intl.localizeUrl(link.href)}>
                               {link.name}
                           </NavLink>
                       )
                   })
               }

               <div className='lang-selector'>
                   <NativeListener onClick={this.changeLocale.bind(this, 'en-US')}>
                       <a href="#" style={{color: 'white'}}>EN</a>
                   </NativeListener>
                   /
                   <NativeListener onClick={this.changeLocale.bind(this, 'ua-UA')}>
                       <a href="#" style={{color: 'white'}}>UA</a>
                   </NativeListener>
               </div>
           </div>
        );
    }
}