Nuxt.js and the Wordpress REST API

Nuxt.js and the Wordpress REST API

Published: 5/3/20205 min read
JS
Vue.js
vuejs.svg logo
WordPress
Nuxt.js

Wordpress is a powerful CMS with a rich and deep ecosystem. You just name itโ€ฆ and there is a Wordpress plugin for it, not to mention the countless wordpress themes, invaluable official docs and wordpress dedicated communities. However, if you have some experience with modern Javascript frameworks like React or Vue, or even modern PHP frameworks (like Laravel) for that matter, doing stuff the "wordpress-wayโ€ might seem a bit rigid. So, if you want to experiment with a different way of using wordpress โ€“ this post is for you.

The Wordpress REST API

Since version 4.4 the Wordpress REST API infrastructure was integrated to the Wordpress core. The API allows us to get pages, posts, comments and much more as JSON. Also, the wordpress REST API is extendable! Here is a partial list of available endpoints:

/wp/v2/posts
/wp/v2/posts/<id>/revisions
/wp/v2/categories
/wp/v2/tags

๐Ÿ‘‰ Get the full list of available wordpress REST API endpoints here
๐Ÿ‘‰ A complete Wordpress REST API reference here
๐Ÿ‘‰ Official live demo here
Now, letโ€™s build a tiny Nuxt.js app!

Nuxt.js โ€“ A short Overview

Nuxt.js is a framework built on top of Vue.js. Basically, Nuxt.js offers us 3 modes of development/rendering:

  • Single Page Application (SPA)
  • Server Rendered (Universal SSR)
  • Static Generated

Nuxt.js has out-of-the-box routing, a convenient and simple project folder structure, HMR in development, automatic code splitting and many more features. The two development modes that I'm interested in are SSR and Static. Soon, we will see how easy it is to generate a static site with Nuxt.js.

Install

With npx:

$ npx create-nuxt-app <my-awesome-project>

Or with npm:

$ npm init nuxt-app <my-awsome-project>

Or with Yarn:

$ yarn create nuxt-app <my-awesome-project>

Start nuxting with:

npm run dev

Folder Structure

Nuxt has a clear and simple folder structure. For this small app, I will only use the layouts, components, and pages folders. The layouts folder is where you store, wellโ€ฆ your layouts. If Left unspecified, all the views in you pages folder will extend the default.vue layout. The components folder will store out components. The pages folder is where some of the Nuxt magic happens. If we create an about.vue file inside pages, Nuxt will create a route for us!

1. Create Home and About Pages

---|my-project/
------|pages/
---------about.vue
---------index.vue

We can also create an about folder and have an index.vue file inside it.

---|my-project/
------|pages/
---------|about/
------------index.vue
---------index.vue

Repeat folder + index.vue nesting as much as you want. You can also create dynamic routes.

2. Create Header, Loader and PostItem Components

To make things a bit shorter, the styles included in the components are available at the project's repository.

components/Header.vue file:

<template>
  <div class="container">
    <ul>
      <li>
        <nuxt-link to="/">Home</nuxt-link>
      </li>
      <li>
        <nuxt-link to="/about">About</nuxt-link>
      </li>
    </ul>
  </div>
</template>

components/Loader.vue file:

<template>
  <div class="container">
    <div>
      Fetching posts from WP REST API...
    </div>
  </div>
</template>

components/PostItem.vue file:

<template>
  <div class="post-item">
    <h3>#{{ post.id }}: {{ post.title.rendered }}</h3>
    <div class="the-excerpt" v-html="post.excerpt.rendered"></div>
  </div>
</template>

<script>
export default {
  props: {
    post: {
      type: Object,
      default: () => {}
    }
  }
};
</script>

Import components/Header.vue to layouts/default.vue:

<template>
  <div>
    <app-header />
    <nuxt />
  </div>
</template>

<script>
import AppHeader from "@/components/Header";
export default {
  components: {
    AppHeader
  }
};
</script>

Import components/Loader.vue and components/PostItem.vue to pages/index.vue:

<template>
  <div class="container">
    <div>
      <h1 class="title">Posts</h1>
    </div>
  </div>
</template>

<script>
import PostItem from "@/components/PostItem";
import Loader from "@/components/Loader";

export default {
  components: {
    Loader,
    PostItem
  },
}
</script>

3. Get Posts With The Nuxt.js Fetch Method

The fetch() method is a Nuxt hook available in your Nuxt-Vue components. It is called on the server side when your route renders, and on the client side on navigating. So, when you use the fetch() hook, $fetchState becomes available at the component level. $fetchState has some cool options like: $fetchState.pending and $fetchState.error. And here is an example for using how you can use the fetch() hook and $fetchState:

<template>
  <div class="container">
    <div>
      <h1 class="title">Posts</h1>
      <Loader v-if="$fetchState.pending" />
      <div v-else>
        <post-item v-for="post in posts" :key="post.id" :post="post" />
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import PostItem from "@/components/PostItem";
import Loader from "@/components/Loader";

export default {
  components: {
    Loader,
    PostItem
  },
  data() {
    return {
      posts: []
    };
  },
  async fetch() {
    const { data: posts } = await axios.get(
      "https://demo.wp-api.org/wp-json/wp/v2/posts"
    );
    this.posts = posts;
  }
};
</script>

4. Go Static

Generating and deploying static sites with Nuxt.js is simple. Simply run:

$ npm run generate

Nuxt will create a dist folder for you, with all your static files and assets. Make sure to check out the official docs for a deeper dive to deployment options.
๐Ÿ‘‰ Nuxt.js and wordpress REST API - Project repository here