loading...
Cover image for Integrating ButterCMS in your Vue application

Integrating ButterCMS in your Vue application

easyaspython profile image Dane Hillard Originally published at dane.engineering ・3 min read

This post originally appeared on dane.engineering.


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 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:

<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>
Enter fullscreen mode Exit fullscreen mode

The code for displaying a single post is much the sameβ€”a data property contains information about the post and we can fetch the post as the component is created:

<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>
Enter fullscreen mode Exit fullscreen mode

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 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:

import Butter from 'buttercms'

const butter = Butter('YOUR API KEY')
Vue.prototype.$butter = butter
Enter fullscreen mode Exit fullscreen mode

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


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

Discussion

pic
Editor guide
Collapse
silverman42 profile image
Sylvester Nkeze

Simple and precise. For someone like me hoping to develop my JAM stack blog site with Nuxtjs, this is a huge deal for me. Thanks Dane

Collapse
easyaspython profile image
Dane Hillard Author

I'm really glad to hear that Sylvester! I was in the exact same boat so I hoped this would resonate with others too. Hope it goes well!