A Modern Site Generator for Vue.js

Who I am? 👩🏻‍💻💪🏻💻

 

Maria Fernana Serna Arboleda

Co-Organizer MedellinJS

 

https://mafe.dev  💻

Javascript Developer 🤓

¿Static vs Dynamic?

A static website contains Web pages with fixed content. Each page is coded in HTMLand displays the same information to every visitor.

A Dynamic website is a collection of dynamic web pages whose content changes dynamically. It accesses content from a database or Content Management System (CMS).

¿What is JAMstack?

¿Why?

  • Better Performace

  • Higher Security

  • Cheaper, Easier Scaling

  • Better Developer Experience

JavaScript

Any dynamic programming during the request/response cycle is handled by JavaScript, running entirely on the client.

APIs

All server-side processes or database actions are abstracted into reusable APIs, accessed over HTTPS with JavaScript

Markup

Templated markup should be prebuilt at deploy time, usually using a site generator for content sites, or a build tool for web apps.

¿ What is Gridsome ?

Gridsome is a modern website development framework for creating fast and secure websites that can be deployed anywhere. Static HTML files are generated to create SEO-friendly markup that hydrates into a Vue.js-powered SPA once loaded in the browser.

Bring your data

Build

Deploy

CMS: Any Headless CMS, Contentful, WordPress, Drupal, Sanity.io, etc.

Data: Any APIs, Databases, AirTable, YAML, CSV, JSON, etc.

Markdown: Any Git-based CMS, Forestry, Netlify CMS, Blogs, Documentation.

Centralized data management
powered by GraphQL

Static Web Hosts & CDNs

Netlify, AWS Amplify, Zeit Now, Amazon S3, Surge.sh, Aerobatic, Now.sh & many more.

How does Gridsome work

How to install

1. Install the Gridsome CLI tool

2. Create a Gridsome project

3. Start the local dev server

yarn global add @gridsome/cli​
gridsome create my-gridsome-site
gridsome develop

Open http://localhost:8080

in your browser

.gitignore
package.json
gridsome.config.js
gridsome.server.js
📁dist
📁node_modules
📁src
├─ main.js
├─ 📁layouts
   └─ Default.vue
├─ 📁pages
   ├─ Index.vue
   ├─ AboutUs.vue
   └─ Blog.vue
├─ 📁templates
   └─ BlogPost.vue
📁static

Directory Structure

Recommendations

  • src/assets - global styles, images, fonts and icons
  • src/components - shared .vue components
  • src/data - Data files like .json or .yaml you might import into your components
module.exports = {
  siteName: 'Gridsome',
  siteUrl: 'https://www.gridsome.org',
  plugins: []
}

This is optional and is for using various parts of the Gridsome Server API.

Local GraphQL data layer

Bring your data

Add data with Source plugins

module.exports = {
  plugins: [
    {
      use: '@gridsome/source-contentful',
      options: {
        typeName: 'Contentful',
        space: 'YOUR_SPACE', // required
        accessToken: 'YOUR_ACCESS_TOKEN', // required
        host: 'cdn.contentful.com',
        environment: 'master'
      }
    }
  ]
}

Add data from any APIs

 
module.exports = function (api) {
  api.loadSource(async store => {
    // Fetch data from APIs
    const { data } = await axios.get('https://scrapp-slide.herokuapp.com/api/scrap/find/mafeserna')

    // Create a new GraphQL content type
    const posts = store.addContentType({
      typeName: 'Talks'
    })

    // Add data to the new content type
    data.map((item) => {
      posts.addNode({
        id: item.id,
        url: 'https://slides.com' + item.url,
        slug: item.slug,
        viewCount: item.viewCount,
        imageUrl: item.imageUrl,
        description: item.description
      })
    })
  })
}

Use Markdown for data

 
module.exports = {
  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        path: 'docs/**/*.md',
        typeName: 'DocPage'
      }
    }
  ]
}

The GraphQL Playground

 

https://localhost:8080/___explore

Preview & test queries from the local data layer

Query

Results

Browse

Schema

Build your site with Vue.js

Layouts

