How to manage Internationalization with NextJS SSG
Emmanuel Gautier / March 14, 2021
3 min read
Statically generating a website with the NextJS framework in different languages is not so obvious. The framework does not bring clear support for this use case and the NextJS documentation explains that i18n routing is not supported for SSG.
If you are seeing the message i18n support is not compatible with next export
, this post should be able to help find a workaround.
Bootstrap the project
First of all, let's create a new next project from the with-react-intl
template
npx create-next-app -e with-react-intl
If don't need anymore to manage any localization client side, you can remove the getInitialProps
function and the part for localization in the render
function.
The SSR server is useless if you only need SSG as well. So you can remove server tsconfig, server.ts
file and change your package.json
file script part as follow :
"scripts": {
"dev": "next dev",
"build": "npm run extract:i18n && npm run compile:i18n && next build",
"export": "next export",
"extract:i18n": "formatjs extract '{pages,components}/*.{js,ts,tsx}' --format simple --id-interpolation-pattern '[sha512:contenthash:base64:6]' --out-file lang/en.json",
"compile:i18n": "formatjs compile-folder --ast --format simple lang compiled-lang",
"start": "next start"
},
Static Site Generation (aka SSG) with NextJS
When you generate your website statically, it is not possible to use browser request header or any other information from the browser to know which language to use.
We need to introduce a new environment variable NEXT_PUBLIC_LOCALE
which will contain the locale of the website generated during the export process.
Example of content in .env.*
file
NEXT_PUBLIC_LOCALE=en
You can now use the NEXT_PUBLIC_LOCALE
variable in your _app.tsx
file in the getInitialProps
function to define the locale.
const getInitialProps: typeof App.getInitialProps = async (appContext) => {
const locale = appContext.router.locale || process.env.NEXT_PUBLIC_LOCALE
const [supportedLocale, messagePromise] = getMessages(locale)
const [, messages, appProps] = await Promise.all([
polyfill(supportedLocale),
messagePromise,
App.getInitialProps(appContext),
])
return {
...(appProps as any),
locale: supportedLocale,
messages: messages.default,
}
}
Thanks to this variable and the change done, react-intl
will now use as locale the content from the env variable. The translated messages taken are now from the right locale.
Now you have a website available for multiple languages. You can build your website for multiple domains as well dealing with multiple build processes, one for each locale. Feel free to implement it with the service you want like Netlify, Vercel, ... etc
The showcase generated for two languages deployed with Vercel :
If you want to know more, have a look into the Source Code
Consulting
If you're seeking solutions to a problem or need expert advice, I'm here to help! Don't hesitate to book a call with me for a consulting session. Let's discuss your situation and find the best solution together.
Related Posts
Formatting Big Numbers in JavaScript
When working with large numerical values in JavaScript, it can be challenging to display them in a way that's easy to read and understand. In this blog post, we'll explore techniques for formatting big numbers in JavaScript with built-in methods.
Changing Document Field Types with MongoDB
This article explains how to convert document field types during query execution and how to use MongoDB's built-in aggregation operators $convert. The article also provides practical examples and code snippets to demonstrate how to change field types in MongoDB.
Solve React error "Property autocomplete does not exist on type"
Sometimes, it happens that an easy-to-solve issue takes you more time than it should. The Typescript React error "Property autocomplete does not exist on type" is maybe one of them.
Featured Posts
How to deal with Docker Hub rate limit on AWS
Since 2020, DockerHub has been limited to only 200 container image pull requests per six hours. This article will help you to deal with this limitation on AWS.
How to enable Python type checking in VSCode
Python now has support for type hints. In this article, we will see how to enable better IntelliSense and type checking analysis in VSCode.
Install and configure a DNS server with Bind9 on Linux
A service DNS (Domain Name Service) allows domain name resolution to an IP Address and other resources. This service is useful for example for browsing internet websites and not have to know IPs addresses for these websites.