Open
Description
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
- Follow our Code of Conduct