使用 Vue & UI Pro 的仪表板模板

storyblok
storyblok

Storyblok Nuxt 模块

Storyblok Logo

@storyblok/nuxt

用于 Storyblok 的 Nuxt 3 模块,无头 CMS。


Storyblok JS Client npm

Follow @Storyblok
Follow @Storyblok

实时演示

如果您时间紧迫,请查看我们在 Stackblitz 上的官方 实时演示

🚀 使用

注意 此模块适用于 Nuxt 3。 查看 @storyblok/nuxt-2 以获取 Nuxt 2.

重要 如果您是 Storyblok 的首次用户,请阅读 入门 指南,以便在不到 5 分钟的时间内准备好项目。

安装

安装 @storyblok/nuxt

npx nuxi@latest module add storyblok

将以下代码添加到 nuxt.config.js 的 modules 部分,并将 accessToken 替换为 Storyblok 空间的 API 令牌。

import { defineNuxtConfig } from "nuxt";

export default defineNuxtConfig({
  modules: [
    ["@storyblok/nuxt", { accessToken: "<your-access-token>" }]
    // ...
  ]
});

您也可以使用 storyblok 配置,如果您更喜欢。

import { defineNuxtConfig } from "nuxt";

export default defineNuxtConfig({
  modules: ["@storyblok/nuxt"],
  storyblok: {
    accessToken: "<your-access-token>"
  }
});

警告 此 SDK 在后台使用 Fetch API。如果您的环境不支持它,您需要安装一个 polyfill,例如 isomorphic-fetch。有关更多信息,请参阅 storyblok-js-client 文档

选项

初始化模块时,您可以传递所有 @storyblok/vue 选项,以及一个 bridge 选项,该选项在我们的 JS SDK Storyblok 桥接部分 中解释,以及一个 enableSudoMode 选项来定义您自己的插件(见下文)。

注意 如果您想在 nuxt-devtools 中使用 Storyblok,您可以使用选项 devtools,如果启用,请确保已安装 @nuxt/devtools 模块并在您的 nuxt 配置中启用它。

// Defaults
["@storyblok/nuxt", {
  {
    accessToken: "<your-access-token>",
    bridge: true,
    devtools: true,
    apiOptions: {}, // storyblok-js-client options
  }
}]

定义您自己的插件

虽然推荐的方法涵盖了大多数情况,但有些情况下您可能需要使用 enableSudoMode 选项并禁用我们的插件,以便您可以合并您自己的插件。

// nuxt.config.ts
modules: [
  [
    "@storyblok/nuxt",
    {
      accessToken: "<your-access-token>",
      enableSudoMode: true
    }
  ]
];

要在 SDK 的 apiOptions 中包含其他功能,例如自定义缓存方法,您可以在 plugins 文件夹(自动导入)中实现以下解决方案。

// plugins/storyblok.js
import { StoryblokVue, apiPlugin } from "@storyblok/vue";

export default defineNuxtPlugin(({ vueApp }) => {
  vueApp.use(StoryblokVue, {
    accessToken: "<your-access-token>",
    apiOptions: {
      cache: {
        type: "custom",
        custom: {
          flush() {
            console.log("all right");
          }
        }
      }
    },
    use: [apiPlugin]
  });
});

区域参数

可能的值

  • eu(默认):用于在欧盟创建的空间
  • us:用于在美国创建的空间
  • ap:用于在澳大利亚创建的空间
  • ca:用于在加拿大创建的空间
  • cn:用于在中国创建的空间

在美国创建的空间的完整示例

["@storyblok/nuxt", {
  {
    accessToken: "<your-access-token>",
    apiOptions: {
      region: "us"
    }
  }
}]

重要 对于在美国或中国创建的空间,region 参数 **必须** 指定。

入门

1. 创建并链接您的组件到 Storyblok 可视化编辑器

将您的 Vue 组件链接到 Storyblok 空间中的等效组件

  • 首先,您需要将它们全局加载,并将它们添加到 ~/storyblok 目录中。在您的代码中使用帕斯卡命名法命名它们很重要 ExampleComponent.vue,并在您的 Storyblok 空间中使用连字符命名它们 example-component,这样它们将被自动导入。
    如果您想为 Storyblok 相关的组件定义自己的目录,您可以在 nuxt.config.js 中使用选项 componentsDir
    // nuxt.config.ts
    modules: [
      [
        "@storyblok/nuxt",
        {
          accessToken: "<your-access-token>",
          componentsDir: false,
        }
      ]
    ],
    components: {
      dirs: [
        {
          path: '~/components/storyblok',
          global: true,
        }
      ]
    },
    

    否则,您可以设置另一个目录并手动加载它们(例如,通过 使用 Nuxt 插件)。

    警告 请注意,如果您在 storyblok 文件夹中命名的组件与 components 文件夹中的另一个组件相同,它将无法正常工作。提示:在您的 Nuxt 项目中使用不同的名称来保留组件。

  • 对于每个组件,在其根元素上使用 v-editable 指令,传递它们接收的 blok 属性
