Integrating ButterCMS in your Vue application
Tags: vue, headless, cms, webdev
Published: 2019-02-05 22:52:42

---
title: Integrating ButterCMS in your Vue application
published: true
description: Learn how easy the headless CMS platform ButterCMS is to get up and running in an existing Vue.js application
tags: vue,headless,cms,webdev
canonical_url: https://dane.engineering/post/buttercms-in-vue/
cover_image: https://d2wzhk7xhrnk1x.cloudfront.net/rgPM9aHoSSKnjk44TQlD_butter-blog-post.jpg
---

This post originally appeared on [dane.engineering](https://dane.engineering/post/buttercms-in-vue/).

<hr />

Although sites like Medium provide audience reach and a consistent experience, the list of reasons I'm no longer happy with it keeps growing. I've done most of my recent writing here on dev.to, which has been a refreshing change!

I decided to take my maiden voyage into headless CMS, and I've chosen [ButterCMS](https://buttercms.com) for the moment. Its small but focused API was plenty for me to get my blog up and running! Best of all, it's free for non-commercial use.

Right after you sign up with Butter, you'll get an API key and links to an impressive array of framework-specific instructions for how to get set up. I found the instructions for Vue very easy to follow, and was able to go from signing up to retrieving the test blog post within 15 minutes or so! I'm using single-file components (SFCs) in my app, so I started by grabbing a list of blog posts and creating the template together. Butter returns a `data` property that contains the list of posts, each of which has a title, slug, body, and so on. We can fetch these when the `BlogPostList` component is created, so that the data becomes available around the time it mounts. I also put in a loading state for the rare occasion where the API response takes a noticeable amount of time:

```html
<template>
  <main>
    <h1>Posts</h1>
    <span v-if="loading">Loading...</span>
    <ul v-else-if="posts.data.length">
      <li v-for="post in posts.data" :key="post.slug">
        <router-link :to="{ name: 'post', params: { slug: post.slug } }">
          {{ post.title }}
        </router-link>
      </li>
    </ul>
  </main>
</template>

<script>
import Butter from 'buttercms'

const butter = Butter('YOUR API KEY')

export default {
  name: 'BlogPostList',
  data () {
    return {
      loading: true,
      posts: {},
    }
  },
  methods: {
    fetchPosts () {
      butter.post.list({ page: 1, pageSize: 10 })
        .then((response) => {
          this.loading = false
          this.posts = response.data
        }).catch((response) => {
          console.log(response)
        })
    },
  },
  created () {
    this.fetchPosts()
  },
}
</script>
```

The code for displaying a single post is much the same&mdash;a `data` property contains information about the post and we can fetch the post as the component is created:

```html
<template>
  <main>
    <article v-if="post.data">
      <h1>{{ post.data.title }}</h1>
      <span class="metadata">{{ publishedDate }}</span>
      <div v-html="post.data.body" />
    </article>
  </main>
</template>

<script>
import Butter from 'buttercms'

const butter = Butter('YOUR API KEY')

export default {
  name: 'BlogPost',
  data () {
    return {
      loading: true,
      post: {},
    }
  },
  methods: {
    fetchPost () {
      butter.post.retrieve(this.$route.params.slug)
        .then((response) => {
          this.loading = false
          this.post = response.data
        }).catch((response) => {
          console.log(response)
        })
    },
  },
  created () {
    this.fetchPost()
  },
}
</script>
```

This is about all you need in order to start fetching a list of posts and rendering each post! The rest of the work is in dropping all the SEO into place (I use [`vue-meta`](https://github.com/nuxt/vue-meta) for this) and styling the content as you wish. One additional thing I did to make using Butter easier throughout my Vue app was adding it to the Vue prototype:

```javascript
import Butter from 'buttercms'

const butter = Butter('YOUR API KEY')
Vue.prototype.$butter = butter
```

Then I can just type `this.$butter` in a component's methods instead of initializing the API client each time.

<hr />

The features I like about butter so far are:

* The easy-to-use API and corresponding JavaScript client
* The small amount of time it took to get started
* The image API they provide (through Filestack)

The features that could use some work are:

* Adding code blocks to your posts: it's way nicer than Medium, but not as good an experience in the WYSIWYG as other more basic things
* Terminology: this isn't unique to Butter; a CMS can be complex so it's difficult to distinguish all the concepts you can configure, create, and customize