DEV Community

Cover image for Using Docker For Local Development Of Headless WordPress Sites With NextJS
Josh Pollock
Josh Pollock

Posted on • Updated on

Using Docker For Local Development Of Headless WordPress Sites With NextJS

Back in 2016, I was talking about adding how the WordPress REST API was the first step in evolving WordPress to more of an application platform. Since then the WordPress post editor has been re-written in React. In addition to the WordPress REST API, there is now a GraphQL plugin for WordPress being developed with the goal of making it a part of WordPress core one day.

Back then, we were not sure how to integrate React or Vue with WordPress sites. Today, NextJS and Gatsby exist and come with WordPress presets. I am a huge fan of NextJS, which includes static site generation, making it perfect for static content sites. I also love the zero config routing for front-end pages and API routes.

NextJs's WordPress preset is everything you need to start a content site, with WPGraphQL. That's cool, but it could also be the start point for a WordPress-powered application.

Like most WordPress projects, the first step is choosing a local development environment for the WordPress site. There are a ton of options out there. I like to use Docker beacuse there is very little setup for WordPress, thanks to the @wordpress/wp-env package.

With a little configuration, we can automate all of the setup that is needed. This makes onboarding new developers and QA easier. In this article I am going to show you how to set that up. I will assume you are familiar with WordPress and NextJS.

Create The Application

First thing, we need a Next app. The WordPress preset is a great start point. It even includes Tailwind. Get started by generating the app using create-next-app:

yarn create next-app --example cms-wordpress cms-wordpress-app
Enter fullscreen mode Exit fullscreen mode

That will create the application. Now we need a WordPress.

Adding A Local WordPress Site

The configuration for this site is going to very minimal. We need a site with a few plugins and we need to set one constant in wp-config.php of that site. @wordpress/wp-env can do all of that.

The WordPress site will need to have WPGraphQL installed. I like to add the Headless Mode plugin I made with some friends awhile ago. This will redirect all unauthenticated requests to the front-end of the WordPress site will be redirected to the client.

First install the package:

yarn add @wordpress/env
Enter fullscreen mode Exit fullscreen mode

Then we will need to create a .wp-env.json config file for the local Docker site:

{
    "core": null,
    "plugins": [
        "https://downloads.wordpress.org/plugin/wp-graphql.zip",
        "https://downloads.wordpress.org/plugin/headless-mode.zip"
    ],
    "port": 4113,
    "config": {
        "HEADLESS_MODE_CLIENT_URL": "http://localhost:3000"
    }
}
Enter fullscreen mode Exit fullscreen mode

The "plugins" section is being used to download the latest version of both of those plugins from WordPress.org. The "config" section sets one PHP constant. This is the URL for the redirect. You will need to set one constant in production to match your deployed URL for the client, as documented here.

To make my life easier, I added a "wordpress" command to the scripts section of package.json


{
        "scripts": {
        "dev": "next",
        "build": "next build",
        "start": "next start",
        "wordpress": "wp-env start"
    }
}
Enter fullscreen mode Exit fullscreen mode

Making Them Work Toghether

Now, lets make sure the WordPress site is working. Try starting it:

yarn wordpress
Enter fullscreen mode Exit fullscreen mode

If everything goes as expected that will download the plugins we need and start the site. When it says its done, if you go to the front-end of the WordPress site it should redirect you to port 3000, which isn't' running and that is fine. We are not there yet.

If you go to the WordPress login page you should see that like normal. If you can login with username "admin" and password "password", then everything is good.

Configuring NextJS To Work With WordPress

Before starting the next app, we need to tell it what URL to source content from.

Create a .env and add this:

WORDPRESS_API_URL=http://localhost:4113/graphql`
Enter fullscreen mode Exit fullscreen mode

Now start the front-end

yarn && yarn dev
Enter fullscreen mode Exit fullscreen mode

Now you should see the front-end at http://localhost:3000/.

Adding A Plugin

If you're going to add custom post types, or register new mutations or do anything else that requires custom PHP code, you will need to add a plugin or mu-plugin.

I like having a plugin for my custom code, so I can turn it on and off. I added a directory called "wordpress-plugin" and put a file in there called "wordpress-plugin". Then I updated the "plugins" section of .wp-config.json to map that directory as a plugin:

{
    "core": null,
    "plugins": [
        "./wordpress-plugin",
        "https://downloads.wordpress.org/plugin/wp-graphql.zip",
        "https://downloads.wordpress.org/plugin/headless-mode.zip"
    ],
    "port": 4113,
    "config": {
        "HEADLESS_MODE_CLIENT_URL": "http://localhost:3000"
    }
}
Enter fullscreen mode Exit fullscreen mode

Check out this part of the documentation for more information on other ways to load plugins and mu-plugins.

Make Web Application Now

That's all you need to set up a NextJS app using a local WordPress site running in Docker containers. You can start developing the PHP and JavaScript for your project. What you do next is up to you. Figuring our deployment and authentication as well as coding the app will come next.

If you push the repo to Github, you can deploy the front-end with Vercel with their (super simpler importer](https://vercel.com/new). Make sure to set the WORDPRESS_API_URL environment variable to match the URL of the live WordPress site.

Feel free to fork the source for the example application to build your own thing. I hope you enjoy.

Featured image by Suresh Ramamoorthy on Unsplash

Discussion (1)

Collapse
mrahmadawais profile image
Ahmad Awais ⚡️

Good one, Josh. Minor typo

yarn add @wordpres/wp-env
Enter fullscreen mode Exit fullscreen mode

has an s missing in wordpress and should be:

yarn add @wordpress/wp-env
Enter fullscreen mode Exit fullscreen mode

Thank you! 🙌