Next.js client-side-only data preview with @storyblok/react

Hello there!

TLDR

Is there a way to make client-side loaded stories show updated draft data correctly in the editor live preview when using a server-side generated framework like Next.js?

Metadata

API version: Storyblok API version V2
Editor version: Storyblok editor 1 (not the upcoming one)
Framework: Next.js
Library: @storyblok/react

Question explanation

I’m working on a Next.js (Server-side generated) project where we load global data like the menu navigation and footer data on the client-side, so we don’t have to include that data on every route change.

For page data we use useStoryblokState from @storyblok/react, which works perfectly with the visual live preview editor.

However, I’ve noticed that it doesn’t seem possible to get the live preview to work correctly with client-side-only data when using Next.js (using any form of useStoryblokState or useStoryblok from @storyblok/react. I’ve tried writing my own version of either of those hooks with the sbBridge, but to no avail.

I’ve setup the live preview mode like described in the Next.js 5 minutes example. Server side fetched data and preview behaves as expected. However, when I update client-side-only data (fetched using useStoryblok hook) in the editor, I can shortly see the data update to the updated preview data, but then the storyblok preview editor refreshes the page, displaying the last-saved data again. Even forcing version: 'draft' hard-coded doesn’t help.

If I just use react following the React.js 5 minutes example, with the useStoryblok hook, everything works as expected: the editor doesn’t refresh on input.

This seems to be the behavior both on localhost and a remote host.

What I’ve tried

I cloned the React boilerplate and Next.js boilerplate and only added the useStoryblok hook to fetch a specific client-side-only story (in my case navigation/menu). The react boilerplate behaves as expected (Editing data in the editor doesn’t reload the page and shows the updated preview data).

I edited the Next.js boilerplate, adding a useStoryblok hook to navigations/menu for the client-side, but it doesn’t seem to behave as expected, so it doesn’t seem to be a problem with our own setup.

Code I added to the Next.js boilerplate ([...slug].js):

import {
  useStoryblokState,
  useStoryblok,
  getStoryblokApi,
} from "@storyblok/react";

import { useRouter } from "next/router";

export default function Page({ story }) {
  story = useStoryblokState(story);

  const { isPreview } = useRouter()

  const menuStory = useStoryblok('navigation/menu', { version: isPreview ? 'draft' : 'published' })

  console.log(menuStory.content)

  if (!menuStory || !menuStory.content) {
    return 'loading...'
  }

  return (
    <div className={styles.container}>
      {menuStory.content.menuLabel}
    </div>
  );
}

Is there a way to prevent the editor from refreshing if I’m already in the preview mode and only the input of the client-side story is updated?

Thank you for your time, please let me know if you need more details or a more comprehensive example.

Hello @Folkert-Jan,

I’ve seen most people using the preview mode of Next.js in the live preview editor. Here is also an article that explains how to get it running: Next.js Preview in iframes - Storyblok

In case that you couldn’t find any solution feel free to reach out to our developer community on Discord: Storyblok

Best regards
Hannes