New Nextjs + headless Wordpress site

05/05/2023

Context

Lately, I had the opportunity to develop a small showcase site, actually a visual update of a legacy site in the flour industry.

This was a classic Wordpress site as you can see below with an outdated design.

Alliance Farine legacy

Stack choice

The new design has already been made by a friend of mine, and I just had to care about web development.

The client wanted to continue using Wordpress for content management. Though, I wanted to use the modern JS stack I'm confortable with.

Obviously, I decided to combine both desires and use Wordpress as headless CMS to generate content on a Next.js based front-end.

As I intended to use Vercel to host the front site, I quickly stumbled on an official guide + starter.

Wordpress

This is not my first Wordpress experience, actually maybe the thenth or something ๐Ÿ˜›.

I even already used Wordpress as API for a previous version of my projects portfolio, which is managed via Markdown files for a while now.

The main difference this time is that I decided to stick to the recommanded starter way: using a Wordpress Graph QL API using the WPGraphQL plugin.

I struggled a bit building the proper queries for each content request, as I usually never use it, but started to understand more and more as I tried things right into the plugin playground.

Though, it's still mentally hard for me to build the right query on the first try, as I mess a lot with nodes/edges, objects keys...

Next.js

Nothing special to say on this part, except I brought Framer-motion back into the game to leverage a wide variety of animations, from micro interactions, to scroll-linked and scroll-triggered kind, even page transitions.

Next.js is still my framework of choice at the time as it's reliable and performant, backed by a huge community.

I was tempted back then to switch to Sveltekit when I built the 2023 new year game.

But the main blocking thing remains the lacking of an official image optimization workflow.

Deployment

I was overwhelmed with questions before I grasp the nettle, especially regarding the hosting part on production and how to disable the legacy Wordpress front-end given an url.

I found a useful insight which is simply to create a subdomain for the Wordpress part and set the proper redirections.

Here are the steps I followed:

  1. I already have an existing domain on OVH redirecting to some legacy hosting instance
  2. I bought a new hosting instance with an empty SQL database
  3. I packaged the site locally using the famous Duplicator plugin
  4. I uploaded the package via ftp, then deployed it online
  5. I configured a new admin.xxx subdomain and attached it to my hosting instance
  6. I added some SSL certificates for these subdomains
  7. I changed the wp-config site name URL for the admin subdomain
  8. I deployed my front site on Vercel with the proper environment variables (especially the new production GraphQL API)
  9. I attached the legacy OVH domain to the new Vercel hosting

And it finally worked! ๐Ÿพ

Site admin is accessible through the admin subdomain, and front-site is accessible from the legacy root domain being properly redirected via DNS.

This is a major one, and the starter explain how to get unpublished post versions via specific API calls.

But my problem was all different : there is no posts (only pages) and no draft states.

This site only has published pages.

All I wanted was to make the bridge between the editing phase on Wordpress, and a preview button, leading to the proper page url, and not the legacy one using some Wordpress hierarchy.

I found a quick snippet that solved this use-case by rewriting preview urls.

It works for both dev and production, and both root and children pages.

It has to be placed right into functions.php:

function custom_frontend_url( $permalink, $post ) {
    $isDev = $_SERVER['HTTP_HOST'] === 'localhost:8888';
    $domain = $isDev ? 'http://localhost:3027' : 'https://alliance-farine.fr';

    $isHomepage = $post == 10;

    if(!$isHomepage){
        $custom_permalink = str_replace( home_url(),  $domain,  $permalink );
    }else{
        $custom_permalink = $domain;
    }

    return $custom_permalink;
};

add_filter( 'page_link', 'custom_frontend_url', 10, 2 );
add_filter( 'post_link', 'custom_frontend_url', 10, 2 );
add_filter( 'post_type_link', 'custom_frontend_url', 10, 2 );

Wrapping up

Here is the new deployed site: alliance-farine.fr.

I wouldn't say it's the easiest way to deploy a website as Wordpress is not design for this purpose.

But it allows someone, considering the Wordpress contraint from the client, to achieve this combination using our beloved front-end tools ๐Ÿ’•.

The best stack to my opinion is still to use a headless CMS, without having to mess up with a non-conventional workflow.

I already tried some solutions such as Prismic, Storyblok, and Strapi.

The one I'm willing to try is Sanity, as it seems to offer a local environment through special syncs under the hood.

But let that experience take part and explained in a futur post hopefully ๐Ÿ™‚.