storyblok / storyblok-vue-2

[DEPRECATED] Vue.js 2 SDK for Storyblok CMS
0 stars 3 forks source link

v-editable not working properly with static (SSR) Nuxt pages #278

Closed mandalornl closed 1 year ago

mandalornl commented 1 year ago

Describe the issue you're facing

I'm getting an error when I try to click on a component with v-editable enabled and I'm having trouble getting it to work properly with @storyblok/nuxt-2 and statically generated pages.

Uncaught SyntaxError: "undefined" is not valid JSON

I believe it is related to v-editable not being triggered by the update event. Currently it only listens to the bind event, so it will only trigger when the component is created.

https://github.com/storyblok/storyblok-vue-2/blob/3ab1e43647e34b524d3cf62fed03d2dd1f45ce65/lib/src/index.ts#L16

We use nuxt generate to generate static pages for our projects. Because it is not being viewed in the Visual Editor at the time of generation and the published version is requested, the bind event will of course not detect the _editable property in the story.content API response. I therefore think the directive should listen to both the bind and update events. This way, when the static page is visited on the client from inside the editor, the update event will be fired and the data-blok-c attribute will be updated accordingly to fix the problem.

I was able to get it to work with the code snippet below.

const updateFn: DirectiveFunction = (el, {
  value,
  oldValue
}) => {
  // Return early if nothing changes.
  if (
    !value?._editable 
    || value?._editable === oldValue?._editable
  ) {
    return;
  }

  const options = storyblokEditable(value);
  el.setAttribute("data-blok-c", options["data-blok-c"]);
  el.setAttribute("data-blok-uid", options["data-blok-uid"]);
  el.classList.add("storyblok__outline");
};

const vEditableDirective = { bind: updateFn, update: updateFn };

Just to rule out. I'm using the draft version when viewed in the editor and I'm using the preview API key.

Reproduction

n/a

Steps to reproduce

  1. Generate static pages using nuxt generate.
  2. Open Visual Editor and click on any component with v-editable enabled.

System Info

vue 2.7.14
@storyblok/nuxt-2 2.0.11
@storyblok/vue-2 3.0.11
@storyblok/js 2.2.6

OS: macOS 13.4.1
Node: 18.16.0
Yarn: 1.22.19
Chrome: 115.0.5790.114

Used Package Manager

yarn

Error logs (Optional)

No response

Validations

manuelschroederdev commented 1 year ago

Hi @mandalornl,

the v-editable is not designed or expected to work with statically generated sites. It is exclusively to be used for preview environments.

I'm not sure why you would want to use it in a production environment that is not viewed in Visual Editor and thus requires no interactivity with the Storyblok Bridge. Could you please elaborate? 🙂

mandalornl commented 1 year ago

@manuelschroederdev Our production environment uses static pages exclusively to host our projects, but we make use of Nuxt preview mode to enable the Storyblok Bridge and use the draft version on all API calls. This happens only when viewed in the Visual Editor. However, when pages are generated during our CI/CD pipeline, the published version is used (for obvious reasons) and the _editable property is missing from the API response (also for obvious reasons). Therefore, the data-blok-c attribute is updated only if the update directive event is also triggered in preview mode. Then click events will work as expected when viewed in the Visual Editor.

I hope this clarifies the issue.

manuelschroederdev commented 1 year ago

@mandalornl I understand. I'd suggest using two completely separate environments. One using the preview access token, fetching draft stories, and running nuxt build, the other one using the public access token, fetching published stories, and running nuxt generate. You could set this up as two projects in Vercel/Netlify/whatever you're using, using the same code base and repository, just differentiating via environment variables.

mandalornl commented 1 year ago

@manuelschroederdev I decided to abandon @storyblok/nuxt-2 and opted to manually initialize loadStoryblokBridge and useStoryblokBridge from @storyblok/js when in preview mode. I also implemented my own Editable directive to handle bind and update events. It seems to work just fine now for our use case.

Thank you for your time :slightly_smiling_face: