granit nebiu logo

Building a Multilingual Next.js Blog with Polylang

cmsgranit

Author:

cmsgranit

https://gcms.codaton.com/wp-content/uploads/2023/02/next-js-polylang-react-polylang.jpg

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' 
JavaScript

Save 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;
JavaScript

This 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;
JavaScript

Step 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
Terminal

Finally, 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;
JavaScript

Step 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,
      },
   };
}
JavaScript

Step 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,
      },
   };
}
JavaScript

Congratulations! You’ve just leveled up your coding skills by completing an awesome mini-project with multilanguage functionality!

You might also enjoy

<p>Enhancing the WordPress REST API: Adding Author and Featured Image to Post Responses. Are you working with the WordPress REST API and need to include the author and featured image of your posts in the response? By default, the WordPress REST API doesn&#8217;t include the author or featured image fields in the post response. But [&hellip;]</p>

How to Add Author and Featured...

Enhancing the WordPress REST API: Adding Author and Featu...

<p>When working with React, you may encounter situations where you need to render HTML content as a string using dangerouslySetInnerHTML. This can be useful for rendering user-generated content, but it also introduces potential security vulnerabilities if the content is not properly sanitized. In this article, we&#8217;ll explore how to truncate dangerouslySetInnerHTML in React using a [&hellip;]</p>

How to Truncate dangerouslySet...

When working with React, you may encounter situations whe...

<p>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 [&hellip;]</p>

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