How to create a static Headless WordPress site using Next.js and the Bogo plugin


WordPress has a number of plugins for managing multilingual content, such as PolylangWPML, and Bogo. By combining these plugins and their extensions, many websites can now be delivered in multiple languages.

When publishing a website on Headless/Jamstack, the requirement to support multiple languages cannot be avoided. However, if possible, we would like to make use of the know-how and assets that we have built up through building and operating websites.

In this article, I will briefly introduce how to use a website that has been made multilingual with a plugin, Bogo, on a website that has been made static with Next.js.

Retrieving data by each language from WP API

Articles created by Bogo can be retrieved from the WP API.

However, since we need to use the filter query, we need to add the following code.

The code of the above plugin is as follows: filter The query is designed to search WP Query.

<?php

/**
 * Plugin Name: WP REST API filter parameter
 * Description: This plugin adds a "filter" query parameter to API post collections to filter returned results based on public WP_Query parameters, adding back the "filter" parameter that was removed from the API when it was merged into WordPress core.
 * Author: WP REST API Team
 * Author URI: http://v2.wp-api.org
 * Version: 0.1
 * License: GPL2+
 **/

add_action('rest_api_init', 'rest_api_filter_add_filters');

/**
 * Add the necessary filter to each post type
 **/
function rest_api_filter_add_filters()
{
  foreach (get_post_types(array('show_in_rest' => true), 'objects') as $post_type) {
    add_filter('rest_' . $post_type->name . '_query', 'rest_api_filter_add_filter_param', 10, 2);
  }
}

/**
 * Add the filter parameter
 *
 * @param  array           $args    The query arguments.
 * @param  WP_REST_Request $request Full details about the request.
 * @return array $args.
 **/
function rest_api_filter_add_filter_param($args, $request)
{
  // Bail out if no filter parameter is set.
  if (empty($request['filter']) || !is_array($request['filter'])) {
    return $args;
  }

  $filter = $request['filter'];

  if (isset($filter['posts_per_page']) && ((int) $filter['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 100)) {
    $args['posts_per_page'] = $filter['posts_per_page'];
  }

  global $wp;
  $vars = apply_filters('rest_query_vars', $wp->public_query_vars);

  // Allow valid meta query vars.
  $vars = array_unique(array_merge($vars, array('meta_query', 'meta_key', 'meta_value', 'meta_compare')));

  foreach ($vars as $var) {
    if (isset($filter[$var])) {
      $args[$var] = $filter[$var];
    }
  }
  return $args;
}



By making this code work, you will be able to retrieve articles by language with an API call like the one below.

Japanese only: wp-json/wp/v2/posts?filter[lang]=ja
English only: wp-json/wp/v2/posts?filter[lang]=en
Based on the default language: wp-json/wp/v2/posts?filter[lang]=en_US

Static generation of pages by each language in Next.js

Now that we can get data from the REST API, all we have to do is call that API from Next.js to generate the page.

About the i18n module in Next.js

Next.js has a module for multiple languages since version 10. However, this feature is not available when staticized with next export.

Therefore, in this article, we will show you how to generate pages with getStaticPath and getStaticProps.

Create a file in /pages/ for each language

Next.js generates URLs based on the files placed in /pages.

So add a page like /pages/en/index.tsx if you want to add English content, or /pages/ja_JP/index.tsx if you want to add Japanese to an English site.

export const getStaticProps = async () => {
  const posts = await fetch('https://example.com/wp-json/wp/v2/posts?filter[lang]=ja')
  return {
    props: {
      posts
    }
  }
}

export default function Home({posts}) => {
  return (
   <ul>
      {posts.map(post => (
        <li key={post.ID}><Link href={`/ja_JP/{post.slug}`}>{post.title.rendered}</Link></li>
      )} 
   </ul>
  )
}

Then, place [slug].tsx in the same directory as index.tsx, and create each submission page there.

export const getStatisPaths = async () => {
  const posts = await fetch('https://example.com/wp-json/wp/v2/posts?filter[lang]=ja')
  return {
    fallback: false,
    paths: posts.map(post => ({
      params: {
         slug: decodeURI(post.slug)
      }
    })
  }
}

export const getStaticProps = async ({params}}) => {
    const slug = typeof params.slug === 'string' ? params.slug : params.slug[0]
  const posts = await fetch('https://example.com/wp-json/wp/v2/posts?filter[lang]=ja&slug={slug}')
  return {
    props: {
      post: posts[0]
    }
  }
}

export default function Page({post}) => {
  return (
   <div>
   <h1>{post.title.rendered}</h1>
   </div>
  )
}

Note that in production, it is necessary to use getStatisPaths to fetch all pages. fallback can be used to generate pages dynamically in Next.js, but if you use this method, you will not be able to use next export for SSG using next export will not be possible.

Once you have a set of pages for one language, you can place them under /pages/ with different filter[lang] values.

Once you have a set of pages for one language, you can place them under /pages/ with different filter[lang] values.

Appendix: About searching with Algolia

If you want to search multilingual content on Bogo, we recommend that you prepare a search index in Algolia, and by using the WP Search with Algolia plugin, the search index will be created and updated automatically when you update your articles.

However, if you just use the plugin. mentioned above, Algolia will not send an attribute to determine which language the post is in, so all posts in all languages will be displayed in search results such as Algolia Instantsearch.

By using the Search with Algolia Bogo extension plugin, you can automatically reflect Bogo’s language settings in Algolia’s index when updating articles.

When searching, let’s run the following search process in Instantsearch.js.

index.search("about next", {
 "getRankingInfo": true,
 "analytics": false,
 "enableABTest": false,
 "hitsPerPage": 10,
 "attributesToRetrieve": "*",
 "attributesToSnippet": "*:20",
 "snippetEllipsisText": "…",
 "responseFields": "*",
 "maxValuesPerFacet": 100,
 "page": 0,
 "facets": [
  "*",
  "locale",
 ],
 "facetFilters": [
  [
   "locale:en_US"
  ]
 ]
});

Creating a simple multilingual Jamstack site with Bogo and Next.js

By using Bogo, you can get multilingual content management features that can be used from the WP API with minimal customization. Next.js is a framework that makes it easy to build a multilingual site frontend, as it has multilingualization functions implemented in its core.

By using Jamstack, there is less need to consider how to incorporate multilingual functions into WordPress themes, and if you use Next.js, multilingualization can be achieved at a relatively low cost.

You can also use ideas such as “when retrieving data from getStaticProps, which generates pages, use DeepL or Google/AWS translation APIs to automatically translate articles that are not yet translated on the WordPress side.

Take the Next Step

Get started on your website today with Shifter. Try out our free plan and take the first step towards building the perfect website for you and your visitors.