<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dave</title>
    <description>The latest articles on DEV Community by Dave (@thedavedavies).</description>
    <link>https://dev.to/thedavedavies</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F205049%2Fd64b7ec7-57f5-414e-a2ad-bbb28c5a3f29.jpeg</url>
      <title>DEV Community: Dave</title>
      <link>https://dev.to/thedavedavies</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thedavedavies"/>
    <language>en</language>
    <item>
      <title>How to use 11ty with Headless WordPress</title>
      <dc:creator>Dave</dc:creator>
      <pubDate>Sun, 28 Feb 2021 17:08:59 +0000</pubDate>
      <link>https://dev.to/thedavedavies/how-to-use-11ty-with-headless-wordpress-and-deploy-to-netlify-3i73</link>
      <guid>https://dev.to/thedavedavies/how-to-use-11ty-with-headless-wordpress-and-deploy-to-netlify-3i73</guid>
      <description>&lt;p&gt;In this tutorial, we'll learn how to use 11ty with Headless WordPress, and then deploy it to Netlify.&lt;/p&gt;

&lt;p&gt;You can see the final project hosted on Netlify at &lt;a href="https://headless-wordpress-11ty.netlify.app/" rel="noopener noreferrer"&gt;headless-wordpress-11ty.netlify.app&lt;/a&gt;, or skip the tutorial altogether and view the Git repo at &lt;a href="https://github.com/thedavedavies/Headless-WordPress-11ty" rel="noopener noreferrer"&gt;github.com/thedavedavies/Headless-WordPress-11ty&lt;/a&gt;. &lt;strong&gt;Lets get started!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Eleventy?
&lt;/h2&gt;

&lt;p&gt;Eleventy (or 11ty) is a Static Site Generator, which we can use to fetch our WordPress posts and pages, and then compile the data at build time. This allows us to use WordPress as a Headless CMS, and deploy an entirely static and lightweight site to &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;. We can get this data from WordPress using either the WordPress REST API, or using a WPGraphQL endpoint. In this tutorial, we'll be using the WordPress REST API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use 11ty with Headless WordPress?
&lt;/h2&gt;

&lt;p&gt;These days there are many great headless Content Management Systems (CMS) and Static Site Generators (SSG) to choose from, so why pick WordPress over any other? I've been working with WordPress for over 10 years, and had a load of established sites I wanted to be able to use the data on. Some of these sites didn't need any extra functionality and so entirely static HTML pages are a perfect solution.&lt;/p&gt;

&lt;p&gt;WordPress also has an active and supportive community, with thousands of plugins to help you build any type of website. For sites which need extra functionality, you can use &lt;a href="https://dev.to/thedavedavies/using-nextjs-with-headless-wordpress-44om"&gt;NextJS with Headless WordPress&lt;/a&gt; too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the WordPress fetch API
&lt;/h2&gt;

&lt;p&gt;If you've never used Eleventy before, then there's loads of great resources at &lt;a href="https://www.11ty.dev/" rel="noopener noreferrer"&gt;https://www.11ty.dev&lt;/a&gt;. In the meantime, create a fresh project (we'll call ours &lt;strong&gt;Headless-WordPress-11ty&lt;/strong&gt;) and open that new project in your code editor (I'm using VS Code).&lt;/p&gt;

&lt;p&gt;Installing Eleventy into our project requires a &lt;code&gt;package.json&lt;/code&gt; file. Let's create it with &lt;code&gt;npm init -y&lt;/code&gt;. The &lt;code&gt;-y&lt;/code&gt; parameter tells npm to skip all the questions and just use the defaults.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
npm install --save-dev @11ty/eleventy node-fetch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In that code snippet above, the dependencies we're installing are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Eleventy&lt;/strong&gt; -- The Static Site Generator&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.npmjs.com/package/node-fetch" rel="noopener noreferrer"&gt;&lt;strong&gt;node-fetch&lt;/strong&gt;&lt;/a&gt; -- We'll use this to fetch our data from the WordPress REST API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preparing our 11ty project to fetch data from the WordPress REST API
&lt;/h2&gt;

