Search code examples
htmlwebpackinternationalizationhtml-webpack-pluginmulti-page-application

What is the proper way to i18n multipage site, build with webpack?


The task

To build several static pages for several languages using the same parts. Keep the project as simple and minimal as it's possible.

Stack

Webpack with html-loader, HtmlWebpackPlugin, and I18nPlugin. Nothing fancy. Everything is in latest versions for today.

Current solution

webpack.config.js:

const entryHtmlPlugins = (language) => pageList
    .map(function (entryName) {
        const langPart = language === defaultLanguage ? '' : `${language}.`;

        return new HtmlWebpackPlugin({
            filename: `../dist/${langPart}${entryName}`,
            template: `prerender/${entryName}`,
            language,
        });
    });

module.exports = Object.keys(languages).map((language) => ({
    ...
    module: {
        rules: [{
            test: /\.(html)$/,
                include: path.join(__dirname, 'src/pages'),
                use: {
                     loader: 'html-loader',
                     options: {
                         interpolate: true
                     }
                }
         },
    ...]
    },
    plugins: [
        ...
        new I18nPlugin(languages[language]),
    ].concat(entryHtmlPlugins(language))
}))

index.html

<!-- regular html with translations in format: -->
<%= __('Test') %>

Problem

In templates, imported with

<%= require('html-loader!./partial.html') %>

or

${require('!html-loader!./partial.html')}

translations aren't working.

Solutions?

Processing of the HTML pages with the plugin from temp folder (so every page is built once for including partials and once more for translation) is working but cause infinite rerendering. And doesn't feel right.
The task looks so simple and I hardly believe there is no other way than to use a template engine. I wonder if this is the right thought direction to make a custom plugin? If the current stack is too modest for my purpose, could you please suggest any other options.

Question

So are there a more or less elegant way to use partials and i18n at the same time or I have to use pug (or something) for templating?


Solution

  • I have actually found an answer in Webpack: include html partial inside another partial?

    All you need to translate the part that you including is to interpolate it, so instead of

    <%= require('html-loader!./partial.html') %>
    

    we doing

    <%= require('html-loader?interpolate./partial.html') %>
    

    This is not so pretty if you including a lot of parts and parts inside part's parts but it works (at least for now) and does not require any additional template engines.