Telerik blogs
VueT Dark_870x220

Enter the world of static site generation and the JAMstack using Gridsome. Learn to build a blog using Markdown and GraphQL, and then deploy it to Netlify.

The web is ever evolving and the need to stay updated as developers is really important. In this article, I’ll be introducing you to the world of static site generation and the JAMstack using Gridsome. At the end of the article we’ll build a blog using Markdown as the generated content and GraphQL to query posts that will be displayed on the pages, and then we’ll see how to deploy it to Netlify.

Static Site Generators are part of a new hybrid approach to web development that allows you to build a powerful website locally on your computer but pre-builds the site into static files for deployment. JAMstack is a new way of building websites and applications that delivers better performance, higher security, lower cost of scaling and better developer experience.

Table of Contents:

  1. Introduction to Gridsome
  2. Prerequisites
  3. Setting up Gridsome Project
  4. Building A Blog With Gridsome
  5. Creating the Page Layout
  6. Displaying the Post Layout
  7. Deploying Blog To Netlify
  8. Conclusion

Gridsome official website

Introducing Gridsome

Gridsome is a Vue.js-powered static site generator for creating fast and secure websites that can be deployed anywhere. It makes it easy for developers to build modern JAMstack websites.

Gridsome comes bundled with some features that are hard to miss, and this makes it one of the most sought-after static site generators out there. Some of these features include:

  • Local development with Hot Reloading - See changes in real-time while developing.
  • Write Vue.js Code - A lightweight and approachable frontend framework.
  • GraphQL data layer - Centralized data management for all your data.
  • Automatic page routing - Quickly create and manage pages with files.
  • Progressive image support - Auto resize, optimize & lazy load images.
  • Auto page prefetching - Pages are loaded in the background for fast browsing.
  • Auto-optimized code - Get code-splitting and asset optimization out-of-the-box.
  • Fast static page generating - Deploy securely and fast to any Static Web Host.
  • Data source plugins - Add data from popular Headless CMSs, APIs or Markdown files.

Prerequisites

In order to follow through with this tutorial, You should have a basic knowledge of the following:

Setting Up a Gridsome Project

We’ll need to set up a new Gridsome project, and to do so we’ll be required to run the following commands.

For the first step, install the Gridsome CLI on your computer using npm or yarn.

$ npm install --global @gridsome/cli or
$ yarn global add @gridsome/cli

The next step after installing the CLI is to go ahead and create a new project called Telerik-blog and run the project.

// create a new gridsome project
$ gridsome create telerik-blog
$ cd telerik-blog
$ gridsome develop

After running these commands, your local dev server should be running at http://localhost:8080 with the sample page displayed below.

The Page is shown after creating a project

If we try to change anything on this layout page then we’ll see that it automatically changes what we have on the screen. This is as a result of Gridsome Hot Reloading feature we talked about earlier.

Building Out a Blog with Gridsome

We’ll get started by describing what we are trying to achieve with the blog — we’ll have a single page with a list of posts and have each post with content in Markdown. In order to achieve this, we’ll need to install a Gridsome Plugin called gridsome/source-filesystem that helps transform files into content that can be fetched with GraphQL in your components. Go ahead and install the package using this command:

yarn add @gridsome/source-filesystem or 
npm install @gridsome/source-filesystem

and configure it within the gridsome.config.js file:

module.exports = {
  siteName: 'Gridsome Blog',
  siteDescription: 'A simple blog designed with Gridsome',
  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        path: 'content/posts/**/*.md',
        typeName: 'Post',
        route: '/blog/:slug'
      }
    }
  ]
}

The configuration above is what we need to set up the source-filesystem plugin. The options set here:

  • Path: the location of the markdown content we’ll be consuming in the posts.
  • typeName: The GraphQL type and template name. A .vue file in src/templates must match the typeName to have a template for it.
  • route: This is the route every post will follow i.e localhost:8080/blog/new-post

Now that we have that set up, we can create a content/posts folder. This is where all markdown content for our blog will be stored. We also want to include syntax highlight to our blog.

The @gridsome/remark-prismjs plugin adds that to code blocks. We can set it within the gridsome.config.js:

yarn add @gridsome/remark-prismjs or 
npm install @gridsome/remark-prismjs 

Then go ahead to main.js and import prismjs CSS Theme.

import 'prismjs/themes/prism.css'


export default function (Vue) {
  // ...
}

In gridsome.config.js, add syntax highlighter to all markdown sources:

transformers: {
   //Add markdown support to all file-system sources
   remark: {
     externalLinksTarget: '_blank',
     externalLinksRel: ['nofollow', 'noopener', 'noreferrer'],
     plugins: [
       '@gridsome/remark-prismjs'
     ]
   }
},

Gridsome uses Layouts as a wrapper for pages and templates. Layouts contain components like header, footer or sidebars, etc. and a slot component where content coming from pages and templates is inserted.

<template>
  <div class="layout">
    <slot/> <!-- Page/Template will be inserted here -->
    <div class="footer">
      <p>
        Built with
        <a class="link" href="//gridsome.org">Gridsome</a>
        & Made with ❤️ by
        <a class="link" href="//twitter.com/lauragift21">Gift Egwuenu</a>
      </p>
    </div>
  </div>
</template>

The above code block is our Default.vue component. The styling for the blog is populated in the style tag. We can find more details about the styling used in the GitHub Repo.

