Skip to content
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

Automatically fetch new data on generated sites when in the editor #423

Closed
SebbeJohansson opened this issue May 26, 2023 · 17 comments
Closed
Assignees
Labels
documentation [Issue] Add new docs about a topic or update existing one question [Issue] Further information is requested

Comments

@SebbeJohansson
Copy link
Contributor

In nuxt2 you could previously run enablePreview() to refetch data, maybe we can implement something like that?

Expected Behavior

I expect the application to always fetch new data when in preview mode.

Current Behavior

Currently it displays pregenerated content.

Steps to Reproduce

  1. Use useAsyncStoryblok to fetch data in a generate nuxt3 application.
  2. Deploy site.
  3. Edit the site in the live editor in storyblok.
  4. Notice how the site is still with the generated content.

Example code from Henrik Hansson:

<template>
    <StoryblokComponent v-if="story" :blok="story.content" />
</template>

<script setup lang="ts">
import { ISbStoriesParams } from 'storyblok-js-client';

const { currentRoute } = useRouter();
const slug = currentRoute.value.path.toString().replace(/\/$/, '');

const version = useRuntimeConfig().public
  .version as ISbStoriesParams['version'];

const story = await useAsyncStoryblok(slug === '' ? 'start' : slug, {
  version: version,
  resolve_links: 'url'
});

</script>

Discussion from discord: https://discord.com/channels/700316478792138842/1111583846731882586
Discussion from nuxt github: nuxt/nuxt#15639 & nuxt/nuxt#18407 (comment)

@henrikhansson
Copy link

henrikhansson commented Jun 8, 2023

I have been looking into this for a few weeks but still have no solution how to make the Storyblok visual editor work properly using Nuxt 3 and SSG. As mentioned, this was a very simple matter on Nuxt 2 using enablePreview() to force asyncData to fetch new content, but there seem to be no way to achieve this in Nuxt 3. refreshNuxtData() should be the solution but it has no effect on useAsyncStoryblok. Is there actually no way of making the visual editor work using Nuxt 3 and SSG or am I missing some obvious solution?

@stijns96
Copy link

I really want to see this feature as well. Actually this is even so important, that I just can not transfer this to my clients.... They just don't understand what happens.

Is there any news on this, because this is really critical.

I also tried to load draft data when in preview etc, but everytime I hit save, it changes back to the generated content. Location.reload(false) also isn't doing anything.

@Adamkillander96
Copy link
Contributor

Adamkillander96 commented Jul 14, 2023

We really need this feature as well and I have created a funky work around that worked for me. We can flush the cache when you click the save button in the visual editor.

How we did it

This is how we fetch data from Storyblok, we dont use useAsyncStoryblok, but a combination of useAsyncData and useStoryblokApi. We do this because we need the refresh function that useAsyncData provides.