&lt;p&gt;After installing the &lt;strong&gt;Eleventy&lt;/strong&gt; and &lt;strong&gt;node-fetch&lt;/strong&gt; packages, create a new directory in the root of your project called &lt;strong&gt;_data&lt;/strong&gt;, and inside that new &lt;strong&gt;_data&lt;/strong&gt; folder create a file called &lt;strong&gt;posts.js&lt;/strong&gt;. The &lt;strong&gt;_data&lt;/strong&gt; directory is where all of our global data will be controlled. In our case, that means using the WordPress REST API to hit our endpoint and fetch our posts and pages.&lt;/p&gt;

&lt;p&gt;Back in your root directory, create another new directory named &lt;strong&gt;_layouts&lt;/strong&gt;, and inside &lt;strong&gt;_layouts&lt;/strong&gt; create a new file called &lt;strong&gt;layout.njk&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's with the .njk file extension?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The .njk file extension means that we're using Nunjucks as a templating language. You can easily use 10 different templating languages in 11ty (or a mixture of them all) so whilst we're using Nunjucks, if there's a different template language you're more comfortable using, then go ahead and use that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, back in your root directory again, create 2 new files called &lt;strong&gt;index.njk&lt;/strong&gt; and &lt;strong&gt;posts.njk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Having added these new directories and files, your project should be looking similar to this screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8n41hgl076yks2zlztm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8n41hgl076yks2zlztm.jpg" alt="Screenshot of 11ty-Headless-WordPress project setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Creating a .gitignore file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While a &lt;strong&gt;.gitignore&lt;/strong&gt; file isn't essential to testing out the WordPress REST API with 11ty, it's highly recommended for when you want to deploy your site. Here's the &lt;strong&gt;.gitignore&lt;/strong&gt; settings I'm using for this project:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
_site/
_tmp/
.DS_Store
node_modules/
package-lock.json
.env*

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Fetching post data from the WordPress REST API
&lt;/h2&gt;

&lt;p&gt;Now that we've prepared the foundations and set up our base project, let's get writing some code to fetch our posts from WordPress.&lt;/p&gt;

&lt;p&gt;Head to your &lt;strong&gt;_data/posts.js&lt;/strong&gt; file, and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetch = require("node-fetch");

