Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"dev:build": "nuxi build playground",
"dev:preview": "nuxi preview playground",
"prepare:playground": "nuxi prepare playground",
"dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground",
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
"cy:open": "cypress open",
"cy:run": "cypress run",
"test:e2e": "start-server-and-test dev http://localhost:3000 cy:run",
Expand Down
7 changes: 5 additions & 2 deletions packages/nuxt/playground-e2e/pages/[...slug].vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<script setup>
<script setup lang="ts">
const route = useRoute();

const { story, error } = await useAsyncStoryblok(route.path, {
api: {
version: 'draft',
language: 'en',
resolve_relations: ['popular-articles.articles'],
resolve_relations: 'popular-articles.articles',
},
bridge: {
resolveRelations: 'popular-articles.articles',
},
});

Expand Down
7 changes: 5 additions & 2 deletions packages/nuxt/playground/pages/[...slug].vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<script setup>
<script setup lang="ts">
const { slug } = useRoute().params;
const { story } = await useAsyncStoryblok(
slug && slug.length > 0 ? slug.join('/') : 'home',
slug && slug.length > 0 ? (slug as string[]).join('/') : 'home',
{
api: {
version: 'draft',
language: 'en',
resolve_relations: ['popular-articles.articles'],
},
bridge: {
resolveRelations: 'popular-articles.articles',
},
},
);
</script>
Expand Down
6 changes: 4 additions & 2 deletions packages/nuxt/playground/pages/articles/[slug].vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script setup lang="ts">
const path = useRoute();
const story = await useAsyncStoryblok(`vue/articles/${path.params.slug}`, {
version: 'draft',
language: 'en',
api: {
version: 'draft',
language: 'en',
},
});
</script>

Expand Down
9 changes: 0 additions & 9 deletions packages/nuxt/playground/pages/articles/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ const { data: articles } = await storyblokApi.get('cdn/stories/', {
starts_with: 'vue/articles',
is_startpage: false,
});
/* const storyblokApi = useStoryblokApi()

const { data: articles } = await storyblokApi.get('cdn/stories/vue', {
version: 'draft',
starts_with: 'articles',
is_startpage: false,
})

console.count('Articles Fetch') */
</script>

<template>
Expand Down
9 changes: 1 addition & 8 deletions packages/nuxt/playground/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
<script setup lang="ts">
/* import type { SbBlokData } from '@storyblok/vue'; */

// const storyblokApi = useStoryblokApi();
// // Checking custom Flush method
// storyblokApi.flushCache();

