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