Power up your next blog using WordPress and Vue.js
I’ve been working on a project for an architecture firm lately. It’s written with Nuxt.js as a progressive web application. Due to the static nature of the website, I wasn’t considering implementing a CMS for it until the client requested a fully functional blog.
At first, I considered using Nuxt content, but normal non-technical users don’t like interacting with Markdown at all. My next option was a ready-to-use headless CMS, but the client insisted on having WordPress as a blogging system because of their familiarity with it.
That’s when I decided to leverage WordPress capabilities as a headless CMS through its almost rich REST API.
Using this simple walkthrough, you can set up your next blog with WordPress as a headless CMS.
Get to know WordPress REST API and its endpoints
You can use either a fresh installed WordPress website or one already in production. the base URL for accessing its endpoints is [Your website address]/wp-json/wp/v2/ and since I’m using a local development environment, it would be https://localhost/blog/wp-json/wp/v2/posts.
A complete list of WordPress REST API endpoints can be found in WordPress’s official reference, but the one I’ll be using today is /wp/v2/posts
.
Sending a get request to the URL above results in listing all posts along with their id, slug, date, status (published or not), title, content, and much much more.
You can filter the results with WP Global Parameters. I’m going to get the only field I need for implementing the blog which would be id, slug, title, content, and author.
Implement the blog in our Vue.js application
Now let’s use our Vue.js application to retrieve and show these posts. I’ve created two components called PostList and Post.
Using the below code, we can retrieve the posts:
mounted() {
fetch('http://localhost/blog/wp-json/wp/v2/posts')
.then(response => response.json())
.then(data => this.posts = data);
}
In our template, we’re going to show the retrieved posts like this:
<div class="posts-list">
<div v-for="(post, index) in posts" :key="index" class="post">
<h1>
<router-link :to="{name: 'Post', params: {id: post.id}}">{{ post.title['rendered'] }}</router-link>
</h1>
<p v-html="post.content['rendered']"></p>
</div>
</div>
As you can see, every title is linked to the post page. I’ve defined the routes as below:
routes: [
{
path: '/',
name: 'Home',
component: App
},
{
path: '/blog',
name: 'Blog',
component: PostList
},
{
path: '/post/:id',
name: 'Post',
component: Post
}
]
Using a dynamic route, the post title, content, and image can be retrieved like this (we’re going to add the _embed global parameter in our call so that the featured image is also fetched) :
fetch(`http://localhost/blog/wp-json/wp/v2/posts/${this.$route.params.id}?_embed`)
.then(response => response.json())
.then(data => this.post = data);
And in our template:
<div class="container">
<div class="post-image">
<img :src="post._embedded['wp:featuredmedia']['0'].source_url" alt="">
</div>
<h1>
{{ post.title['rendered']}}
</h1>
<p v-html="post.content['rendered']"></p>
</div>
Which results in:
As easy as pie
As you have seen, using WordPress as a headless CMS is super easy and fun. Though there are many more of its abilities to use in production. You can get a broad view of WordPress REST API in their official documentation. Some other features, like modifying or creating endpoints are also achievable.