Closed grantspilsbury closed 3 weeks ago
Hey @grantspilsbury ! I tried the stackblitz link with a couple of changes - I just removed the preview/config options for testing. And it works for me!
What I mean is the setup you have works. Regarding questions -
Also - just a suggestion, since you're already fetching the story in StaticProps, you don't need to fetch that again, you can just use useStoryblokState
Here is the code, that I tried (it is yours, I just removed a few things to test and added useStoryblokState as well, though it works with useStoryblok too) Please let me know if you face more issues, or if live editing is still an issue. You can use this to compare and see if there was anything that was causing the issue.
Also, another quick question - is it happening on dev or prod or both?
import {
storyblokInit,
apiPlugin,
useStoryblok,
getStoryblokApi,
storyblokEditable,
useStoryblokState
} from "@storyblok/react";
import React from 'react'
// Function to get story by slug
const getStoryBySlug = async (slug) => {
const params = {
version: 'draft',
cv: Date.now()
}
const storyblokApi = getStoryblokApi()
const { data } = await storyblokApi.get(`cdn/stories/${slug}`, params)
return data.story
}
export const mapPanel = (data) => ({
title: data.title.replace(/(^"|"$)/g, '')
})
// Sample Panel component
const Panel = ({ title }) => (
<div className="panel">
{title}
</div>
)
const componentMap = {
panel: [Panel, mapPanel]
}
// Components map
const components = {
panel: Panel,
// Add other components here
}
// Initialize Storyblok
storyblokInit({
accessToken: 'Td6uuk4Q2JYJH3uzOuOyIgtt',
use: [apiPlugin],
components
})
// Custom component mapper
const ComponentMapper = ({ blok }) => {
const [Component, mapFn] = componentMap[blok.component] ?? []
const props = mapFn ? mapFn(blok) : {}
return (
<div {...storyblokEditable(blok)} key={blok._uid}>
<Component {...props} />
</div>
)
}
// Home component
const Home = ({ story }) => {
const editableContent = useStoryblokState(story)
const content = editableContent?.content || {}
const { panel = [], body = [] } = content
return (
<main>
{(panel ?? []).map((blok) => (
<ComponentMapper blok={blok} key={blok._uid} />
))}
{(body ?? []).map((blok) => (
<ComponentMapper blok={blok} key={blok._uid} />
))}
</main>
)
}
export default Home
// Static props for the Home component
export const getStaticProps = async (context) => {
console.log(context)
const story = await getStoryBySlug('home')
return {
props: {
story
},
revalidate: 3600
}
}```
arorachakit
Thanks for the help. Can you help me understand 2 things: 1) What could be the reasons that nextJs draftMode is working when I run my app outside Storyblok (http://localhost:3000/api/draft?secret=corp-secret&slug=pages/) but when I run it inside storyblok (https://localhost:3010/api/draft?secret=corp-secret&slug=pages/) and view it in the Storyblok preview window draftMode().isEnabled is always false. 2) What could the reasons be for the storyblok-v2-latest.js script not to load when I run storyblokInit? Previously I could see it in the networks tab but since moving to nextjs 14 with /app directory I can’t get it to load. I have tried initialising it in client and server components as well as the StoryblokProvider. I can print out config.storyblokApiKey and it is initialising with the correct key.
'use client'
import { storyblokInit, apiPlugin } from '@storyblok/react'
import config from 'config'
interface Props {
children: React.ReactNode
}
console.log(config.storyblokApiKey)
storyblokInit({
accessToken: config.storyblokApiKey,
use: [apiPlugin],
apiOptions: {
cache: {
clear: 'auto',
type: 'memory'
}
},
bridge: process.env.NODE_ENV !== 'production'
})
Hey @grantspilsbury ! I hope the previous issue was resolved.
The reason of draft mode not working in the visual editor could be (most probably) related to the cookie and it's same site policy - you need to have same site as None for the cookie. As Storyblok is loading your content in an iframe, this could be the reason. Please take a look here, this is Next 12 example but should be similar for Next 14 - https://github.com/storyblok/next.js-ultimate-tutorial/blob/main/pages/api/preview.js#L20
A couple of months ago we implemented a basic check to not load the bridge outside the visual editor, that could be the issue. Is it not even loading in the visual editor?
For loading it outside the Visual Editor, simply append _storyblok_tk
to the URL and it should work as expected.
I was using next: 14.2.3. I downgraded to next: 13.4.2 and it loads as expected
@grantspilsbury - do you mean keeping the same setup, it is an issue with different versions?
I have a couple of more questions - Is it happening for the complete app, or just for any specific pages?
Also, is it happening inside the Visual Editor or outside that?
Is the live editing also not working?
Also, another quick question - is this happening with just app directory?
Here is small project I did a couple of months ago with Next 14 and app directory - https://github.com/arorachakit/Restaurant-Guide-with-Next.js-and-Storyblok I can see the bridge load in the networks tab, please take a look - this might help.
Also let me know if there is still an issue, maybe you can share a small setup if that is something different to what you already shared. :)
It was working and then I started messing with next and @storyblok/react versions and now I can't get it to load the script.
On a side note are you able to share a tsconfig.json setup as I am getting typescript errors on: import { storyblokEditable } from '@storyblok/react/rsc'
Cannot find module '@storyblok/react/rsc' or its corresponding type declarations.
There are types at '/website/node_modules/@storyblok/react/dist/types/rsc/index.d.ts', but this result could not be resolved under your current 'moduleResolution' setting. Consider updating to 'node16', 'nodenext', or 'bundler'.
My config file is:
{
"compilerOptions": {
"baseUrl": "./src",
"lib": ["esnext", "dom", "dom.iterable"],
"allowJs": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"outDir": "./dist",
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
},
"allowSyntheticDefaultImports": true,
"target": "es6",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"skipLibCheck": true
},
"include": ["./src/**/*", "next-env.d.ts", ".next/types/**/*.ts"],
"exclude": ["node_modules", "migrations"]
}
@grantspilsbury - Sure, also please take a look at the project I shared. It might be a good reference point.
For the tsconfig - the issue could be moduleResolution, please try changing it to nodenext
or bundler
instead of node
. Let me know if it works with that :)
https://github.com/arorachakit/Restaurant-Guide-with-Next.js-and-Storyblok
Thanks for the help. Here's a sample repo: https://github.com/grantspilsbury/storyblok_nextjs_14_live_editing_preview The script is loading but the live editing is not working. Do you see any obvious issues?
I am mapping the incoming data from Storyblok and then displaying the component:
const ComponentMapper: React.FC<Props> = ({ blok }) => {
const [Component, mapFn] = componentMap[blok.component]
return (
<div {...storyblokEditable(blok)} key={blok._uid}>
<Component {...mapFn(blok)} />
</div>
)
}
export default ComponentMapper
// example of mapFn
export const mapTitle = (data) => ({
title: data.title ?? '',
description: data.description ?? '',
})
// example of Component
const Title: React.FC<Props> = ({ title, description }) =>
<div>
<ComplicatedTitle title={title} />
<div>{description}</div>
</div>
export default Title
I can see the data-block-c properties but it isn't live editing.
I see there is a StoryblokStory and StoryblokComponent which I'm not using. And because of that I'm not adding the components to storyblokInit. Is this incorrect?
Hey @grantspilsbury - the sample project isn't up to date I guess. In any case, I recommend you reading the readme of this repo https://github.com/storyblok/storyblok-react?tab=readme-ov-file#nextjs-using-app-router---live-editing-support along with the tutorial we have - https://www.storyblok.com/tp/add-a-headless-cms-to-next-js-13-in-5-minutes
It takes you through the two approaches - live editing and complete server side. Yes, StoryblokStory along with not using the StoryblokProvider can be the issue.
Please take a look at the resources to know more - and in case you want to have your own mapper, please feel free to check the code of StoryblokStory and StoryblokComponent in this repo itself.
Within storyblok's visual editor the v2 script loads when viewing a page but it doesnt load it when setting the draft / preview
It loads on: https://localhost:3010/pages/
but not on: https://localhost:3010/api/draft?secret=secret&slug=pages/
I get a 500 error (Failed to load resource: the server responded with a status of 500 (Internal Server Error)
) which is logged in dev console but not in terminal. This is while using the proxy (https://localhost:3010 → http://localhost:3000
) at https://localhost:3010/api/draft?secret=secret&slug=pages/
Do you think I have a Storyblok setup issue or it's not meant to load when access the draft route or maybe something to do with my draft route code:
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const slug = searchParams.get('slug') ?? '/'
const story = await getPageBySlug(slug)
if (!story) {
return new Response('Invalid slug', { status: 401 })
}
draftMode().enable()
cookies()
.getAll()
.forEach((cookie) => {
cookies().set(cookie.name, cookie.value, {
sameSite: 'none',
secure: true
})
})
return new Response(null, {
status: 307,
headers: {
Location: `/${story.full_slug}`
}
})
}
Edit: on further inspection I also get the 500 error when viewing a page without the api/draft route
https://localhost:3010/pages?_storyblok=1192xxx&_storyblok_c=home&_storyblok_version=&_storyblok_lang=default&_storyblok_release=0&_storyblok_rl=1718953xxx&_storyblok_tk%5Bspace_id%5D=69xxx&_storyblok_tk%5Btimestamp%5D=171895xxxx&_storyblok_tk%5Btoken%5D=b6f0520ea5a43c4d15xxx
But the script does load
Hey @grantspilsbury ! There can be many reasons for the 500 error, not sure if I can help much here.
As the issue is already closed and we initially had a different topic - I recommend you taking a look at our discord. We also have a next.js channel over there, maybe you can find something over there. Also a couple of setups can be with the draft mode as well. That would be the correct place for such questions, the community is pretty awesome!
Please feel free to open any new issues if you find anything related to the SDK - and feel free to take a look at tutorials to see the setup and compare.
Thank you!
Hi everyone, Im getting an error when doing live editing, also cannot toggle, for example if i change the text, or choose another banner, then the rest component become disappear, like this:
Thanks everyone
this only occurs when I changes some text, or live adjust the component, then it trigger to this, refresh will be revert to normal, but then the purpose of live editing become not able to perform
Is this because of the API configure or the bridge, wonder what causing this issue. Thanks
Describe the issue you're facing
I am trying to get live editing working for @storyblok-react on my Nextjs 14 site (not using App router). The HTML looks ok but live editing is not working. The latest version of https://app.storyblok.com/f/storyblok-v2-latest.js is being loaded.
This is the code I have added:
When logging editable content it also looks ok:
The rendered HTML looks something like this![Screenshot 2024-06-11 at 11 26 34 AM](https://github.com/storyblok/storyblok-react/assets/3175433/95df54fc-a6a2-49b7-9f7b-8e74c791a5a4)
Reproduction
https://stackblitz.com/edit/stackblitz-starters-uh3eae?file=pages%2Findex.jsx
Steps to reproduce
No response
System Info
Used Package Manager
npm
Error logs (Optional)
No response
Validations