Skip to content

Visual editing not working on first load #881

Open
@nicwands

Description

Describe the issue you're facing

I am having trouble getting visual editing to work on first load with SSG.

I followed the tutorial here to create a fully static preview environment: https://www.storyblok.com/tp/create-a-preview-environment-for-your-nuxt-3-website

When in the Storyblok editor, visual editing does not work when it's first loaded. If I make any change in the editor though, the bridge correctly updates everything and after that update, visual editing works as expected.

The problem seems to be in the v-editable composable not adding the necessary attributes on first load for some reason. I tried creating my own custom directive and found that binding.value does not have the _editable property needed to add these attributes, which I think means that the bridge is not initialized yet.

Does anyone know why the bridge isn't initializing correctly on first load?

Here is my preview.js:

export default defineNuxtPlugin((nuxtApp) => {
    const route = useRoute()

    const preview = route.query?._storyblok || false

    if (preview) {
        nuxtApp.hook('page:finish', () => {
            console.log('refresh')
            refreshNuxtData()
        })
    }

    return { provide: { preview } }
})

And the composable I'm using to fetch stories:

export const useAsyncStory = async (
    url,
    apiOptions = {},
    bridgeOptions = {}
) => {
    const { $preview } = useNuxtApp()
    const version = $preview ? 'draft' : 'published'
    const refreshKey = ref(url)
    const story = ref()

    onMounted(async () => {
        if (story.value && story.value.id) {
            useStoryblokBridge(
                story.value.id,
                (evStory) => {
                    story.value = evStory
                    refreshKey.value =
                        Math.random() + (1).toString(36).substring(7)
                },
                { resolveLinks: 'url', ...bridgeOptions }
            )
        }
    })

    const { data } = await useAsyncData(url, async () => {
        const { data } = await useStoryblokApi().get(`cdn/stories/${url}`, {
            version,
            resolve_links: 'url',
            resolve_links_level: 2,
            ...apiOptions,
        })

        return data?.story
    })

   if (data.value?.content) {
        story.value = data.value
    } else {
        throw createError({
            statusCode: 404,
            statusMessage: 'Not Found',
            fatal: true,
        })
    }

    return { story, refreshKey }
}

Reproduction

Not possible

Steps to reproduce

No response

System Info

System:
    OS: Linux 6.9 Arch Linux
    CPU: (20) x64 13th Gen Intel(R) Core(TM) i9-13900H
    Memory: 4.64 GB / 15.25 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v20.10.0/bin/yarn
    npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm
    pnpm: 9.4.0 - /usr/bin/pnpm
  Browsers:
    Chromium: 126.0.6478.182

Used Package Manager

pnpm

Error logs (Optional)

No response

Validations

Metadata

Assignees

No one assigned

    Labels

    pending-author[Issue] Awaiting further information or action from the issue authorpending-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