Skip to content

Streamlining useAsyncStoryblok to nuxt's useAsyncData #836

Open
@jrutila

Description

@jrutila

Description

In the latest versions useAsyncStoryblok returns only the story. You cannot control the useAsyncData that is inside the useAsyncStoryblok at all. For example, you would like to instruct lazy or client only fetching.

To be more in line with the way nuxt composables like useAsyncData or useFetch work the useAsyncStoryblok should return the object that contains the usual data, pending, etc properties. One could also provide the AsyncDataOptions for the composable.

This would be a breaking change and thus needs more discussion.

I can submit a PR for this if the idea sounds solid.

Suggested solution or improvement

This implementation of useAsyncStoryblok should work as described above.

import { useStoryblokApi, useStoryblokBridge } from "@storyblok/vue";
import type { ISbStoriesParams, StoryblokBridgeConfigV2, ISbStoryData } from '@storyblok/vue';
import { useState, onMounted, useAsyncData } from "#imports";
import { type AsyncDataOptions } from "#imports";

export const useAsyncStoryblok = async (
  url: string,
  apiOptions: ISbStoriesParams = {},
  bridgeOptions: StoryblokBridgeConfigV2 = {},
  asyncOptions: AsyncDataOptions = {}
) => {
  const storyblokApiInstance = useStoryblokApi();
  const uniqueKey = `${JSON.stringify(apiOptions)}${url}`;
  const story = useState<ISbStoryData>(`${uniqueKey}-state`);

  onMounted(() => {
    if (story.value && story.value.id) {
      useStoryblokBridge(
        story.value.id,
        evStory => (story.value = evStory),
        bridgeOptions,
      );
    }
  });

  return await useAsyncData(
    uniqueKey,
    () => {
      return storyblokApiInstance
        .get(`cdn/stories/${url}`, apiOptions)
        .then((r) => r.data.story)
    },
    asyncOptions
  )
};

This could be then called like this (from playground folder):

const { data: story, pending } = await useAsyncStoryblok(`vue/articles/${path.params.slug}`, {
  version: "draft",
  language: "en"
}, {},
{ server: false, lazy: true, dedupe: "defer" }); // <- any asyncData options to give the control to the dev

Additional context

No response

Validations

Metadata

Metadata

Assignees

Labels

enhancement[Issue][PR] New featurep3pending-triage[Issue] Ticket is pending to be prioritised

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions