Astro获取Sanity数组slug报错:Cannot read properties of undefined (reading 'current')
问题解决:Sanity数组元素生成Astro静态路径
错误原因
art.images是数组类型,直接访问art.images.slug会触发Cannot read properties of undefined错误——数组本身没有slug属性,只有数组内的每个对象才包含该属性。- 用
art.images[0].slug仅能获取数组第一个元素,无法遍历所有元素生成对应静态路径。
解决方案步骤
1. 优化Sanity查询(可选但推荐)
修改查询语句,只获取需要的字段,减少冗余数据传输:
export async function getAllArts() { const query = `*[_type == 'art']{ year, images[]{ image, title, slug } }`; const data = await useSanityClient().fetch(query); return data; }
2. 重构getStaticPaths生成所有路径
遍历每个art文档,再遍历其images数组,将每个图片元素转换为独立静态路径,同时处理空数组避免报错:
export async function getStaticPaths() { const allArtInfo = await getAllArts(); // 展开所有art的images数组,生成每个图片对应的路径 const paths = allArtInfo.flatMap(art => { // 若当前art无图片,返回空数组跳过 if (!art.images || art.images.length === 0) return []; // 遍历每个图片,生成路径参数与组件props return art.images.map(image => ({ params: { slug: image.slug.current }, props: { art, // 传递完整art文档数据 image // 传递当前图片的详细数据 } })); }); return paths; }
3. 更新Props类型定义
适配新的props结构,明确数据类型:
export interface Props { art: { year: string; images: Array<{ image: any; title: string; slug: { current: string }; }>; }; image: { image: any; title: string; slug: { current: string }; }; }
4. 组件内使用目标数据
直接通过props调用当前图片的信息,简化渲染逻辑:
--- // ... 其他导入代码 const { art, image } = Astro.props; const seo = { title: image.title, description: `Artwork from ${art.year}` } --- <Layout seo={seo}> <h1>{image.title}</h1> <p>Year: {art.year}</p> {/* 可结合astro-sanity的图片工具渲染图片 */} </Layout>
关键说明
- 使用
flatMap替代map:将嵌套的images数组展开为一维数组,确保每个图片对应一个独立静态路径。 - 空数组判断:避免部分
art文档无图片时触发运行错误。 - 直接传递图片数据:组件内无需再从
art.images中查找目标元素,直接使用imageprops即可。
内容的提问来源于stack exchange,提问作者Create and Choose
相关产品推荐
相关产品推荐

