DEV Community

John Samuel
John Samuel

Posted on

Creating a JAMstack blog using Contentful and Nuxt with fetch()

Sarah Drasner (@sarah_edo ) recently posted a great tutorial on how to build a blog with Nuxt and Contentful hosted on Netlify. Sarah is a great teacher and I have learned a lot from her tutorials. I used this tutorial to build a quick blog and it was super easy.

In the tutorial, she uses Vuex to store the blog posts for the summary page and the individual dynamic blog pages. However, I noticed that in the 2.12 release of Nuxt, they updated how the fetch() method works (there is a great blog post on their site that explains all the details). Using this updated method makes building a blog even easier --- and you don't have to involve Vuex at all.

In Sarah's tutorial, she created an action in her Vuex store like this...

export const actions = {
 async getPosts({ commit }) {
   try {
     if (!client) return;
     const response = await client.getEntries({
       content_type: "blogPost"
     });
     if (response.items.length > 0) commit("updatePosts", response.items);
   } catch (err) {
     console.error(err);
   }
 }
};

But with the new fetch method, you can move this logic into a Vue component as follows...

<script>
import cms from "~/plugins/contentful"

export default {
  async fetch() {
    try {
      if (!cms) return
      const response = await cms.getEntries({
        content_type: "blog"
      })
      if (response.items.length > 0) this.posts = response.items
    } catch (err) {
      console.error(err)
    }
  },
  ...

Similarly, you can use fetch in the dynamic post component as follows...

import cms from "~/plugins/contentful"
export default {
  async fetch() {
    try {
      if (!cms) return
      const response = await cms.getEntries({
        content_type: "blog",
        "fields.slug[in]": this.$route.params.slug
      })
      if (response.items.length > 0) this.post = response.items[0].fields
    } catch (err) {
      console.error(err)
    }
  },
  ...

Notice, since I don't have access to the post id, I grab the posts that match the slug in the params and use the first (and only) item in the returned array.

One of the nice features of this fetch method is that it exposes a $fetchState object with three useful keys...

$fetchState = {
  pending: true | false,
  error: null | {},
  timestamp: Integer
};

For example, you can add some conditional logic in your Vue template to show while the posts are being fetched from Contentful...

<p v-if="$fetchState.pending">Fetching posts...</p>

I'm really enjoying building things with this combination of Nuxt, Contentful and Netlify (I also use TailwindCSS for styling). And this new fetch() method makes Nuxt even easier to use with third-party data sources.

Hope this helps!

Top comments (0)