<!-- Layout -->
<template>
  <div>
    <header />
    <slot /> <!-- Page content will be inserted here  -->
    <footer />
  </div>
</template>

Layout components are used to wrap pages and templates. Layouts should contain components like headers, footers or sidebars that will be used across the site.

// src/main.js

import Layout from '~/layouts/Default.vue'

export default function (Vue, { head, router, isServer }) {
  Vue.component('Layout', Layout)
}

Layout Global

Routes  &  Pages 

<template>
  <Layout>
    <h1>About us!</h1>
  </Layout>
</template>

<style>
  h1 { font-size: 32px }
</style>

<script>
export default {
  metaInfo: {
    title: 'About us'
  }
}
</script>
src/pages/About.vue
https://website.com/about

All .vue files in the src/pages directory will become the pages for your website. The page URL is generated based on the location and name of the file.

Pages are used for normal pages and for listing & paginating GraphQL collections.

<template>
  <Layout>
    <h1>My blog</h1>
    <div v-for="edge in $page.talks.edges" :key="node.id">
       <h3>{{ node.slug }}</h3>
       <g-link :to="node.id">Read more</g-link>
    </div>
  </Layout>
</template>


<page-query>
query Talks {
  talks: allTalks {
    edges {
      node { 
        id
        imageUrl
        slug
        url
      }
    }
  }
}
</page-query>

Query from GraphQL data layer

Templates

<template>
  <Layout>
    <h1 v-html="$page.post.title" />
    <div v-html="$page.post.content" />
  </Layout>
</template>

<page-query>
query Post ($id: String!) {
  post: contenfulPost (id: $id) {
    title
    content
  }
}
</page-query>

<script>
export default {
  metaInfo () {
    return {
      title: this.$page.post.title
    }
  }
}
</script>

Templates are used for single post views to GraphQL collections.

/blog

/blog/:slug (dynamic)

Components

<template>
  <div class="card">
    {{ message }}
    <button @click="onClick">
      Change
    </button>
  </div>
</template>

<script>
export default {
  name: 'Card',
  data () {
    return {
      message: 'Try change me!'
    }
  },
  methods: {
    onClick () {
      this.message = 'Here you go :)'
    }
  }
}
</script>

<style>
.card {
  padding: 20px;
  background: #FFF;
}
</style>

Gridsome uses Vue Single File Components. This means you add HTML, JavaScript and CSS in the same file. This makes your projects easier to maintain and test and your components more reusable.

<template>
  <Card />
</template>

<script>
import Card from '~/components/Card.vue'

export default {
  components: {
    Card
  }
}
</script>

Smart link prefetching with <g-link>

<!-- Link with string path -->
<g-link to="/about">About us</g-link>

<!-- Link with variable path -->
<g-link :to="node.path">Read more</g-link>

<g-link> uses Intersection Observer to prefetch linked pages when link is in view. This makes browsing around very fast because the clicked page is already downloaded.

Progressive Images with <g-image>

<g-image src="~/image.png" width="500" height="300" />

<g-image> automatically generates an ultra-compressed blurred Base64 image by default and lazy loads the proper image when it's in view.

<g-image> lets you set width, height, and quality in real-time when in development mode, so what you set is what you get.

Deploy your site

To deploy a Gridsome site you need a static web host.

Git-based deploying

Deploy from terminal

FTP deploying

Drag & drop deploying

  • Netfly Drop

🚀

  • Amazon S3
  • Zeit Now
  • Netfly
  • Aws Amplify
  • Zeit Now
  • GitLab Pages

Fast by Default 🏃🏻‍♀️

Smart link prefetching that uses Intersection Observer to load next pages.

Code Splitting. Only what you need is loaded per page.

Pre-rendered HTML. Nothing beats static HTML on a CDN in speed.

Progressive Images with automatic image compression and lazy loading.

Vue.js SPA Hydration for fast browsing with no page refresh.

Make website building fun again

 

No need to be a performance expert.

Centralized data management.

Build on the JAMstack 💚

Thanks 💚

 

👩🏻‍💻

mafe.dev

Made with Slides.com