reinoldus / storyblok-nuxt-2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Storyblok Logo

@storyblok/nuxt-2

Nuxt 2 module for the Storyblok, Headless CMS.


Storyblok JS Client npm

Follow @Storyblok
Follow @Storyblok

Live Demo

If you are in a hurry, check out our official live demo on Stackblitz.

🚀 Usage

Note: This module is for Nuxt 2. Check out @storyblok/nuxt for Nuxt 3.

If you are first-time user of the Storyblok, read the Getting Started guide to get a project ready in less than 5 minutes.

Installation

Install @storyblok/nuxt-2:

npm install @storyblok/nuxt-2
# yarn add @storyblok/nuxt-2

Initialize the module by adding it to buildModules section of nuxt.config.js and replace the accessToken with API token from Storyblok space:

{
  buildModules: [
    // ...
    ["@storyblok/nuxt-2/module", { accessToken: "<your-access-token>" }],
  ];
}

Options

When you initialize the module, you can pass all @storyblok/vue-2 options plus a useApiClient option.

For spaces created in the United States, you have to set the region parameter accordingly { apiOptions: { region: 'us' } }.

// Defaults
[
  "@storyblok/nuxt-2/module",
  {
    accessToken: "<your-access-token>",
    bridge: true,
    apiOptions: {
      // storyblok-js-client options
      // cache: { type: "memory" },
      // region: 'us'
    },
    useApiClient: true,
  },
];

Getting started

1. Creating and linking your components to Storyblok Visual Editor

To link your Vue components to their equivalent you created in Storyblok:

  • First, you need to load them globally. If you use Nuxt 2.13+, you can just place them on the ~/components/storyblok directory, otherwise you can load them globally (for example, by using a Nuxt plugin).

  • For each components, use the v-editable directive on its root element, passing the blok property that they receive:

<div v-editable="blok" / >
  • Finally, use <StoryblokComponent> which available globally in the Nuxt app:
<StoryblokComponent blok="blok" />

The blok is the actual blok data coming from Storblok's Content Delivery API.

2. Getting Storyblok Stories and listen to Visual Editor events

Composition API without @nuxtjs/composition-api

You don't need to install @nuxtjs/composition-api if you're in the latest versions of Nuxt 2, as it comes with Vue 2.7 with Composition API support out of the box.

The simplest way is by using the useStoryblok one-liner composable:

<script setup>
  import { useStoryblok } from "@storyblok/nuxt-2";
  const { story, fetchState } = useStoryblok("vue", { version: "draft" });
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>

Composition API with @nuxtjs/composition-api

Use Nuxt 2 with the Composition API plugin installed: @nuxtjs/composition-api.

The simplest way is by using the useStoryblok one-liner composable, which uses the useFetch from @nuxtjs/composition-api under the hood:

<script setup>
  import { useStoryblok } from "@storyblok/nuxt-2";
  const { story, fetchState } = useStoryblok("vue", { version: "draft" });
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>

Which is the short-hand equivalent to using useStoryblokApi and useStoryblokBridge functions separately:

<script setup>
  import { onMounted, ref, useFetch } from "@nuxtjs/composition-api";
  import { useStoryblokBridge, useStoryblokApi } from "@storyblok/nuxt-2";

  const story = ref(null);

  const { fetch } = useFetch(async () => {
    const storyblokApi = useStoryblokApi();
    const { data } = await storyblokApi.get(`cdn/stories/vue/test`, {
      version: "draft",
    });
    story.value = data.story;
  });
  fetch();

  onMounted(async () => {
    if (story.value && story.value.id)
      useStoryblokBridge(story.value.id, (evStory) => (story.value = evStory));
  });
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>

Options API

You can still use the useStoryblokApi and useStoryblokBridge as follows:

<script>
  import { useStoryblokBridge, useStoryblokApi } from "@storyblok/nuxt-2";

  export default {
    asyncData: async ({ app }) => {
      const storyblokApi = useStoryblokApi();
      const { data } = await storyblokApi.get("cdn/stories/vue", {
        version: "draft",
      });
      // OR: const { data } = await app.$storyapi.get("cdn/stories/vue", { version: "draft" });

      return { story: data.story };
    },
    mounted() {
      useStoryblokBridge(this.story.id, (newStory) => (this.story = newStory));
    },
  };
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>

As you see in the comment, you can also use app.$storyapi if that's more comfortable for you. It's injected into Nuxt context and available in the components instance via this.$storyapi as well.

Rendering Rich Text

You can easily render rich text by using the renderRichText function that comes with @storyblok/nuxt-2 and a Vue computed property:

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

<script setup>
  import { computed } from "@nuxtjs/composition-api";
  import { renderRichText } from "@storyblok/nuxt-2";

  const articleContent = computed(() => renderRichText(blok.articleContent));
</script>

You can also set a custom Schema and component resolver by passing the options as the second parameter of the renderRichText function:

<script setup>
  import { computed } from "vue";
  import { renderRichText, RichTextSchema } from "@storyblok/nuxt-2";
  import cloneDeep from "clone-deep";

  const props = defineProps({ blok: Object });

  const mySchema = cloneDeep(RichTextSchema); // you can make a copy of the default RichTextSchema
  // ... and edit the nodes and marks, or add your own.
  // Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/v4/source/schema.js

  const articleContent = computed(() =>
    renderRichText(props.blok.articleContent, {
      schema: mySchema,
      resolver: (component, blok) => {
        switch (component) {
          case "my-custom-component":
            return `<div class="my-component-class">${blok.text}</div>`;
          default:
            return "Resolver not defined";
        }
      },
    })
  );
</script>

API

useStoryblok(slug, apiOptions, bridgeOptions)

Check the available apiOptions (passed to storyblok-js-client) and bridgeOptions (passed to the Storyblok Bridge).

useStoryblokApi()

Returns the instance of the storyblok-js-client.

useStoryblokBridge(storyId, callback, bridgeOptions)

Use this one-line function to cover the most common use case: updating the story when any kind of change happens on Storyblok Visual Editor.

$storyapi

Equivalent to the client that useStoryblokApi returns, but accessible in the Nuxt context and components instance.

🔗 Related Links

ℹ️ More Resources

Support

Contributing

Please see our contributing guidelines and our code of conduct. 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.

About


Languages

Language:JavaScript 72.6%Language:Vue 26.0%Language:Shell 1.4%