Gatsby5中Contentful富文本无引用字段,无法获取slug问题
解决Gatsby 5中Contentful富文本ENTRY_HYPERLINK无法获取slug的问题
核心问题
contentful/rich-text-react-renderer 不会自动将你查询到的references数据关联到富文本的链接节点上,所以在处理INLINES.ENTRY_HYPERLINK时,node.data.target仅包含基础sys信息,需要手动关联查询到的引用数据。
步骤1:完善GraphQL查询
确保查询中包含富文本的raw字段(渲染富文本必需),以及完整的引用数据:
query MyQuery { allContentfulPost { nodes { body { raw # 必须包含,用于解析富文本结构 references { ... on ContentfulAlbum { node_locale contentful_id __typename id slug } } } } } }
步骤2:手动关联引用数据并渲染链接
在组件中,先将查询到的references转换为以contentful_id为键的映射表,然后在自定义renderNode函数中匹配链接目标,生成动态URL:
import { renderRichText } from "gatsby-source-contentful/rich-text" import { INLINES } from "@contentful/rich-text-types" const PostComponent = ({ post }) => { // 将引用数据转为映射表,方便快速查找 const referenceMap = post.body.references.reduce((acc, ref) => { acc[ref.contentful_id] = ref return acc }, {}) const renderOptions = { renderNode: { [INLINES.ENTRY_HYPERLINK]: (node, children) => { // 通过sys.id匹配对应的引用数据 const targetContentfulId = node.data.target.sys.id const album = referenceMap[targetContentfulId] // 降级处理:找不到引用时返回空链接 if (!album) return <a href="#">{children}</a> // 生成动态URL const dynamicUrl = `${album.node_locale}/music/${album.slug}` return <a href={dynamicUrl}>{children}</a> }, }, } return <div className="post-content">{renderRichText(post.body, renderOptions)}</div> } export default PostComponent
关键说明
node.data.target.sys.id对应Contentful中的contentful_id,是匹配引用数据的唯一标识- 映射表的作用是避免每次查找都遍历数组,提升性能
- 加入降级处理可以防止因引用数据缺失导致的页面崩溃
内容的提问来源于stack exchange,提问作者Cmorales
相关产品推荐
相关产品推荐

