In this tutorial we are going to create a blog with multi-language support using Next.js. The blog will be in English and Spanish extendable to as many languages as you wish.
Let’s start by opening the terminal and creating a basic Next.js app with create-next-app. Replace travel-blog with the name of your blog.
npx create-next-app@latest travel-blog
Change directory to get inside the blog’s folder.
cd travel-blog
Start Next.js development server:
npm run dev
Open your browser and visit http://localhost:3000 to see a basic Next.js website. We are going to enable localization in Next.js. Open /travel-blog/next.config.js in your editor and this code and save the file:
module.exports = { reactStrictMode: true, i18n: { locales: ['en', 'es'], defaultLocale: 'en', }, }
Stop and start again the Next.js dev server for this change to take effect:
npm run dev
Next.js is now supporting urls with locales made of 2 letters language codes like: http://localhost:3000/es and http://localhost:3000/en.
Next we are going to add some content to the home page. We will need some articles to show in the blog. Let’s install Polyblog to get some mockup articles fast:
npm install @polyblog/polyblog-js-client
Paste this code in nextjs-blog-example/pages/index.js and save:
import Link from 'next/link' import { getArticles } from '@polyblog/polyblog-js-client' export async function getStaticProps({locale}) { // signup at https://app.polyblog.io/signup to get your blogId const articles = await getArticles({ blogId: 'YOUR_BLOG_ID', locale, published: true, sortDirection: 'DESC', }) return { props: { articles } } } export default function Blog({articles}) { return ( <div> <h1>Blog</h1> {articles?.map(article => ( <Link key={article._id} href={article.slug}> <a> <h4>{article.title}</h4> </a> </Link> ))} </div> ) }
Signup at https://app.polyblog.io/signup to get your blogId to enter in the code above. After signing up visit the page Settings to find the id of your blog (ex. 1234567890abcdef12345678) You can now visit http://localhost:3000/en to see articles in English. You can visit http://localhost:3000/es to see the same articles in Spanish.
Wow. That was FAST.
Mark Zuckerberg advised us to “move fast and break things”. We are missing the break things part though. Throw something on the ground and jump on it euphorically! He didn’t mean like that? Okay okay, if you don’t want to trash the room let’s get back to the blog.
In the code above you can see a function getStaticProps which is a special function that Next.js uses for data fetching and other awesome goodies like pre-rendering.
Create a file travel-blog/pages/[slug].js and paste this:
import { getArticles } from '@polyblog/polyblog-js-client' export async function getStaticPaths({locales}) { let articles = await getArticles({ blogId: 'YOUR_BLOG_ID', published: true, }) articles = articles.filter(({locale}) => locales.includes(locale)) const paths = articles.map((article) => ({ locale: article.locale, params: { slug: article.slug }, })) return { paths, fallback: 'blocking' } } export async function getStaticProps({locale, params}) { const { slug } = params const articles = await getArticles({ blogId: 'YOUR_BLOG_ID', locale, slug, }) return { props: { article: articles[0], } } } export default function Article({article}) { return ( <div> {article && ( <div> <h1>{article.title}</h1> <div>{article.description}</div> <div dangerouslySetInnerHTML={{ __html: article.content }} /> </div> )} </div> ) }
You can click on one of the articles on the home page and it should lead you to the article page. There is a lot of magic here. So much magic, we are summoning a blog out of thin air. Let’s try to understand what’s going on. To start that funny looking file name [slug].js looks suspicious. It’s not a bug, it’s a feature and Next.js calls it Dynamic Routes. [slug].js is a wild-card parameter that will pass a portion of the url to our page component. You can see in the code above the function getStaticProps is receiving a params which contains a field named slug. There is another special Next.js function called getStaticPaths which is used to fetch all the articles of the entire blog in all languages to statically generate html pages and serve them super fast over a CDN.