Building a Multilingual Next.js Blog with Polylang
Author:
cmsgranit
Polylang is a popular WordPress plugin that allows users to create multilingual WordPress sites. With Polylang, you can easily create posts, pages, categories, and tags in different languages. In this tutorial, we will show you how to use Polylang to create multilingual WordPress posts. Before we begin, please note that we need Polylang Pro to share the same permalink for posts.
Step 1: Install and Activate Polylang Plugin
The first step is to install and activate the Polylang plugin on your WordPress site. You can do this by going to Plugins > Add New and searching for Polylang. Once you find the plugin, click the Install Now button and then Activate.
Step 2: Configure Polylang Settings
After activating the plugin, you need to configure the Polylang settings. Go to Settings > Languages in your WordPress dashboard. In the Languages settings, you can choose the default language of your site and add additional languages. To add a new language, click on the Add New Language button. In the Add New Language screen, you can select the language you want to add and configure the language settings.
Step 3: Create Multilingual Posts
Once you have configured the Polylang settings, you can start creating multilingual posts. To do this, go to Posts > Add New in your WordPress dashboard. In the post editor, you will see a new section called Language. This section allows you to select the language of your post. You can create a new post in a different language by selecting the language from the dropdown menu. After you have created the post, you can edit it in any language by selecting the language from the Language section.
Step 4: Add Language Code to REST API
By default, the WordPress REST API does not include the Polylang language code for each post. However, we can add the language code to the REST API response by adding some code to the functions.php file of our WordPress theme.
To include the Polylang language code for each post in the REST API /posts
response, we need to add a custom REST API field for it. Here’s an example:
Create a new function in functions.php
to register the custom REST API field:
function add_language_to_posts_rest_api() {
register_rest_field( 'post', 'language', array(
'get_callback' => function( $object ) {
$lang_code = pll_get_post_language( $object['id'] );
$lang = pll_get_language( $lang_code );
return $lang;
},
'schema' => array(
'type' => 'string',
'description' => 'The Polylang language code of the post',
'context' => array( 'view' ),
),
) );
}
add_action( 'rest_api_init', 'add_language_to_posts_rest_api'
JavaScriptSave the changes and reload the WordPress site.
Make a request to the /wp-json/wp/v2/posts
endpoint and check if the language
field is included in the response for each post. If it’s not, make sure the function is properly registered and the changes are saved.
Note: This assumes that Polylang is properly set up and the language of each post is defined using Polylang.
Step 5: Create Language Switcher Component in Next.js
To add the language switcher, we need to create a component in our Next.js application that allows users to toggle between the different languages. Here is an example of what that component might look like:
import Link from "next/link";
import { useRouter } from "next/router";
import { useState } from "react";
const LanguageSwitcher = () => {
const { locale, locales, asPath } = useRouter();
const [isOpen, setIsOpen] = useState(false);
const toggleMenu = () => {
setIsOpen(!isOpen);
};
return (
<div>
<button onClick={toggleMenu}>{locale}</button>
{isOpen && (
<div>
{locales.map((lng) => (
<Link href={asPath} locale={lng} key={lng}>
<animate>{lng}</animate>
</Link>
))}
</div>
)}
</div>
);
};
export default LanguageSwitcher;
JavaScriptThis component will display a button with the current language code and a dropdown menu with links to switch to the other languages. It uses the useRouter
hook from Next.js to access the current locale and the locales
array containing all the supported languages.
To use this component, we can add it to the Navigation component of our Next.js application. Here is an example of what that might look like:
import Link from "next/link";
import LanguageSwitcher from './LanguageSwitcher'
const Nav = () => {
return (
<div>
<nav>
<ul>
<li>
<Link href="/">
<a>Home</a>
</Link>
</li>
<li>
<Link href="/blog">
<a>Blog</a>
</Link>
</li>
</ul>
<LanguageSwitcher />
</nav>
</div>
);
};
export default Nav;
JavaScriptStep 6: Change next.config.js and install react-intl
We need to install the react-intl
the package which provides internationalization capabilities to React applications. We can do this by running the following command in our terminal:
npm install react-intl
TerminalFinally, we need to configure the i18n
property in our next.config.js
file to specify the available locales and their translations. We can do this by defining a locales
object that maps each locale to a corresponding messages
object that contains translations for that locale.
Here’s an example next.config.js
file:
const nextConfig = {
i18n: {
locales: ["sq", "en", "de"],
defaultLocale: "en",
localeDetection: false
},
};
module.exports = nextConfig;
JavaScriptStep 7: Creating a Page for Blog posts and fetching posts
First, create a new page in your Next.js app. For this example, let’s call it PostsPage.js
. You can do this by creating a new file in the pages
directory of your Next.js app.
In this blog post, we will take a closer look at a code snippet that is used to create a blog post page in Next.js. The code allows you to fetch blog posts from a WordPress website using the WordPress REST API and display them on a web page.
The code imports the necessary modules and components, such as useRouter
from Next.js, Link
from Next.js, axios
, Image
from Next.js, and Nav
from a custom component.
Let’s take a closer look at the code:
import { useRouter } from "next/router";
import Link from "next/link";
import axios from "axios";
import Image from "next/image";
import Nav from "../components/Nav";
export default function PostsPage({ blogPosts }) {
const router = useRouter();
// Get the current language from the router
const { locale } = router;
// Filter the blog posts to show only the ones in the current language
const filteredBlogPosts = blogPosts.filter(
(post) => post.language_code === locale
);
return (
<>
<Nav />
<h1>Blog Posts</h1>
{filteredBlogPosts?.map((item, index) => (
<div key={item.id}>
<Link href={`/post/${item?.slug}`}>
<a>
<Image
src={item?.featured_media_url}
alt={item?.excerpt?.rendered}
width={400}
height={400}
/>
</a>
</Link>
<div>
<h3>
<Link href={`/post/${item.slug}`}>
<a
dangerouslySetInnerHTML={{
__html: item?.title?.rendered,
}}
></a>
</Link>
</h3>
<p
dangerouslySetInnerHTML={{
__html: item?.excerpt?.rendered,
}}
></p>
</div>
<div>
<Link href={`/post/${item.slug}`}>
<a>Read more ...</a>
</Link>
</div>
</div>
))}
</>
);
}
export async function getServerSideProps(context) {
const { locale } = context;
let blogPosts = [];
const blogPostsEndpoint = `https://gcms.codaton.com/wp-json/wp/v2/posts?_embed&lang=${locale}&order=desc&per_page=100&status=publish`;
try {
const response = await axios.get(blogPostsEndpoint);
blogPosts = response.data;
} catch (error) {
console.error(error);
}
return {
props: {
blogPosts,
},
};
}
JavaScriptStep 8: Creating a Page to display Single Post
Time to make your website dynamic! Head over to your Next.js project and create a new folder called “post” under the “pages” directory. Within the “post” folder, create a new file called “[post].js”. Copy and paste the snippet code provided below to retrieve and display a single blog post on your website. Get ready to take your website to the next level!
import axios from "axios";
import Image from "next/image";
import Nav from "../../components/Nav";
export default function Projects({ singlePost }) {
return (
<div>
<Nav />
<Image
src={singlePost[0]?.featured_media_url}
alt={singlePost[0]?.featured_media_url}
width={1024}
height={400}
/>
<div
dangerouslySetInnerHTML={{
__html: singlePost[0]?.content?.rendered,
}}
></div>
</div>
);
}
export async function getServerSideProps(context) {
const { query, locale } = context;
let singlePost = [];
const singlePostEndPoint = `https://gcms.codaton.com/wp-json/wp/v2/posts?_embed&lang=${locale}&order=desc&per_page=100&status=publish&slug=${query.post}`;
await axios.get(singlePostEndPoint).then(function (response) {
singlePost = response.data;
});
return {
props: {
singlePost,
},
};
}
JavaScriptCongratulations! You’ve just leveled up your coding skills by completing an awesome mini-project with multilanguage functionality!
You might also enjoy
How to Add Author and Featured...
Enhancing the WordPress REST API: Adding Author and Featu...
How to Truncate dangerouslySet...
When working with React, you may encounter situations whe...
Building a Multilingual Next.j...
Polylang is a popular WordPress plugin that allows users ...
Comments (0)
No comments yet!
Speak up and share your thoughts! Your comments are valuable to us and help us improve.writeComment