module.exports = async function () {
  console.log("Fetching data...");

  return fetch("https://fake-data.better-wordpress.dev/wp-json/wp/v2/posts")
    .then((res) =&amp;gt; res.json())
    .then((json) =&amp;gt; json);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exclusively a browser API, we can't use &lt;strong&gt;fetch&lt;/strong&gt; in NodeJS. Using the &lt;strong&gt;node-fetch&lt;/strong&gt; package brings the ability to use &lt;strong&gt;fetch&lt;/strong&gt; into NodeJS. We're then setting up an &lt;strong&gt;asynchronous function&lt;/strong&gt;, which expects a promise to be returned, which is exactly what's happening when we run &lt;code&gt;return fetch("https://fake-data.better-wordpress.dev/wp-json/wp/v2/posts")&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1.5: Testing your fetch
&lt;/h2&gt;

&lt;p&gt;Next, open your &lt;code&gt;package.json&lt;/code&gt; file and in your scripts property add the following 2 scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "start": "npx @11ty/eleventy --serve",
    "build": "npx @11ty/eleventy"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;scripts&lt;/strong&gt; property in your &lt;strong&gt;package.json&lt;/strong&gt; file allows you to run predefined scripts. Once you've added the &lt;strong&gt;start&lt;/strong&gt; and &lt;strong&gt;build&lt;/strong&gt; scripts above, you'll be able to run &lt;code&gt;npm run start&lt;/code&gt; to start up a hot-reloading local web server, and &lt;code&gt;npm run build&lt;/code&gt; to compile any templates into the output folder (this defaults to &lt;strong&gt;_site&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do we get back from our fetch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;async function&lt;/strong&gt; we wrote earlier in &lt;strong&gt;_data/posts.js&lt;/strong&gt; returns to us a JSON object which we can then work with. To confirm that the data is coming back successfully from the WordPress REST API, you can change the final &lt;code&gt;.then&lt;/code&gt; in your function to a &lt;code&gt;console.log()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return fetch("https://fake-data.better-wordpress.dev/wp-json/wp/v2/posts")
    .then((res) =&amp;gt; res.json())
    .then((json) =&amp;gt; console.log(json);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and run your &lt;code&gt;npm run start&lt;/code&gt; script in your console. If all goes well with your fetch, then you should see an output similar to the screenshot below, with your JSON data logged out into the console:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmq9la0pl2sg5sc58dai.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmq9la0pl2sg5sc58dai.jpg" alt="Screenshot of example console output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Creating a layout template
&lt;/h2&gt;

&lt;p&gt;Now that we're successfully fetching our posts from the WordPress REST API, we can start creating a template to show that data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you changed your &lt;strong&gt;fetch&lt;/strong&gt; function to &lt;code&gt;console.log(JSON)&lt;/code&gt; the JSON data, then make sure you now return it to how it was in Step 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In your &lt;strong&gt;_includes/layout.njk&lt;/strong&gt; file, paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"/&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"/&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"/&amp;gt;
    &amp;lt;title&amp;gt;{{ posts.title.rendered }}&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    {{ content | safe }}
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Very simply, the code above scaffolds out the HTML we'll use to display our data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{{ posts.title.rendered }}&lt;/code&gt; is the title object that we get back in our JSON object.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;{{ content | safe }}&lt;/code&gt; means that the layout template will populate the &lt;code&gt;content&lt;/code&gt; data with the child template's content. Using the &lt;code&gt;safe&lt;/code&gt; filter prevents double-escaping the output (this is built into Nunjucks).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Creating our index page
&lt;/h2&gt;

&lt;p&gt;Now we get to start seeing content in our browser! In your &lt;strong&gt;index.njk&lt;/strong&gt; file, paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
pagination:
  data: posts
  size: 2
layout: layout.njk
title: "Latest Posts"
---

&amp;lt;ol&amp;gt;
  {%- for item in pagination.items %}
    &amp;lt;li&amp;gt;
      &amp;lt;a href="/posts/{{ item.title.rendered | slug }}"&amp;gt;
        {{ item.title.rendered }}&amp;lt;/li&amp;gt;
    &amp;lt;/a&amp;gt;
  {% endfor -%}
&amp;lt;/ol&amp;gt;

&amp;lt;nav&amp;gt;
  &amp;lt;ol&amp;gt;
    &amp;lt;li&amp;gt;
      {% if pagination.href.previous %}
        &amp;lt;a href="{{ pagination.href.previous }}"&amp;gt;Previous&amp;lt;/a&amp;gt;
      {% else %}Previous{% endif %}
    &amp;lt;/li&amp;gt;
    {%- for pageEntry in pagination.pages %}
      &amp;lt;li&amp;gt;
        &amp;lt;a href="{{ pagination.hrefs[ loop.index0 ] }}" {% if page.url == pagination.hrefs[ loop.index0 ] %} aria-current="page" {% endif %}&amp;gt;Page
          {{ loop.index }}&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
    {%- endfor %}
    &amp;lt;li&amp;gt;
      {% if pagination.href.next %}
        &amp;lt;a href="{{ pagination.href.next }}"&amp;gt;Next&amp;lt;/a&amp;gt;
      {% else %}Next{% endif %}
    &amp;lt;/li&amp;gt;
  &amp;lt;/ol&amp;gt;
&amp;lt;/nav&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nunjucks uses &lt;strong&gt;front matter&lt;/strong&gt;, which will be processed by our templates when we build our site. So what does this front matter do?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pagination&lt;/strong&gt; iterates over our data set and then creates pages for individual chunks of data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;data: posts&lt;/strong&gt; is taking our &lt;strong&gt;_data/posts.js&lt;/strong&gt; as a data set. The front matter value for &lt;strong&gt;data&lt;/strong&gt; needs to match up with our data file. So, if the file was called &lt;strong&gt;_data/pages.js&lt;/strong&gt;, then our front matter would instead be: &lt;strong&gt;data: pages&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;size: 2&lt;/strong&gt; is telling 11ty to list 2 of our posts before moving onto pagination&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;layout: layout.njk&lt;/strong&gt; is telling 11ty to use the layout that we built in Step 2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that saved, and &lt;code&gt;npm run start&lt;/code&gt; running, you should now be able to see a paginated list of our pre-build posts from WordPress!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzapks4jp6tjpxnywjfv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzapks4jp6tjpxnywjfv.jpg" alt="Screenshot of the browser with our pagination output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Creating a template for our single posts
&lt;/h2&gt;

&lt;p&gt;The final task we have to do before launching our site is to create a template for our single posts. Paste the following code into &lt;strong&gt;posts.njk&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
pagination:
    data: posts
    size: 1
    alias: posts
permalink: "posts/{{ posts.title.rendered | slug }}/"
layout: layout.njk
---

&amp;lt;h1&amp;gt;{{ posts.title.rendered }}&amp;lt;/h1&amp;gt;
&amp;lt;div class="mainContent"&amp;gt;
    {{posts.content.rendered | safe}}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The front matter in our &lt;strong&gt;posts.njk&lt;/strong&gt; file is similar to our &lt;strong&gt;index.njk&lt;/strong&gt;, however this time our pagination size is just 1, and we're using an &lt;a href="https://www.11ty.dev/docs/pagination/" rel="noopener noreferrer"&gt;alias&lt;/a&gt; in the slug.&lt;/p&gt;

&lt;p&gt;11ty provides a number of filters which we can pass into our content. Here, we're using the &lt;strong&gt;slug&lt;/strong&gt; filter to 'slugify' our URL, and the &lt;strong&gt;safe&lt;/strong&gt; filter again to render out the HTML we get back from the WordPress REST API.&lt;/p&gt;

&lt;p&gt;Finally we have a fully built (but very much unstyled) site which is populated from our existing WordPress website! Our last task is to deploy this site to Netlify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Hosting our 11ty site with Netlify
&lt;/h2&gt;

&lt;p&gt;Netlify is a powerful serverless hosting platform with an intuitive git-based workflow and a very generous free tier. This means we can deploy our static 11ty site to Netlify, and if you're using Git you can connect Netlify to your Git repo to trigger a rebuild every time you commit.&lt;/p&gt;

&lt;p&gt;At this point, it's best practice to remove your API endpoint URLs from your code and use a &lt;strong&gt;.env&lt;/strong&gt; file instead. So let's do that by installing the &lt;a href="https://www.npmjs.com/package/dotenv" rel="noopener noreferrer"&gt;&lt;strong&gt;dotenv&lt;/strong&gt;&lt;/a&gt; package: &lt;code&gt;npm i dotenv&lt;/code&gt;. Next, create a &lt;strong&gt;.env&lt;/strong&gt; file in the root of your project. This is where we'll add all of our secret endpoint URLs. If you created a &lt;strong&gt;.gitignore&lt;/strong&gt; file earlier, make sure to have &lt;strong&gt;.env&lt;/strong&gt;* in the file. This will tell git to ignore all .env files.&lt;/p&gt;

&lt;p&gt;Open up your &lt;strong&gt;.env&lt;/strong&gt; file, paste in your WordPress REST API endpoint along with a variable to link it to -- i.e.: &lt;code&gt;WORDPRESS_REST_API_URL=https://fake-data.better-wordpress.dev/wp-json/wp/v2/posts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to make sure that 11ty knows about our .env file, so create a &lt;strong&gt;.eleventy.js&lt;/strong&gt; file (note the dot at the start of that filename), and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = function () {
  require("dotenv").config();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this code do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;.eleventy.js&lt;/strong&gt; file holds all our custom site-wide configuration, but for now all we need to pass to it is our dotenv config. You can &lt;a href="https://www.11ty.dev/docs/config/" rel="noopener noreferrer"&gt;read more about Eleventy configuration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally in our &lt;strong&gt;_data/posts.js&lt;/strong&gt; file, we can replace our endpoint url with &lt;strong&gt;process.env.WORDPRESS_REST_API_URL&lt;/strong&gt;. We can now safely commit our code to our Git repo without exposing our secret endpoint URLs, or any other API keys you need to keep secret.&lt;/p&gt;

&lt;p&gt;Netlify already has a super in-depth blog post on &lt;a href="https://www.netlify.com/blog/2016/09/29/a-step-by-step-guide-deploying-on-netlify/" rel="noopener noreferrer"&gt;deploying your site&lt;/a&gt;, so follow that to get your site up on Netlify. One addition we want to make though, is just before you Deploy your site - click &lt;strong&gt;Advanced build settings&lt;/strong&gt; and add in your env key and value from your local .env file (which hopefully hasn't been committed to your repo).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaay7azue7hyrbhus12m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaay7azue7hyrbhus12m.jpg" alt="Screenshot of Netlify advanced build settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finished!
&lt;/h2&gt;

&lt;p&gt;And we're done! We now have a very high level proof-of-concept project to fetch our posts from the WordPress REST API, build them into a static site using Eleventy, then deploy that site to Netlify.&lt;/p&gt;

&lt;p&gt;There's plenty more we can do, including styling the site and fetching various pages and other data that the WordPress REST API gives us.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>11ty</category>
      <category>headless</category>
    </item>
    <item>
      <title>Using NextJS with Headless WordPress</title>
      <dc:creator>Dave</dc:creator>
      <pubDate>Sun, 21 Feb 2021 18:29:21 +0000</pubDate>
      <link>https://dev.to/thedavedavies/using-nextjs-with-headless-wordpress-44om</link>
      <guid>https://dev.to/thedavedavies/using-nextjs-with-headless-wordpress-44om</guid>
      <description>&lt;p&gt;&lt;a href="https://wordpress.org/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt; is used on over 1.3 billion websites across the world, and it works great as a Headless CMS. &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt; is a framework built on React to give you an amazing amount of features, which you would otherwise need to set up yourself (static rendering, bundling, prefetching etc), and provides super fast and performant websites. Let's combine the two to create a super fast headless WordPress website!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pre-requisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A basic understanding of NodeJS and React&lt;/li&gt;
&lt;li&gt;  An existing WordPress website with some posts and page&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll be using &lt;a href="https://www.colbyfayock.com/" rel="noopener noreferrer"&gt;Colby Fayock's&lt;/a&gt; Next.js WordPress Starter in this walkthrough (&lt;a href="https://github.com/colbyfayock/next-wordpress-starter/" rel="noopener noreferrer"&gt;https://github.com/colbyfayock/next-wordpress-starter/&lt;/a&gt;). This Next.js WordPress Starter project aims to "&lt;em&gt;take WordPress as a headless CMS and use Next.js to create a static experience that can be deployed anywhere.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;The Next.js WordPress Starter project allows us to easily pull everything you would normally expect to be in a WordPress website (posts, pages, author listings, global search) and brings it into NextJS through a GraphQL endpoint. The project is actively under development, so watch the repo for further feature updates!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  WordPress
&lt;/h3&gt;

&lt;p&gt;The Next.js WordPress Starter uses GraphQL, so start by logging into your WordPress website and install &lt;a href="https://www.wpgraphql.com/" rel="noopener noreferrer"&gt;WPGraphQL&lt;/a&gt;. If you don't have an existing WordPress website, I've set up a dummy project you can use instead at: &lt;a href="https://fake-data.better-wordpress.dev" rel="noopener noreferrer"&gt;https://fake-data.better-wordpress.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js WordPress Starter
&lt;/h3&gt;

&lt;p&gt;The quickest way to get started with NextJS for the frontend is by opening your terminal, navigating to the folder you want to start working in, and running:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn create next-app -e https://github.com/colbyfayock/next-wordpress-starter&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Once that's finished installing, open up your code editor and add an &lt;code&gt;.env.local&lt;/code&gt; file to the root of the project. This is where we're going to set up our Environmental Variables, so that NextJS knows where to get our data from.&lt;/p&gt;

&lt;p&gt;The Environmental Variable the Starter Project uses is: &lt;code&gt;WORDPRESS_GRAPHQL_ENDPOINT&lt;/code&gt;, so I'm using &lt;code&gt;WORDPRESS_GRAPHQL_ENDPOINT="https://fake-data.better-wordpress.dev/graphql"&lt;/code&gt; to get some dummy data. You can use this dummy WordPress data too while testing, but don't forget to replace the url with your own WordPress endpoint when you're ready to go live!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1uabk6infw3yqhlchrx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1uabk6infw3yqhlchrx.jpg" alt="Screenshot of .env.local file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back in your terminal, running &lt;code&gt;yarn dev&lt;/code&gt; starts up a development server. This isn't the time to be looking at performance and bundle size of your new NextJS website (a mistake I made when first experimenting with NextJS), although you should always be making sure you ship as small a bundle size as possible. We'll get to that later on.&lt;/p&gt;

&lt;p&gt;After running &lt;code&gt;yarn dev&lt;/code&gt; in your terminal, you can now open up your browser and see your Headless WordPress site running at: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations -- you now have a fully headless WordPress website running on the JAM stack, which includes all of you posts, pages and a live search! If you're using my fake data API, then your site should look similar to this screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplfscqemyudt0qx2twwr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplfscqemyudt0qx2twwr.jpg" alt="Screenshot of data coming from a Headless WordPress installation running on NextJS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Screenshot of data coming from a Headless WordPress installation running on NextJS&lt;/p&gt;

&lt;p&gt;At this point, you can start to customise the starter project to look and function exactly how you want it to. And when you're done, it's time to deploy your website for the world to see!&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying your NextJS website
&lt;/h2&gt;

&lt;p&gt;Before you run a production build, update your &lt;code&gt;package.json&lt;/code&gt; file with your live URL (on line 3). This is the URL which will be passed into your sitemap -- very important for SEO.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fnd6zc8jxfidnzf9nx2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fnd6zc8jxfidnzf9nx2.jpg" alt="Screenshot of package.json file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;yarn build&lt;/code&gt; in your terminal will actually fetch all of your posts and pages, create a sitemap and an optimised production build of your static website ready to deploy to your server.&lt;/p&gt;

&lt;p&gt;After running &lt;code&gt;yarn build&lt;/code&gt;, you can then run &lt;code&gt;yarn start&lt;/code&gt; to run a local server and test your local production build. This is the perfect time to be looking at your bundle sizes and site speed, as it's a good representation of how your site will respond on a server.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;vercel.com&lt;/a&gt; to deploy better-wordpress.dev. Vercel are the same team who built NextJS, and they have a generous free tier, so it makes perfect sense to deploy it there.&lt;/p&gt;

&lt;p&gt;I'm currently working on blog posts explaining how to deploy NextJS to Vercel, Netlify and other hosts -- but in meantime the Vercel docs are pretty great: &lt;a href="https://nextjs.org/docs/deployment" rel="noopener noreferrer"&gt;https://nextjs.org/docs/deployment&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;You now have a fully featured and blazingly fast website running on the JAM stack, using NextJS on the frontend and WordPress for your data.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
