-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useStoryblokAsync equivalent for multiple stories (storyblokApi.get()) #547
Comments
I just played around with the existing composable useAsyncStoryblok and changed
Calling it like that
|
you can wrap your call to the storyblok-api inside a const articles = ref(null)
const storyblokApi = useStoryblokApi()
const { data } = await useAsyncData(
'articles',
async () =>
await storyblokApi.get('cdn/stories', {
version: 'draft',
starts_with: 'blog',
is_startpage: false,
})
)
articles.value = data.stories but i agree, that a shorthand composable would be very handy. |
Hi @papoms & @codeflorist, thanks for opening and giving insights into this feature request. I will talk about this internally with my manager, but in the meantime, will you be willing to participate in developing the composable if we have the green light? |
@codeflorist With this your data object is structured a bit differently: I thought this would work for me but I've run into a few problems over the past few weeks. Potentially cache related? Here are my problems:
// RecentArticles.vue
<script setup>
defineProps({ blok: Object })
const articles = ref(null)
const storyblokApi = useStoryblokApi()
const { data } = await useAsyncData(
'recent-articles',
async () =>
await storyblokApi.get('cdn/stories', {
version: 'draft',
starts_with: 'blog',
is_startpage: 0,
per_page: 3
})
)
articles.value = data.value.data.stories
</script> // AllArticles.vue (with cv and localization)
<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n({
useScope: 'global'
})
defineProps({ blok: Object })
const articles = ref(null)
const storyblokApi = useStoryblokApi()
const { data } = await useAsyncData(
`blog-${new Date().getTime()}`,
async () => await storyblokApi.get('cdn/stories', {
version: 'draft',
starts_with: 'blog',
is_startpage: 0,
language: locale.value,
cv: new Date().getTime()
})
)
articles.value = data.value.data.stories
</script> @papoms @codeflorist @Dawntraoz Have you run into this issue? |
ad 1) if your are using ad 2) I think you need to include the language in the useAsyncData(`blog-${locale.value}`,... ad 3) Thats strange, since you are using different keys with As an alternative to // RecentArticles.vue
<script setup>
defineProps({ blok: Object })
const articles = useState('recent-articles')
const storyblokApi = useStoryblokApi()
if (!articles.value) {
const stories = await storyblokApi.get('cdn/stories', {
version: 'draft',
starts_with: 'blog',
is_startpage: 0,
per_page: 3
})
articles.value = stories
}
</script> This doesn't seem to store it's data in the payload-files, but rather directly in the |
@Dawntraoz I'll try to wrap up a pull request. |
how is pagination solved for the examples above? or is it not resolved? |
I ended up getting it all to work like this: const storyblokApi = useStoryblokApi()
const { data } = await useAsyncData(
`blog-list-${locale.value}-${page.value}`,
async () => await storyblokApi.get('cdn/stories', {
version: draft,
starts_with: 'blog',
is_startpage: false,
language: locale.value,
per_page: 10,
page: page.value
})
) You need to set a unique key for the cache to retrieve the data per page, so: `blog-list-${locale.value}-${page.value}`, is adding the and |
Thanks @bocooper-dev ! In my case I need all pages to resolve to a single promise. And then return the results. At the moment i have to do some horrible looping in order to get all the pages for a certain section (like blog) async function useStoryblokGetStoriesAsync(url, apiOptions) {
const storyblokApiInstance = useStoryblokApi()
let currentPage = 1
let results = []
const { data } = await useAsyncData(
`${cv}${url}${page.value}`,
async () => {
while (fetchingStories) {
const rs = await storyblokApiInstance.get('cdn/stories', {
...apiOptions,
version: 'draft',
cv: myGetCacheVersion(),
per_page: 10,
page: currentPage,
excluding_fields: apiOptions.excluding_fields || 'pageBody',
})
// ...some more things here
const currentPageStories = rs.data.stories || []
results = results.concat(currentPageStories)
currentPage++
}
return results
},
)
return data.value
} This is the only way I've been able to loop through pages, but TBH I am not happy with it. |
you should be able to simply use here is how i do it ( using const articles = useState<NewsArticle[]>('articles-' + currentLocale.value)
if (!articles.value) {
const stories = await storyblokApi.getAll('cdn/stories', {
starts_with: 'articles/',
sort_by: 'first_published_at:desc',
language: currentLocale.value,
})
articles.value = stories
} |
Thank you big time @bocooper-dev @codeflorist !! I ended up implementing it this way: /**
* Fetches Storyblok stories based on the provided URL or configuration.
*
* @param {string | StoryConfig} url - The URL or Storyblok configuration to fetch the story.
* @param {ISbStoriesParams} apiOptions - Additional API options for fetching the story (optional).
* @returns {Promise<ISbStoryData[]>} - The fetched story data.
*/
export async function useStoryblokGetStoriesAsync(
url: string,
apiOptions: ISbStoriesParams = {},
): Promise<ISbStoryData[]> {
const version = getStoryVersion()
const cv = getCacheVersion()
// @ts-expect-error: Nuxt doesn't offer an explicit export for useState and auto imports it.
const stories = useState<ISbStoryData[]>(`${cv}${url}`)
const storyblokApiInstance = useStoryblokApi()
if (!stories.value) {
const rs = await storyblokApiInstance.getAll('cdn/stories', {
version,
cv,
excluding_fields: apiOptions.excluding_fields || 'pageBody',
...apiOptions,
})
stories.value = rs
}
return stories.value
} This worked fine on dev environment, tho I am getting I will also try the suggestion in the link |
Impressive findings, you all, @nachoadjust, @bocooper-dev & @codeflorist, thanks a lot for this. You made my day! It's so cool to see you all collaborating and helping each other 🤩 Would you be up for a quick sync call? So we can include the solution in the SDK for everyone? Let me know 😍 |
Hi @Dawntraoz ! About the code: |
Description
Using the Storyblok-nuxt module i wish there was a composable similar to useStoryblokAsync but for requests that return multiple stories.
An Example would be fetching all Blog articles as described in: https://www.storyblok.com/tp/create-and-render-blog-articles-in-storyblok-and-nuxt#rendering-all-articles
While that works, i love the benefit of useStoryblokAsync in the context of static site generation with
npm run generate
and the new experimental payload extraction feature of nuxt 3.Would you be interested in including such a composable within this module?
Suggested solution or improvement
write a useStoryBlokAsyncGet Composable
generalize useStoryBlokAsync to allow queries for multiple stories (e.g. cache returned story OR stories)
Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: