Search code examples
next.jsstoryblok

Storyblok React Bridge Restarting Preview On Data Change


I want to use the new Storyblok React bridge with Next.js. In my case, there is a component directly in the _app.js (which should not change between route changes), so it looks like this:

function MyApp({ Component, pageProps: { pageData, globalData } }) {
  const story = useStoryblokState(globalData.story)
  console.log('rendering app')
  return (
    <>
      <Collage story={story} />
      {/* <Component {...pageData} /> */}
    </>
  );
}

The corresponding getStaticProps looks like this:

export async function getStaticProps() {
  let sbParams = {
    version: "draft", // or 'published'
  };

  const storyblokApi = getStoryblokApi();
  let { data: pageData } = await storyblokApi.get(`cdn/stories/home`, sbParams);
  let { data: globalData } = await storyblokApi.get(
    `cdn/stories/collage`,
    sbParams
  );

  return {
    props: {
      pageData,
      globalData,
    },
    revalidate: 3600,
  };
}

Here everything works as intended (i.e. changes to data will only rerender the collage component but not touch anything else), but as soon as I uncomment the main component, in the Storyblok preview (with localhost:3000), changing any data will restart the iFrame, just like it would be the case if no React bridge is used. I can even see that the data changes are applied just before it restarts. Any idea how to fix this?


Solution

  • useStoryblokState() calls useStoryblokBridge() from the @storyblok/js package. Despite its name, useStoryblokBridge() is not a react hook, but an ordinary function with side effects. It subscribes to events from the Storyblok bridge here. If the story that was passed as argument isn't the same story that is sent to the event listener via the Storyblok bridge, the event listener will reload the entire page.

    https://github.com/storyblok/storyblok-js/blob/main/lib/index.ts#L40

    This means that if you call useStoryblokBridge() with two different stories, the window will reload.