Gatsby集成Sanity查询单篇博客内容错配问题如何解决
问题定位
你的判断完全正确,问题根源就是src/templates/blog.js中的GraphQL查询缺少匹配规则:当前查询没有携带任何过滤参数,Gatsby执行查询时会默认返回排序规则下的第一条Sanity博客数据,和当前访问的页面路由完全不绑定,所以不管点击哪篇文章链接,页面都会渲染固定的那篇内容。
修复方法
1. 修改模板页的GraphQL查询
给查询添加slug变量,通过路由传入的slug参数匹配对应文章,替换原有查询代码即可:
// src/templates/blog.js export const query = graphql` query BlogPostBySlug($slug: String!) { sanityPost(slug: { current: { eq: $slug } }) { id slug { current } title publishedAt(formatString: "MMM Do, YYYY") _rawBody } } ` const BlogPost = ({ data }) => { return ( <Layout> <h1>{data.sanityPost.title}</h1> <p>{data.sanityPost.publishedAt}</p> <PortableText value={data.sanityPost._rawBody} /> </Layout> ) } export default BlogPost
这里的$slug是Gatsby自动从页面上下文(context)中读取的查询变量,不需要手动传参。
2. 确认gatsby-node.js的页面创建逻辑
检查项目根目录的gatsby-node.js文件,确保创建博客详情页时已经把文章slug传入了页面上下文,参考正确实现:
// gatsby-node.js const path = require('path') exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions const blogPostTemplate = path.resolve('./src/templates/blog.js') // 查询所有博客的slug const res = await graphql(` query { allSanityPost { nodes { slug { current } } } } `) // 为每篇博客生成独立页面 res.data.allSanityPost.nodes.forEach(post => { createPage({ path: `/blog/${post.slug.current}`, // 页面访问路径,和列表页跳转地址保持一致 component: blogPostTemplate, context: { slug: post.slug.current // 传入slug作为查询匹配依据 } }) }) }
3. 核对列表页跳转路径
确认博客列表页的文章跳转链接和上面createPage定义的path规则完全一致,避免路径不匹配导致的参数传递错误。
注意:修改gatsby-node.js或者模板的GraphQL查询后,必须停止当前运行的Gatsby进程,执行
gatsby clean清空缓存后再重新启动开发服务,避免旧数据缓存导致修改不生效。
修改完成重新编译后,点击不同文章链接就能正常加载对应内容了。
内容的提问来源于stack exchange,提问作者simonxcode
相关产品推荐
相关产品推荐