<style>
  body {
    font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto,
      "Helvetica Neue", Arial, sans-serif;
    margin: 0;
    padding: 0;
    line-height: 1.5;
    border: 15px solid #fecd43;
    min-height: 100vh;
  }
  
  .layout {
    max-width: 760px;
    margin: 0 auto;
    padding-left: 20px;
    padding-right: 20px;
  }
  
  .footer {
    padding-top: calc(30em / 4);
    text-align: center;
    font-size: 1em;
  }
  
  .link {
    border: 2px dashed #fecd43;
    padding: 7px;
    color: #333;
    text-decoration: none;
  }
</style>

Creating the Page Layout

The Page layout will be where all the blog posts are listed and also will serve as the homepage. In Gridsome, Pages are used for normal pages and for listing & paginate GraphQL collections. In this case our blog posts is the collection. The page URL is generated based on the location and name of the file. As an example, if we create a file within the pages directory and name it Index.vue, it will be treated as index.html, which is the home page. The same applies if we create a file and call it About.vue — it’ll be treated as about.html and will be linked as /about. That is how routing works in Pages. Because we only want to display all posts in a single page, we can go ahead and create Index.vue file, or if we have one generated for us already then we can use that.

Our Index.vue should look like this:

<template>
  <Layout>
    <header class="header">
      <h1>Gridsome Blog</h1>
      <p>A simple blog designed with Gridsome</p>
    </header>
  </Layout>
</template>

And with that, we should have this page when we navigate to the homepage.

Blog page

Now that we have the homepage, we can go ahead and create a list of blog posts and display that on the page. We can create a PostList.vue file within the components directory, in which we’ll create the layout for displaying a list of post for our blog.

<template>
  <div class="post-list">
    <hr class="line" />
    <p class="date" v-html="post.date" />
    <h1 class="title" v-html="post.title" />
    <p class="description" v-html="post.description" />
    <b> {{post.timeToRead}} min read </b>  &nbsp
    <g-link :to="post.path" class="read">Read More...</g-link>
  </div>
</template>

<script>
export default {
  props: ["post"],
};
</script>

Within this file, we have content for displaying a list of posts and we are also adding a post props that enable us to pass data from the parent component down to the PostList child component.

Head back to the Index.vue within the Pages directory. Remember I previously mentioned Gridsome has a centralized data management for all your data, which in our case is GraphQL. It uses <page-query> and <static-query> to fetch data into pages, template and components. Here we need to pull all posts we have in our content directory written in Markdown and display them within our Vue component.

<page-query>
query {
  allPost {
    totalCount
    edges {
      node {
        id
        title
        timeToRead
        description
        date (format: "D MMMM YYYY")
        path
      }
    }
  }
}
</page-query>

Now, we have the content in the Vue component we can pass them to the PostList.vue component like this:

<section class="posts">
  <PostList v-for="edge in $page.allPost.edges" :key="edge.node.id" :post="edge.node" />
</section>

Blog post list

Displaying the Post Layout

Now we have a list of posts from the content folder displayed. The next step is to display a single post when one of these posts is clicked. We’ll be using a template to handle this. In Gridsome, a Template is used for displaying a single post view to GraphQL collections. Add a Post.vue file within the templates directory with the following content.

<template>
  <Layout>
    <br>
    <g-link to="/" class="link">  &larr; Go Back</g-link>
    <div class="post-title">
      <h1>{{$page.post.title}}</h1>
        <p class="post-date"> {{ $page.post.date}} | {{$page.post.timeToRead}} min read 
      </p>
    </div>
    <div class="post-content">
      <p v-html="$page.post.content" />
    </div>
  </Layout>
</template>

And to query the content of a single post, we’ll be using a page-query with the following:

<page-query>
query Post ($path: String!) {
   post: post (path: $path) {
    id
    title
    content
    date (format: "D MMMM YYYY")
    timeToRead
  }
}
</page-query>

With that done, when you click on read more on the homepage, you should see the content of a single post displayed with a slug using the post title like we configured in gridsome.config.js.

single post

Deploying Blog with Netlify

Our blog is complete! The next step is to deploy, and for this we’ll be using Netlify. Head over to Netlify website and create a new site. Make sure you have your codebase on GitHub. You can find the Repo for this project on GitHub. The next step is to add the following configuration.

Netlify deploy: Set Publish directory to dist.

After creating a new site on Netlify we’ll be prompted with a modal to configure our site. Go ahead and setup the branch to deploy as master and the build configurations should be gridsome build as the command and dist as the publish directory. After we’ve done that we can then click on deploy site and we’ll have our site deployed with a URL to visit in no time. The URL for this project can be found here.

Conclusion

In this article, we have demonstrated how to build a blog in Vue.js using Gridsome and Markdown. You can see it can be pretty straightforward to implement and in no time you have a personal blog running. Feel free to check out the GitHub Repo and Gridsome Documentation to learn more.


This blog has been brought to you by Kendo UI

Want to learn more about creating great web apps? It all starts out with Kendo UI - the complete UI component library that allows you to quickly build high-quality, responsive apps. It includes everything you need, from grids and charts to dropdowns and gauges.

KendoJSft


Gift Egwuenu
About the Author

Gift Egwuenu

Gift Egwuenu is a developer advocate and technical educator with more than five years of experience in the web development industry. She has a passion for building tools and products that help businesses grow. She enjoys sharing her knowledge and experience through speaking engagements, writing and other educational initiatives. Gift's areas of expertise include web development, JAMstack and career advancement, and she is dedicated to helping others improve their skills and succeed in the tech industry. Gift enjoys reading, cooking and traveling when she is not working.

Related Posts

Comments

Comments are disabled in preview mode.