<div v-editable="blok" / >
  • 最后,使用 <StoryblokComponent>,它在 Nuxt 应用程序中全局可用
<StoryblokComponent :blok="blok" />

blok 是来自 Storblok 的内容交付 API 的实际块数据。

2. 获取 Storyblok 故事并监听可视化编辑器事件

组合 API

最简单的方法是使用 useAsyncStoryblok 一行可组合(它被自动导入)。您需要将 slug 作为第一个参数传递,而第二个和第三个参数 apiOptionsbridgeOptions 分别是可选的。

查看我们 API 文档中可用的 apiOptions 和传递给 Storyblok Bridge 的 bridgeOptions

注意 如果你想了解更多关于版本控制的信息 { version: "draft" /* 或 "publish" */ },请访问 预览和/或生产环境的使用 部分。

<script setup>
  const story = await useAsyncStoryblok(
    "vue",
    { version: "draft", resolve_relations: "Article.author" }, // API Options
    { resolveRelations: ["Article.author"], resolveLinks: "url" } // Bridge Options
  );

  if (story.value.status) {
    throw createError({
      statusCode: story.value.status,
      statusMessage: story.value.response
    });
  }
</script>

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

这是在 useStateuseStoryblokBridge 函数中分别使用 useStoryblokApi 的简写等效方法。

<script setup>
  const story = useState();
  const storyblokApi = useStoryblokApi();

  const { data } = await storyblokApiInstance.get(
    `cdn/stories/vue`,
    {
      version: "draft"
    }
  );
  story.value = data.story;

  onMounted(() => {
    useStoryblokBridge(
      story.value.id,
      (evStory) => (story.value = evStory),
      { resolveRelations: ["Article.author"], resolveLinks: "url" } // Bridge Options
    );
  });
</script>

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

useState 是一个 SSR 友好的 ref 替代方案。它的值将在服务器端渲染后(在客户端水合期间)保留。

渲染富文本

你可以使用 @storyblok/nuxt 附带的 renderRichText 函数和 Vue 计算属性轻松渲染富文本。

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

<script setup>
  const props = defineProps({ blok: Object });
  const articleContent = computed(() =>
    renderRichText(props.blok.articleContent)
  );
</script>

你还可以通过将选项作为 renderRichText 函数的第二个参数传递来设置自定义模式和组件解析器

<script setup>
  import cloneDeep from "clone-deep";

  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 props = defineProps({ blok: Object });

  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>

3. 使用预览和/或生产环境

请记住,桥接器只使用 version: 'draft'预览访问令牌 工作。

对于生产站点,不作为内容编辑器的预览使用,应该使用 version: 'published'公共访问令牌

注意 如果你将生产环境用作营销人员和你的公共网站的预览,你需要一个插件来处理不同的 .env 变量,或者使用 预览访问令牌 的版本,检查你是否在 Storyblok 中。例如,类似于 if (window.location.search.includes(_storyblok_tk[token]=<YOUR_TOKEN>)

查看官方文档,了解如何 访问不同的内容版本

API

useAsyncStoryblok(slug, apiOptions, bridgeOptions)

(推荐选项)在幕后使用 useState 来帮助实现 SSR 兼容性。

查看可用的 apiOptions(传递给 storyblok-js-client)和 bridgeOptions(传递给 Storyblok Bridge)。

useStoryblok(slug, apiOptions, bridgeOptions)

当我们需要进行完整的客户端请求时,例如获取已登录用户的个性化数据,使用 useStoryblok 而不是 useAsyncStoryblok 可能会有所帮助。

查看可用的 apiOptions(传递给 storyblok-js-client)和 bridgeOptions(传递给 Storyblok Bridge)。

useStoryblokApi()

返回 storyblok-js-client 的实例。

useStoryblokBridge(storyId, callback, bridgeOptions)

使用此单行函数来涵盖最常见的用例:在 Storyblok 可视化编辑器上发生任何更改时更新故事。

Storyblok JavaScript SDK 生态系统

A visual representation of the Storyblok JavaScript SDK Ecosystem

ℹ️ 更多资源

支持

贡献

请查看我们的 贡献指南 和我们的 行为准则。此项目使用 semantic-release 通过使用提交消息来生成新版本,我们使用 Angular 约定来命名提交。查看 此问题 关于 semantic-release 常见问题解答中的内容。