const { story, error } = await useAsyncStoryblok('vue', {
api: {
version: 'draft',
Expand All @@ -19,10 +13,9 @@ const { story, error } = await useAsyncStoryblok('vue', {
if (error.value) {
throw createError({
statusCode: error.value.statusCode,
statusMessage: error.value.statusMessage
statusMessage: error.value.statusMessage,
});
}

</script>

<template>
Expand Down
26 changes: 12 additions & 14 deletions packages/nuxt/playground/pages/richtext.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,32 @@
import { NuxtLink } from '#build/components';
import { MarkTypes, type StoryblokRichTextNode } from '@storyblok/vue';

const story = await useAsyncStoryblok(
"vue/test-richtext",
{
version: "draft"
}
// { resolveRelations: "Article.categories" }
);
const story = await useAsyncStoryblok('vue/test-richtext', {
api: {
version: 'draft',
},
});

const resolvers = {
[MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) => {
return node.attrs?.linktype === "STORY"
return node.attrs?.linktype === 'STORY'
? h(
NuxtLink,
{
to: node.attrs?.href,
target: node.attrs?.target
target: node.attrs?.target,
},
node.text
node.text,
)
: h(
"a",
'a',
{
href: node.attrs?.href,
target: node.attrs?.target
target: node.attrs?.target,
},
node.text
node.text,
);
}
},
};
</script>

Expand Down
64 changes: 37 additions & 27 deletions packages/nuxt/src/runtime/composables/useAsyncStoryblok.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { type ISbResult, type ISbStoriesParams, type StoryblokBridgeConfigV2, useStoryblokApi, useStoryblokBridge } from '@storyblok/vue';
import {
type ISbResult,
useStoryblokApi,
useStoryblokBridge,
} from '@storyblok/vue';
import { computed, type ComputedRef, type Ref, watch } from 'vue';
import { useAsyncData } from '#app';
import type { AsyncData, AsyncDataOptions, NuxtError } from '#app';
import type { AsyncData, NuxtError } from '#app';
import type { DedupeOption } from 'nuxt/app/defaults';

/**
* Options for the useAsyncStoryblok composable.
* Extends Nuxt's AsyncDataOptions with Storyblok-specific configuration.
*/
export interface UseAsyncStoryblokOptions extends AsyncDataOptions<ISbResult> {
/** Storyblok API parameters for fetching stories */
api: ISbStoriesParams;
/** Storyblok Bridge configuration for live preview */
bridge: StoryblokBridgeConfigV2;
}
import type { UseAsyncStoryblokOptions } from '../../types';

interface AsyncDataExecuteOptions {
dedupe?: DedupeOption;
Expand Down Expand Up @@ -45,10 +40,13 @@ export interface UseAsyncStoryblokResult {
*/
const stableStringify = (obj: Record<string, any>): string => {
const sortedKeys = Object.keys(obj).sort();
const sortedObj = sortedKeys.reduce((acc, key) => {
acc[key] = obj[key];
return acc;
}, {} as Record<string, any>);
const sortedObj = sortedKeys.reduce(
(acc, key) => {
acc[key] = obj[key];
return acc;
},
{} as Record<string, any>,
);
return JSON.stringify(sortedObj);
};

Expand Down Expand Up @@ -99,18 +97,30 @@ export async function useAsyncStoryblok(
const { api, bridge, ...rest } = options;
const uniqueKey = `${stableStringify(api)}${url}`;

const result = await useAsyncData(uniqueKey, () => storyblokApiInstance.get(`cdn/stories/${url}`, api), rest) as AsyncData<ISbResult, NuxtError<unknown>>;
const result = (await useAsyncData(
uniqueKey,
() => storyblokApiInstance.get(`cdn/stories/${url}`, api),
rest,
)) as AsyncData<ISbResult, NuxtError<unknown>>;

if (import.meta.client) {
watch(result.data, (newData) => {
if (newData?.data.story && newData.data.story.id) {
useStoryblokBridge(newData.data.story.id, (evStory) => {
newData.data.story = evStory;
}, bridge);
}
}, {
immediate: true,
});
watch(
result.data,
(newData) => {
if (newData?.data.story && newData.data.story.id) {
useStoryblokBridge(
newData.data.story.id,
(evStory) => {
newData.data.story = evStory;
},
bridge,
);
}
},
{
immediate: true,
},
);
}

return {
Expand All @@ -122,4 +132,4 @@ export async function useAsyncStoryblok(
clear: result.clear,
story: computed(() => result.data.value?.data.story),
};
};
}
11 changes: 8 additions & 3 deletions packages/nuxt/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import type { AsyncData, AsyncDataOptions, NuxtError } from 'nuxt/app';
import type { ISbResult, ISbStoriesParams, StoryblokBridgeConfigV2 } from '@storyblok/vue';
import type {
ISbResult,
ISbStoriesParams,
StoryblokBridgeConfigV2,
} from '@storyblok/vue';
import type { ComputedRef } from 'vue';

/**
Expand All @@ -10,10 +14,11 @@ export interface UseAsyncStoryblokOptions extends AsyncDataOptions<ISbResult> {
/** Storyblok API parameters for fetching stories */
api: ISbStoriesParams;
/** Storyblok Bridge configuration for live preview */
bridge: StoryblokBridgeConfigV2;
bridge?: StoryblokBridgeConfigV2;
}

export interface UseAsyncStoryblokResult extends AsyncData<ISbResult, NuxtError<unknown>> {
export interface UseAsyncStoryblokResult
extends AsyncData<ISbResult, NuxtError<unknown>> {
story: ComputedRef<ISbResult['data']['story']>;
}

Expand Down
Loading