Shopify Hydrogen项目中无法使用StoryblokComponent求助
解决Shopify Hydrogen中StoryblokComponent无法正常工作的问题
问题根源
报错TypeError: Cannot read properties of undefined (reading 'page')的核心原因是:Hydrogen基于React Server Components(RSC),你当前的Storyblok组件注册和渲染逻辑混合了服务器端与客户端环境——storyblokInit在服务器组件(App.server.jsx)中执行,但注册的Page、Teaser是客户端组件(.client.jsx后缀),服务器端无法访问这些客户端组件,导致StoryblokComponent找不到对应的page组件。
解决方案
1. 迁移Storyblok初始化到客户端专属组件
创建StoryblokProvider.client.jsx,将组件注册和初始化逻辑放在客户端环境执行:
// components/storyblok/StoryblokProvider.client.jsx 'use client'; import { storyblokInit, apiPlugin } from '@storyblok/react'; import Page from './Page.client'; import Teaser from './Teaser.client'; storyblokInit({ accessToken: 'xxxxxxx', use: [apiPlugin], storyblokComponents: { page: Page, teaser: Teaser, }, }); export default function StoryblokProvider({ children }) { return <>{children}</>; }
2. 在根组件中引入客户端Provider
修改App.server.jsx,用上述Provider包裹整个应用,确保客户端初始化逻辑触发:
// App.server.jsx import StoryblokProvider from './components/storyblok/StoryblokProvider.client'; export default function App({ Component, pageProps }) { return ( <StoryblokProvider> <Component {...pageProps} /> </StoryblokProvider> ); }
3. 创建客户端渲染组件封装StoryblokComponent
StoryblokComponent依赖客户端上下文,不能直接在服务器组件中使用,因此创建StoryblokRenderer.client.jsx:
// components/storyblok/StoryblokRenderer.client.jsx 'use client'; import { StoryblokComponent } from '@storyblok/react'; export default function StoryblokRenderer({ blok }) { return <StoryblokComponent blok={blok} />; }
4. 修改页面组件使用客户端渲染器
在index.server.jsx中替换直接使用的StoryblokComponent为上述客户端渲染器,同时添加数据存在性检查:
// index.server.jsx import StoryblokRenderer from './components/storyblok/StoryblokRenderer.client'; import { getStoryblokData } from './utils/storyblok'; export default function Home() { const storyblokData = getStoryblokData('home'); // 避免数据未加载或请求失败时的undefined报错 if (!storyblokData?.story?.content) { return <div>加载中...</div>; } return ( <> <StoryblokRenderer blok={storyblokData.story.content} /> </> ); }
额外说明
- Hydrogen的服务器组件无法访问客户端专属的状态、上下文或组件,所有依赖客户端环境的逻辑必须放在带
'use client'指令或.client.jsx后缀的组件中。 - 保持数据获取逻辑在服务器组件中(
getStoryblokData),符合Hydrogen的性能优化原则,仅将渲染逻辑中依赖客户端的部分拆分出去。
内容的提问来源于stack exchange,提问作者jennEDVT
相关产品推荐
相关产品推荐

