Nuxt3 + SSR + Storyblok, issues with sharing asyncData between components

217 Views Asked by At

I have a composable that loads asyncData from storyblok, that i want to share with multiple components, while hiding the API calls from the client.

My issue is that i can't seem to figure out how to do an initial load with useAsyncData server-side, and share this with components in client, without calling the api again.

my composable 'useSettings.ts' :

const settings = reactive({
  
    loaded: false,
    content: {
        header:null,
        footer:null
    },
    content_version: 'draft'
})
function handleMenuItem(menuitem: any, links: any, locale: string) {
    try {
        // console.log(menuitem.link.id || menuitem )
        if (menuitem.link?.id != '') {
            // console.log("here!")
            menuitem.link.real_story = links.find((l: any) => {
                return menuitem.link.story?.uuid == l?.uuid
            })

            menuitem.link.real_story.full_slug = menuitem.link.story.full_slug
                .replace('pages', '')
                .replace(/\/$/, '')
            if (locale != 'en') {
                menuitem.link.real_story.full_slug = menuitem.link.real_story.full_slug.replace(
                    locale + '/',
                    '',
                )
            }
        } else {
            // console.log("faulty", menuitem)
        }

        if (menuitem.submenu.length > 0) {
            menuitem.submenu.forEach((sub: any) => {
                handleMenuItem(sub, links, locale)
            })
        }
    } catch (error) {
        console.error(error)
    }
}

export default async () => {
    const runtimeConfig = useRuntimeConfig()
    const storyblokApi = useStoryblokApi()
    const { locale, locales } = useI18n()

    const _settings = ref({loaded:false})

    const loadSettings = async () => {
        try {

            await useAsyncData('settings', async () => {
                // console.log("loadSettings : ", (process.server ? 'on server' : 'on client'))
                const main = await storyblokApi.get('cdn/stories/main', {
                    version: settings.content_version,
                    resolve_links: 'url',
                    language: locale.value == 'en' ? '' : locale.value,
                    resolve_relations: 'PageLink.story',
                })
                main.data.story.content.header_menu.forEach((mitem: any) => {
                    handleMenuItem(mitem, main.data.links, locale.value)
                })
                settings.loaded = true

                settings.content.header = main.data.story.content.header_menu
                settings.content.footer = main.data.story.content.footer
            })
            
        } catch (e) {
            console.log(e)
        }
    }
    if(process.server) await loadSettings()

    return { ...toRefs(settings) }

}

and in my 'app.vue'

const {content} = await useSettings()

i want to be able to use content.header and content.footer in different components, without making a new API call.

My expected outcome is the API load happens serverside, hidden from client and then the reactive 'settings' object is accessible within different components.

0

There are 0 best solutions below