npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gridsome-source-storyblok

v2.0.0

Published

Storyblok source for Gridsome with live preview editor

Downloads

85

Readme

Gridsome Source Storyblok

The official Storyblok integration with Gridsome.

To see it in action take a look at the Storyblok Gridsome Boilerplate.

Version Downloads Stars Status

Install

yarn add gridsome-source-storyblok # or npm install gridsome-source-storyblok

Usage

  1. In gridsome.config.js, declare the use of the plugin and define the options:
// in gridsome.config.js
{
  siteName: 'Gridsome',
  plugins: [
    {
      use: 'gridsome-source-storyblok',
      options: {
        client: {
          accessToken: '<YOUR_ACCESS_TOKEN>'
        },
        types: {
          story: {
            typeName: 'StoryblokEntry'
          }
        }
      }
    }
  ]
}
  1. In the src/templates folder create a .vue file with the same name you defined in the typeName option (default is StoryblokEntry). After that set a <page-query> tag to load the data from GraphQL. For example:
<page-query>
query StoryblokEntry ($id: ID) {
  storyblokEntry (id: $id) {
    id
    slug
    content
  }
}
</page-query>
  1. Edit the file gridsome.server.js to use a GraphQL query to generate the pages using Storyblok's full_slug attribute
module.exports = function (api) {
  api.createPages(async ({ graphql, createPage }) => {
    const { data } = await graphql(`{
      allStoryblokEntry {
        edges {
          node {
            id
            full_slug
          }
        }
      }
    }`)

    data.allStoryblokEntry.edges.forEach(({ node }) => {
      createPage({
        path: `/${node.full_slug}`,
        component: './src/templates/StoryblokEntry.vue',
        context: {
          id: node.id
        }
      })
    })
  })
}

The options object in details

When you declare the use of the Storyblok plugin you can pass following options:

{
  use: 'gridsome-source-storyblok',
  options: {
    client: {
      // The Storyblok JS Client options here (https://github.com/storyblok/storyblok-js-client)
      accessToken: '<YOUR_ACCESS_TOKEN>' // required!
    },
    version: 'draft', // Optional. Can be draft or published (default draft)
    // Optional: Config story and tag types names and request calls
    types: {
      story: {
        name: 'StoryblokEntry', // The name of Story template and type (default StoryblokEntry)
        params: {} // Additional query parameters
      },
      tag: {
        name: 'StoryblokTag', // The name of Tag template and type (default StoryblokTag)
        params: {} // Additional query parameters
      }
    },
    downloadImages: true, // Optional. default false,
    imageDirectory: 'storyblok_images', // Optional. Folder to put the downloaded images
    // Optional: Get additional types like datasources, links or datasource_entries
    additionalTypes: [
      {
        type: 'datasources', // required
        name: 'StoryblokDatasource' // required
      },
      {
        type: 'datasource_entries',
        name: 'StoryblokDatasourceEntry',
        params: { ...additionalQueryParams } // optional
      },
      {
        type: 'links',
        name: 'StoryblokLink'
      }
    ]
  }
}

Rendering of the Rich Text field

This plugin comes with a built in renderer to get html output from Storyblok's Rich Text field. Create and register a Richtext.vue component with the code below to use the renderer in your components like this: <richtext :text="blok.richtext"></richtext>.

<template>
  <div>
    <div v-html="richtext"></div>
  </div>
</template>

<script>
export default {
  props: ['text'],
  computed: {
    richtext() {
      return this.text ? this.$storyapi.richTextResolver.render(this.text) : ''
    }
  }
}
</script>

Downloading images

When downloadImages option is marked as true, this plugin will be searching in each story for a image and download it to src/<imageDirectory> folder. In your components, you can use the g-image tag. An important thing is that image property in story will be a object with some fields, not a string. Bellow, we show you an example of this:

<template>
  <div>
    <g-image :src="imageURL"></g-image>
  </div>
</template>

<script>
export default {
  props: ['blok'],
  computed: {
    imageURL () {
      // When options.downloadImages is false, the image property is a string
      if (typeof this.blok.image === 'string') {
        return this.blok.image
      }

      // When options.downloadImages is true, the image property is a object
      // Reference of this: https://github.com/gridsome/gridsome/issues/292
      const path = this.blok.image.path
      return require('!!assets-loader?width=800&quality=100&fit=inside!~/' + path)
    }
  }
}
</script>

<style scoped>
img {
  max-width: 100%;
}
</style>

Working with Tags

By default, this plugin will get all tags and create a reference to stories entries (as described in create-schema function), so it's possible to list stories from tag, for example.

You can change the name of template file and types by setting the options.types.tag.name option in gridsome.config.js (StoryblokTag is default).

Example

Create a StoryblokTag.vue file in src/templates folder with the following code:

<template>
  <Layout>
    <h1>{{ $page.storyblokTag.name }}</h1>
    <ul>
      <li v-for="edge in $page.storyblokTag.belongsTo.edges" :key="edge.node.id">
        <g-link :to="edge.node.full_slug">
          {{ edge.node.name }}
        </g-link>
      </li>
    </ul>
  </Layout>
</template>

<page-query>
query ($id: ID!) {
  storyblokTag(id: $id) {
    name
    belongsTo {
      edges {
        node {
          ... on StoryblokEntry {
            id
            full_slug
            name
          }
        }
      }
    }
  }
}
</page-query>

In your gridsome.server.js file, it will be necessary to create a pages for each tag as the following:

module.exports = function (api) {
  api.createPages(async ({ graphql, createPage }) => {
    // previous code (create pages to stories)

    const { data: tagData } = await graphql(`{
      allStoryblokTag {
        edges {
          node {
            id
            name
          }
        }
      }
    }`)

    tagData.allStoryblokTag.edges.forEach(({ node }) => {
      createPage({
        path: `/tag/${node.name}`,
        component: './src/templates/StoryblokTag.vue',
        context: {
          id: node.id
        }
      })
    })
  })
})

That's all! In your browser you can view a list of stories by the foo tag in http://localhost:8080/tag/foo.

Load data to different collections

To load data to multiple collections, you need to declare the configuration multiple times in gridsome.config.js. Like this:

{
  siteName: 'Gridsome',
  plugins: [
    // default collection
    {
      use: 'gridsome-source-storyblok',
      options: {
        client: {
          accessToken: '<YOUR_ACCESS_TOKEN>'
        }
      }
    },

    // specific collection (blogging for example)
    {
      use: 'gridsome-source-storyblok',
      options: {
        client: {
          accessToken: '<YOUR_ACCESS_TOKEN>'
        },
        types: {
          story: {
            name: 'StoryblokBlogEntry',
            params: {
              starts_with: 'blog/'
            }
          },
          tag: {
            typeName: 'StoryblokBlogTag'
          }
        }
      }
    }
  ]
}

And, in your gridsome.server.js, you can generate your pages for each collection, attending to the name given to each collection.

Get Space informations

It is possible to get the space informations using the GraphQL Data Layer. The space information will be storage in Gridsome's global metadata, so, it will be avaialable for your entire project.

To get the space informations, you can set this following query in your <static-query> in your vue component:

query {
  metadata {
    storyblokSpace {
      id
      name
      version
      language_codes
    }
  }
}

Contribution

Fork me on Github.

This project use semantic-release for generate new versions by using commit messages and we use the Angular Convention to naming the commits. Check this question about it in semantic-release FAQ.