DEV Community

loading...
Cover image for Creating a blog with NuxtJS and Netlify CMS - 2

Creating a blog with NuxtJS and Netlify CMS - 2

Ishaan Sheikh
Software Engineer with a passion for building things 💻🤓
Originally published at frikishaan.com Updated on ・2 min read

In the first part of this series, we learned How to set up a blog using Netlify CMS. In this part, we'll see how to integrate the content with the NuxtJS frontend.

Setting up Vuex store to collect data

In your store directory create a file named index.js and add the following content to it.

export const state = () => ({
  blogPosts: []
});

export const mutations = {
  setBlogPosts(state, list) {
    state.blogPosts = list;
  }
};

export const actions = {
  async nuxtServerInit({ commit }) {
    let files = await require.context(
      "~/assets/content/blog/",
      false,
      /\.json$/
    );
    let blogPosts = files.keys().map(key => {
      let res = files(key);
      res.slug = key.slice(2, -5);
      return res;
    });
    await commit("setBlogPosts", blogPosts);
  }
};

Enter fullscreen mode Exit fullscreen mode

Now we can use the content in our Vue files. To learn more about Vuex store in NuxtJS see this.

To use nuxtServerInit action your mode should be universal in nuxt.config.js

Getting data from Vuex store

In pages/ directory in index.vue file add the following content -

<template>
  <div>
    <h1>Blog Posts</h1>
    <div class="blogs">
      <ul class="blog" v-for="blog in blogPosts" :key="blog.slug">
        <li class="blog__title">
          <nuxt-link :to="`/blog/${blog.slug}`">
            <h2>{{ blog.title }}</h2>
          </nuxt-link>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    // Fetching all posts data
    blogPosts() {
      return this.$store.state.blogPosts;
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Now if you go to your http://localhsot:3000/ you'll see all the blog posts listed there.

Getting a single blog post

Use the following code to get the single blog post

export default {
  // Fetching Single BlogPost
  async asyncData({ params, payload }) {
    if (payload) return { blogPost: payload };
    else
      return {
        blogPost: await require(`~/assets/content/blog/${params.blog}.json`)
      };
  }
};
Enter fullscreen mode Exit fullscreen mode

Now the blogPost variable is available in the template.

<div class="blog">
    <img v-bind:src="blogPost.thumbnail" class="blog__featured-img" />
    <h1 class="blog__title">{{blogPost.title}}</h1>
    <div class="blog__date">{{blogPost.date}}</div>
    <div class="blog__body" v-html="$md.render(blogPost.body)"></div>
  </div>
Enter fullscreen mode Exit fullscreen mode

Since the body contains the markdown, we need to install a package to display the markdown content.

npm install @nuxtjs/markdownit
Enter fullscreen mode Exit fullscreen mode

In your nuxt.config.js add the following line

...
modules: ["@nuxtjs/markdownit"],
...
Enter fullscreen mode Exit fullscreen mode

Generating pages

To render the site as static, you need to add a generate property in your nuxt.config.js

generate: {
    routes: function() {
      const fs = require("fs");
      const path = require("path");
      return fs.readdirSync("./assets/content/blog").map(file => {
        return {
          route: `/blog/${path.parse(file).name}`, // Return the slug
          payload: require(`./assets/content/blog/${file}`)
        };
      });
    }
  },
Enter fullscreen mode Exit fullscreen mode

I have also created a repository to get you started with the NuxtJS blog.

GitHub logo sheikh005 / nuxt-netlify-cms-starter-template

This is a starter files for creating Nuxt.js based blogs using Netlify CMS.

Reference - Netlify CMS Docs

Discussion (6)

Collapse
herrbertling profile image
Markus Siering

You need to check out nuxt/content. Works perfectly with this kind of setup and you can write the posts in markdown :)

Collapse
cguttweb profile image
Chloe

Yeah definitely having come across this I would say the same. I've been playing with nuxt/content module for site idea it's great to be able to write content in markdown. I'm very much a beginner and need to learn more about it but I'm liking it so far just I've a lot of folders in my structure need to try and figure out best why to do it but its been fun. And setting it up with netlifycms was straightforward too.

Collapse
sheikh_ishaan profile image
Ishaan Sheikh Author

Thanks for sharing this.

Collapse
romam88 profile image
Martino Roma

Hello, thank you so much for the syntethic and precise post! I was wondering if you have time to share how to handle categories and category pages.

Collapse
sheikh_ishaan profile image
Ishaan Sheikh Author

Thanks, Martino for reading the post!
In order to handle categories, you have to create a new collection and create a new field with relation type widget (see links) in the blog collection.

....
collections:
  - name: "blog"
    label: "Blog"
    format: "json"
    folder: "assets/content/blog"
    create: true
    slug: "{{slug}}"
    editor:
      preview: true
    fields:
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Publish Date", name: "date", widget: "datetime" }
      - {
          label: "Category",
          name: "category",
          widget: "relation",
          collection: "categories",
          searchFields: ["name"],
          valueField: "name",
          multiple: true,
        }
      - { label: "Body", name: "body", widget: "markdown" }

  - name: "categories"
    label: "Categories"
    folder: "assets/content/category"
    create: true
    slug: "{{slug}}"
    identifier_field: name
    fields:
      - { label: "Name", name: "name", widget: "string" }
      - { label: "Image", name: "image", widget: "image", required: false }
      - { label: "Description", name: "description", widget: "markdown" }
.....

I hope this will help.

Collapse
romam88 profile image
Martino Roma

Great, thanks