Nuxt3+Apollo从Strapi CMS加载数据时遇500错误求助
解决Nuxt Apollo加载Strapi数据时的"Cannot read properties of null (reading 'homepage')"错误
核心问题分析
页面刷新时触发服务端渲染,useAsyncQuery返回的初始data为null,或是Strapi返回的homepage字段为null(比如内容未发布、权限未开放),导致模板中访问相关字段时抛出错误。热加载正常是因为Nuxt热重载复用了客户端已缓存的数据,避开了服务端初始化的空值问题。
解决方案
1. 检查Strapi内容与权限
- 确认Strapi后台的Homepage内容处于发布状态(不是草稿)
- 进入
Settings > Users & Permissions Plugin > Roles > Public,找到Homepage对应的权限,勾选find权限,保存后重启Strapi服务
2. 给查询结果设置默认值并处理加载状态
修改useAsyncQuery的调用,为返回数据设置兜底默认值,同时在模板中增加加载状态判断:
<script setup lang="ts"> import gql from "graphql-tag"; // 原有GET_HOMEPAGE查询代码 const GET_HOMEPAGE = gql` query Homepage { homepage { data { id attributes { body { __typename ... on ComponentContentTypeCtLandingSection { id title description images { data { id attributes { url alternativeText } } } link { id label url style unterseiten { data { id attributes { title slug } } } } } __typename ... on ComponentContentTypeCtGallery { id headline GalleryImage { id title image { data { id attributes { url alternativeText } } } } } __typename ... on ComponentContentTypeCtServices { id headline Card { title description icon { data { id attributes { url alternativeText } } } } } __typename ... on ComponentContentTypeCtCustomersCounter { id customers hours infusions founded } __typename ... on ComponentContentTypeCtText { id title basetext { id headline content } } } } } } } `; // 设置默认值避免空值报错 const { data, pending } = await useAsyncQuery(GET_HOMEPAGE, {}, { default: () => ({ homepage: { data: { attributes: { body: [] } } } }) }); </script> <template> <NavBar /> <!-- 加载状态提示 --> <div v-if="pending">加载中...</div> <div v-else v-for="(body, index) in data?.homepage?.data?.attributes?.body || []" :key="index"> <div v-if="body.__typename === 'ComponentContentTypeCtLandingSection'"> <ContentTypeLandingSection :body="body" :pos="index" /> </div> <div v-if="body.__typename === 'ComponentContentTypeCtCustomersCounter'"> <ContentTypeCustomerCounter :body="body" :pos="index" /> </div> <div v-if="body.__typename === 'ComponentContentTypeCtGallery'"> <ContentTypeGallery :body="body" :pos="index" /> </div> <div v-if="body.__typename === 'ComponentContentTypeCtServices'"> <ContentTypeServices :body="body" :pos="index" /> </div> <div v-if="body.__typename === 'ComponentContentTypeCtText'"> <ContentTypeText :body="body" :pos="index" /> </div> </div> <ContactForm /> <Footer /> </template>
3. 完善模板中的可选链处理
将模板中的遍历表达式改为data?.homepage?.data?.attributes?.body || [],确保即使中间任意层级为null/undefined,也能返回空数组让v-for正常执行,避免报错。
内容的提问来源于stack exchange,提问作者Nirwana
相关产品推荐
相关产品推荐

