Implementing Internationalization (i18n) com Module Federation em React Micro-Frontends
Check out o exemplo projeto list here: React i18n
Visão geral
No realm de micro-frontends, ensuring each aplicação remains as autonomous as possible é crucial. However, scenarios arise onde inter-aplicação communication é inevitable. Uma comum requirement é synchronizing language preferences across micro-frontends, such as quando uma user changes o language setting em one aplicação, e it cascades across all integrated micro-frontends. Este documentação outlines uma estratégia for implementing internationalization usando o react-i18next library within uma micro-frontend architecture facilitated by Module Federation.
Scenario
Consider two aplicações: App A (o container aplicação) e App B (a aplicação remote). While App B funções independently as uma standalone aplicação, it é também designed para ser embedded within App A em runtime. Our objective é para seamlessly synchronize language settings entre App A e App B, ensuring both aplicações pode manage e display their localized content.
Architecture e Implementation
Extending Bundler Configuração
To accommodate micro-frontend integração, nós extend o existente Webpack/Rspack/Rsbuild e Create React App (CRA) configurações usando o Module Federation plugin. Este extension allows App B para exponha various elements (e.g., componentes, themes, hooks) for consumption by App A ou any other integrated aplicações sem requiring codebase ejection.
Setting Up Internationalization
O react-i18next implementation forms o backbone de our translation functionality. Initially, um instance de i18next é configured e imported diretamente no principal aplicação arquivo (App.js). Este instance leverages uma context store para manage estado, recursos (translations), e plugins.
Addressing Translation Override Challenges
Uma direct implementation approach onde each aplicação initializes its i18next instance could lead para recurso conflicts, particularly onde translated terms são overridden. To avoid este, nós establish separate i18next instances for App A e App B, ensuring each aplicação maintains its translation terms independently.
Implementation Steps
Configuring i18next Instances
For both App A e App B, configure separate i18next instances as follows:
Integrating i18next Providers
Wrap a aplicação componentes em I18nextProvider, passing o respective i18next instances para garantir translation contexts são correctly applied.
Language Switching Logic
For App B, write uma custom hook para facilitate language switching, por exemplo:
Exponha este hook via Module Federation para allow its consumption by App A ou other integrated aplicações.
In App A, implement uma hook esse orchestrates language switching across all integrated micro-frontends:
Language Switching Interface
Implement uma user interface componente, such as uma button, para trigger language changes across all aplicações:
Handling Integrated Environments
To conditionally display language switcher componentes (e.g., hide o switcher em App B quando embedded em App A), leverage uma custom hook like useIsRemote.
O useIsRemote hook é designed para determine se o current aplicação (e.g., App B) é running em uma standalone mode ou é embedded within another aplicação (e.g., App A). Este distinction allows us para conditionally render componentes based no aplicação's context.
Below nós fornecido um exemplo de uma simplified implementation do useIsRemote hook esse checks para uma specific condition para determine a aplicação's environment. No real aplicação este condition could ser baseado em URL parameters, DOM presence checks, ou any other trigger esse differentiates entre being embedded e running standalone:
Usando o useIsRemote Hook
Com o useIsRemote hook implemented, você pode now use it within your componentes para conditionally render elements baseado em whether a aplicação é running standalone ou é embedded. Here's um exemplo de como it might ser usado para conditionally display uma language switcher componente em App B:
In este exemplo, LanguageSwitcher vai apenas render quando App B é não embedded within App A, based no isRemote estado determined pelo useIsRemote hook. Este approach ensures esse componentes like language switchers são apenas shown em appropriate contexts, enhancing o user experience e maintaining o independence de micro-frontend aplicações.