const { data, error, refresh, status } = await useAsyncData(
  `get-story-${dataSlug}`,
  async () =>
    await useStoryblokApi().get(`cdn/stories/${slug}`, {
      language: topbar.localeSlash,
      version: STORYBLOK_VERSION,
      resolve_relations: ['global.call_to_action']
  }),
  ...

We use the npm run generate command when we deploy our site. So out of the box, we can't use the visual editor (as of now) because of the static site generation. But with the refresh function, we can flush the cache and call the API again.

So what I did was this:

process.client &&
  window.self !== window.top &&
  onMounted(() => {
    window.addEventListener('message', (event) =>
      event.origin === 'https://app.storyblok.com' &&
      event.data?.action === 'change' &&
      setTimeout(() => refresh(), 1000)
    )
  })

If the page loads on the client side and is in an iframe, use onMounted to attach an eventListener for the message event. If the origin is from storyblok.com and is a change action, refresh the asyncData. I threw this together yesterday, so I am not sure the setTimeout is necessary.

By doing this, the data variable from the useAsyncData updates when you click the save button in the visual editor. So no real time updates, but its something. On top of this, you have to save and wait for your pipeline to build the site when you create a new page. We use the storyblok pipeline plugin, so we can build pages in a test environment before going to prod. If you dont have that, this solution wont really work. Also, you gotta click save twice because the first reloads the page, after the first one it updates without reloading.

An official and less funky solution would be nice, but maybe this could help for the moment for some.

@henrikhansson
Copy link

Thank you @Adamkillander96 for your solution, but as you mentioned without the pipeline it wont work. And it's also not real time update as with Nuxt 2 and enablePreview() . Is there any news on this? I have been testing exchanging the key for useAsyncData without success. Maybe I've missed something obvious, or the approach could inspire someone:

const route = useRoute();
const slug = route.path.replace(/\/$/, '');

const story = ref();
const storyblokApi = useStoryblokApi();

const preview = route.query._storyblok ? true : false;

const { data } = await useAsyncData(
  preview ? 'story-preview' : 'story',
  async () =>
    await storyblokApi.get(`cdn/stories/${slug}`, {
      version: preview ? 'draft' : 'published',
    })
);
story.value = data.value?.data.story;

onMounted(() => {
  useStoryblokBridge(story.value?.id, (evStory) => (story.value = evStory));
});

I also want to stress how important this is, not being able to use the visual editor is making it impossible to hand over any statically hosted project using Nuxt 3 to a client.

@rnenjoy
Copy link

rnenjoy commented Jul 24, 2023

Is this only for generated sites, not on normal hybrid nuxt3 apps?

@henrikhansson
Copy link

I dove a little bit deeper down into problem and decided to set up a few simple tests on a dedicated Netlify site. Neither refresh() as @Adamkillander96 suggested or refreshNuxtData() as any effect on the fetched content. I might be missing something obvious here but am at wits end, is there really no way to achieve a functional visual preview?

@stijns96
Copy link

@Dawntraoz, could you maybe give us an update on this feature? It seems that more and more people are struggling with this...

@ItsMeDelanoDev
Copy link

It's a bit concerning that this ticket has been open for quite a while without any response from the devs. Given the importance of the bug and the relative high subscription prices we pay for this product, one would expect a quicker resolution or at least a response. Just sharing my thoughts on this. Thanks!

@ItsMeDelanoDev
Copy link

After my earlier rant, I actually stumbled upon something interesting. It seems like the issue might have been sorted out in one of the recent releases since August 10. I've noticed that all those warnings etcetera in my console have vanished when using the editor with the SSR Netlify preview link. Plus, the edits I've been making in the editor are behaving themselves. So, hey @stijns96 and @SebbeJohansson, maybe giving the latest version a shot could do the trick for you too.

@ghost
Copy link

ghost commented Aug 16, 2023

Hi @ItsMeDelanoDev,

SSR should work indeed, but the problem is with SSG. This was working with nuxt 2 and not with nuxt 3.

How do you get a SSR preview link? That totally depends on the command you run right?

@ItsMeDelanoDev
Copy link

Besides my stupid mistake I meant Netlify SSG.

After my earlier rant, I actually stumbled upon something interesting. It seems like the issue might have been sorted out in one of the recent releases since August 10. I've noticed that all those warnings etcetera in my console have vanished when using the editor with the SSR Netlify preview link. Plus, the edits I've been making in the editor are behaving themselves. So, hey @stijns96 and @SebbeJohansson, maybe giving the latest version a shot could do the trick for you too.

False alarm after all, while experimenting it seemed to work way better than before. Yet now once again fields are no longer updating real time on our Netlify deploy-preview and production pages. We are running nuxt build on Netlify.

@henrikhansson
Copy link

Years ago, before enablePreview() was introduced in Nuxt 2, using a dedicated SPA site for the visual preview was a way to solve this problem. I just did a test run in Nuxt 3 and it still seems to work. There used to be some navigational issues but so far, in my limited testing, I haven't found any. It's not ideal to be dependent on a second site for the visual preview but you can keep them identical with the use of an environmental variable. And make sure to use the same version in all API calls or you can encounter unwanted results.

For Netlify it can look something like this:

export default defineNuxtConfig({
 process.env.PREVIEW ? ssr: false : ssr:true,

  runtimeConfig: {
    public: {
      version:
        process.env.SITE_ENV === 'production' && !process.env.PREVIEW
          ? 'published'
          : 'draft',
    }
  }
});

I still have some testing to do but this looks promising!

@codeflorist
Copy link

codeflorist commented Aug 24, 2023

i'm having some success with this solution: storyblok/nuxt-ultimate-tutorial#5 (comment)

with it, the story ref seems to get correctly updated, but there seem to be general problems afoot with various elements (like the img-src attribute, or v-html) not getting updated during hydration. i've opened a Nuxt-issue here, with Daniel concluding it is a vue issue. i've now opened a new issue for the vue core here.

also note, that on static hosting, you have to make sure, that calls to non-existant sites get redirected to 200.html. with apache you can put ErrorDocument 404 /200.html inside your .htaccess.

all in all, after working many hours on a prerendered nuxt+storyblok project i can only conclude: it is a veritable shit-show, with many weird effects and stuff not working correctly. :-/

EDIT: i've carved out yet another vue-core problem leading to a mashed up DOM, when removing a component: vuejs/core#9035
i've updated my above linked solution with a fix (moving story.value = draftStory.value inside onMounted.

@Dawntraoz Dawntraoz self-assigned this Oct 16, 2023
@Dawntraoz Dawntraoz added question [Issue] Further information is requested documentation [Issue] Add new docs about a topic or update existing one labels Oct 16, 2023
@Dawntraoz
Copy link
Contributor

Hi folks 👋

As I've already mentioned to @codeflorist in his issue on this at UT repo: storyblok/nuxt-ultimate-tutorial#5 (comment), as I'm working on the last part of the Ultimate Tutorial (Preview environments & Deployment), I have the SSG with preview mode refreshing (as in Nuxt 2) working there.

You can check here the [...slug].vue: https://github.com/storyblok/nuxt-ultimate-tutorial/blob/part-7/pages/%5B...slug%5D.vue
And the preview plugin needed: https://github.com/storyblok/nuxt-ultimate-tutorial/blob/part-7/plugins/preview.js

Again, I hope this helps and can fix all the issues you were having 🤗 As I told to CodeFlorist, if you want to jump in a quick call to see the workaround together or discuss doubts, happy to help and add more insights on the tutorial thanks to your feedback!

@henrikhansson
Copy link

Thank you @Dawntraoz, your solution is a lot leaner than my take on the problem :)

However I get

Uncaught TypeError: e.target.closest is not a function

whenever I click on a block in the visual preview and the editor does not focus on the block. Is this working on your end? My templates should be good, this is working using my solution.

@Dawntraoz
Copy link
Contributor

@henrikhansson indeed should be working, probably worth checking out the differences with main: storyblok/nuxt-ultimate-tutorial@main...part-7, just in case something is different in your solution 🤔

@Dawntraoz
Copy link
Contributor

The article is now live! Please check it out and let me know your feedback: https://www.storyblok.com/tp/create-a-preview-environment-for-your-nuxt-3-website 💜

I will close the issue since this resolves the topic, no need to update the SDK since it's implemented directly on the end project. Do you think will be helpful to update the README.md? If so, I will include it as reference 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation [Issue] Add new docs about a topic or update existing one question [Issue] Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants