Nuxt Nation カンファレンスが開催されます。11月12~13日にぜひご参加ください。

storyblok
@storyblok/nuxt

Storyblok Nuxt モジュール
Storyblok Logo

@storyblok/nuxt

Storyblokの Nuxt 3 モジュール。ヘッドレス CMS。


Storyblok JS Client npm

Follow @Storyblok
Follow @Storyblok

新しいプロジェクトを始めましょう

すぐにコーディングを始めたいですか?Storyblok と Nuxt で新しいプロジェクトを始めるには、以下の手順に従ってください。数分で開始できます!

究極のチュートリアル

実践的なステップバイステップのチュートリアルをお探しですか?Nuxt 究極のチュートリアルをご覧ください!Storyblok と Nuxt を使用して、完全な多言語ウェブサイトを最初から最後まで構築するための包括的な手順が提供されています。

インストール

@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 を使用しています。お使いの環境がこれをサポートしていない場合は、isomorphic-fetch のようなポリフィルをインストールする必要があります。詳細については、storyblok-js-client のドキュメントをご覧ください。

オプション

モジュールを初期化する際、@storyblok/vue のすべてのオプションに加えて、JS SDK の Storyblok Bridge セクションで説明されている bridge オプション、および独自のプラグインを定義するための 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 (デフォルト): EU で作成されたスペースの場合
  • us: 米国で作成されたスペースの場合
  • ap: オーストラリアで作成されたスペースの場合
  • ca: カナダで作成されたスペースの場合
  • cn: 中国で作成されたスペースの場合

米国で作成されたスペースの完全な例

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

重要 米国または中国で作成されたスペースの場合、region パラメーターを必ず指定する必要があります。

はじめに

1. コンポーネントを作成して Storyblok Visual Editor にリンクする

Vue コンポーネントを Storyblok スペース内の同等のコンポーネントにリンクするには

  • まず、それらを ~/storyblok ディレクトリに追加してグローバルにロードする必要があります。コード内ではパスカルケース ExampleComponent.vue で、Storyblok スペース内ではハイフン example-component を使用して名前を付けることが重要です。これにより、自動的にインポートされます。
    Storyblok 関連コンポーネントに独自のディレクトリを定義する場合は、nuxt.config.js でオプション componentsDir を使用できます。
    // nuxt.config.ts
    modules: [
      [
        "@storyblok/nuxt",
        {
          accessToken: "<your-access-token>",
          componentsDir: '~/components',
        }
      ]
    ],
    components: {
      dirs: [
        {
          path: '~/components/storyblok',
          global: true,
        }
      ]
    },
    

    または、別のディレクトリを設定して手動でロードすることもできます (たとえば、Nuxt プラグインを使用)。

    警告 storyblok フォルダー内のコンポーネントを components フォルダー内の別のコンポーネントと同じ名前で命名すると、正しく動作しないことに注意してください。ヒント: Nuxt プロジェクトのコンポーネントの名前を異なるものに保ちます。

  • 各コンポーネントについて、ルート要素で v-editable ディレクティブを使用し、受け取る blok プロパティを渡します
<div v-editable="blok"></div>
  • 最後に、Nuxt アプリでグローバルに使用できる <StoryblokComponent> を使用します
<StoryblokComponent :blok="blok" />

blok は、Storyblok の Content Delivery API からの実際の blok データです。

2. Storyblok Stories を取得し、Visual Editor イベントをリッスンする

Composition API

最も簡単な方法は、ワンライナーのコンポーザブル useAsyncStoryblok (自動インポート) を使用することです。ここで、最初のパラメーターとして slug を渡す必要があります。2 番目と 3 番目のパラメーターである apiOptionsbridgeOptions はそれぞれオプションです。

利用可能な apiOptions については API ドキュメントを、Storyblok Bridge に渡される bridgeOptions については Storyblok Bridge をご確認ください。

バージョニング { version: "draft" /* or "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 storyblokApi.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 関数の 2 番目のパラメーターとしてオプションを渡すことで、カスタムスキーマとコンポーネントリゾルバーを設定することもできます。

<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. プレビューおよび/または本番環境での作業

Bridge は version: 'draft' と *プレビューアクセストークン* を使用する場合にのみ機能することに注意してください。

コンテンツエディターのプレビューとして使用されない本番サイトでは、version: 'published' と *パブリックアクセストークン* を使用する必要があります。

マーケターやパブリックサイトのプレビューとして本番環境を使用している場合は、さまざまな .env 変数または *プレビューアクセストークン* を使用したバージョンを処理するために、Storyblok 内にいるかどうかを確認するプラグインが必要です。たとえば、if (window.location.search.includes(_storyblok_tk[token]=<YOUR_TOKEN>) のようなものです。

さまざまなコンテンツバージョンにアクセスする方法に関する公式ドキュメントを確認してください。

Nuxt でさまざまなコンテンツバージョンを処理する推奨される方法は、Nuxt ランタイム構成と組み合わせて環境変数を使用し、アプリケーション内で構成とシークレットを公開することです

nuxt.config.ts

export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      storyblokVersion: process.env.STORYBLOK_VERSION || "published"
    }
  }
});

その後、コンポーネントでランタイム構成にアクセスできます

const config = useRuntimeConfig();

const story = await useAsyncStoryblok(
  "blog",
  {
    version: config.public.storyblokVersion,
    resolve_relations: "overview.featured_story"
  },
  { resolveRelations: "overview.featured_story" }
);

//or

const { data: articles } = await storyblokApi.get("cdn/stories", {
  version: config.public.storyblokVersion,
  starts_with: "blog",
  is_startpage: false
});

API

useAsyncStoryblok(slug, apiOptions, bridgeOptions)

(推奨オプション) SSR 互換性を実現するために、内部で useState を使用します。

利用可能な apiOptions (storyblok-js-client に渡される) および bridgeOptions (Storyblok Bridge に渡される) を確認してください。

useStoryblok(slug, apiOptions, bridgeOptions)

ログインしたユーザーのパーソナライズされたデータを取得するなど、完全にクライアントサイドのリクエストを行う必要がある場合は、useAsyncStoryblok の代わりに useStoryblok を使用すると役立つ場合があります。

利用可能な apiOptions (storyblok-js-client に渡される) および bridgeOptions (Storyblok Bridge に渡される) を確認してください。

useStoryblokApi()

storyblok-js-client のインスタンスを返します。

useStoryblokBridge(storyId, callback, bridgeOptions)

この 1 行の関数を使用して、Storyblok Visual Editor で何らかの変更が発生した場合にストーリーを更新するという、最も一般的なユースケースに対応します。

Storyblok JavaScript SDK エコシステム

A visual representation of the Storyblok JavaScript SDK Ecosystem

追加のリソース

サポート

貢献

当社の 貢献ガイドライン行動規範 をご確認ください。このプロジェクトでは、コミットメッセージを使用して新しいバージョンを生成するために semantic-release を使用し、コミットの命名には Angular Convention を使用しています。semantic-release FAQ の この質問をご確認ください。