Headless WordPress in Vue 3 - blog post background
So, continuing my experiments with getting everything working in Vue 3, hereās the next topic: setting up GraphQL, a headless WordPress, and Vue 3.
The documentation for Vue 3 and the corresponding Apollo client for GraphQL doesnāt seem to be up to date, soā¦ a couple of solutions to that not working.
First, I recommend this great video tutorial by Jason Lengstorf and Natalia Tepluhina, it will get you started.
However, if you donāt have 1 hour and 32 minutes of great video content, hereās a quick fix/setup to get GraphQL working with WordPress and Vue 3.
Headless WordPress prerequsities
A working installation of WordPress, somewhere, anywhere. For this, a basic setup will do. The only addition to the default installation of WordPress is one plugin, namely:
Add the GraphQL plugin, also available through the plugins search in WordPress.
A custom headless WP theme
For this project, I have created and activated a custom WordPress theme. It consists of a (so far) empty index.php file and a style.css file. They contain nothing.
Iām accessing the WordPress content through Vue, but thereās no automation set up. So if Vue is running on http://localhost:8080, thatās where content is served from.
Vue 3 setup and packages š¦
Install Vue 3/setup your project (with your default, I didnāt use TypeScript for this so perhaps some adjustments are needed).
With your package manager of choice, add the following packages to your dependencies:
- @apollo/client
- @vue/apollo-composable
- graphql
Hereās my package.json:
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@apollo/client": "^3.3.15",
"@vue/apollo-composable": "^4.0.0-alpha.10",
"core-js": "^3.6.5",
"graphql": "^15.5.0",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-airbnb": "^5.0.2",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^7.0.0",
"sass": "^1.26.5",
"sass-loader": "^8.0.2"
}
}
Letās get crackinā
main.js
import { createApp, provide, h } from 'vue';
import {
ApolloClient, InMemoryCache, gql,
} from '@apollo/client/core';
import { DefaultApolloClient } from '@vue/apollo-composable';
import App from './App.vue';
import router from './router';
import store from './store';
const defaultClient = new ApolloClient({
uri: <span style="color: #ff6600;">'insert-your-graphql-endpoint-here, like https://address-to-wordpress-installation/graphql'</span>,
cache: new InMemoryCache(),
});
const app = createApp({
setup() {
provide(DefaultApolloClient, defaultClient);
},
render() {
return h(App);
},
});
app.use(store);
app.use(router);
app.mount('#app');
At one point, I had the following error message:
This dependency was not found: * react in ./node_modules/@apollo/client/react/context/ApolloConsumer.js, ./node_modules/@apollo/client/react/hooks/useApolloClient.js and 1 other
The key to solving this was to do the import from ācoreā, as so:
import {
ApolloClient, InMemoryCache, gql,
} from '@apollo/client/core';
The GraphQL query
As in the video tutorial, I created a separate GraphQL file with the query.Inside my Vue installation, I have this file: app/src/graphql/allPosts.query.gql
The contents of that file look like this (copy-paste from WordPress GraphQL IDE):
query GET_ALL_POSTS {
posts {
nodes {
postId
content(format: RENDERED)
dateGmt
tags {
edges {
node {
name
link
}
}
}
title
}
}
}
The component
And then, my component in Vue looks like this:
<template>
<div class="single-blog-post" v-if="posts">
<article v-for="post in posts.nodes" :key="post.postId">
<h1>{{post.title}}</h1>
<div v-html="post.content"></div>
<hr/>
</article>
</div>
</template>
<script>
import { useQuery, useResult } from '@vue/apollo-composable';
import GET_ALL_POSTS from '../graphql/allPosts.query.gql';
export default {
name: 'ArchivePosts',
setup() {
const { result } = useQuery(GET_ALL_POSTS);
const posts = useResult(result, null, (data) => data.posts);
return {
posts,
};
},
};
</script>