VueJS ❀️ Craft CMS - Single Page App: the API

Published on July 5th, 2017

Estimated Reading Time is 4 mins

Sorry for the delay in getting this one out the door folks, but you know, life and all that.


So far, I've not done a lot with Craft, outside of my simple template and routing changes.

That's needs to change now that I need an API endpoint to consume.

To do that, we need the first-party Element API plugin from those fine folks at Craft.

I won't go through the install process. I'll wait while you do that.

All set? Great, let's dig in.

First up, I need to setup the Element API config. To do that, I need to create craft/config/elementapi.php. If you've followed the plugin install process, you'll have some boilerplate code to deliver an endpoint.

We'll strip that out and replace with

So what's going on here? Well api/v1/jobs.json is setting the url for the endpoint I'm going to hit. When I hit that url in the browser (or later using Axios in the Vue app), it'll load posts from Craft.

Next, the HeaderHelper::setHeader is allowing my endpoint to be accessed by any domain.

After that, I've set that I want to return an Entry element, I want 300 of them (my job board historically has around 250 live jobs at any one time), I want to pull from the Jobs section in Craft and I only want jobs posted in the last 90 days. You can pull that out of your own app if you want.

Also, because I want the category for each job, I need to grab that as well which is what the foreach is doing.

In the return I'm spitting out each field within an entry.

Now if I hit in my browser I should see something that looks a lot like this

I'm not going to bother with the meta object that's returning in this instance. If you plan to use pagination then it's something you'll need to figure out πŸ˜‰.

So with that being well and giving me some jobs, I can head back to my Vue app.

Specifically, I want to open Home.vue and then I'm going to create a new Vue component called JobList.vue within src/js/components/.

Again, like before, I can scaffold that really quick

My scaffold is generally emptier than that but I need something to return when I include this component within Home.vue.

So with that component saved, I hop back to Home.vue and it becomes

I'm including my new component <joblist></joblist> in my template, within my script tags, I'm importing it to be used and within my export, I tell Home.vue that I want to use the component I've just imported.

All things being well, I should now see List of Posts from Craft API in an <h1>.

Next I want to grab the data from the API and to do that I'm going to use Axios.

npm i axios --save to install it (remember to kill your current npm task script first).

Back in JobList.vue in my data definition, I'm going to set jobs as an empty array (because we have no entries until we make the API fetch).

I'm then going to declare a new Vue Instance Lifecycle Hook mounted () and within that I'm going to call a this.getEntries() method.

I then need to declare that method. Putting it all together I have

Now, if I pop open Vue dev tools, I should be able to drill down to my JobList component and see that it has a populated array of entries from the API.

Next I need to loop over that array in the Vue template.

I should now see a ton of entries coming back in the browser in a simple unordered list πŸ€™πŸ»

You could of course return any of the other fields you want inside the v-for loop. However, I'd rather have a reusable Job component, but I'll leave it where it is for now.