Gatsby+Contentful博客修改文章目录后首页Link链接显示undefined求助
解决Gatsby+Contentful博客首页链接显示undefined的问题
问题描述
我用模板搭建了基于Gatsby和Contentful的个人博客,尝试修改文章的子目录结构。目前文章的URL可以正常访问,但首页的链接无法正常工作:将<Link>组件的to属性从/${post.slug}修改为/${post.category}/${post.slug}后,生成的链接变为http://localhost:8000/undefined/(文章slug),而非Contentful中设置的分类名称。另外,使用/blog/这类固定子目录或设置to为/${post.slug}/${post.slug}时,链接可正常工作。
相关组件代码:
import React from 'react' import { Link } from 'gatsby' import { GatsbyImage } from 'gatsby-plugin-image' import Container from './container' import Tags from './tags' import * as styles from './article-preview.module.css' const ArticlePreview = ({ posts }) => { if (!posts) return null if (!Array.isArray(posts)) return null return ( <Container> <ul className={styles.articleList}> {posts.map((post) => { return ( <li key={post.slug}> <Link to={`/${post.category}/${post.slug}`} className={styles.link}> <GatsbyImage alt="" image={post.heroImage.gatsbyImageData} /> <h2 className={styles.title}>{post.title}</h2> </Link> <div dangerouslySetInnerHTML={{ __html: post.description.childMarkdownRemark.html, }} /> <div className={styles.meta}> <small className="meta">{post.publishDate}</small> <Tags tags={post.tags} /> </div> </li> ) })} </ul> </Container> ) } export default ArticlePreview
解决建议
1. 验证GraphQL查询是否包含category字段
post.category显示undefined最常见的原因是组件接收的posts数据里根本没有category字段。
- 打开Gatsby的GraphQL playground(
http://localhost:8000/___graphql),执行查询确认category字段是否存在并返回有效值:
query { allContentfulPost { nodes { slug category title # 其他你需要的字段 } } }
- 如果查询结果里没有category,需要修改获取posts数据的GraphQL查询,把category字段加进去。
2. 处理Contentful中category的字段类型
如果Contentful里的category是引用类型(比如关联了独立的分类内容模型),而不是纯文本字段,那post.category是一个对象,不能直接使用,需要取它的具体属性:
- 比如分类模型里有
slug或name字段,链接要改成:
<Link to={`/${post.category.slug}/${post.slug}`} className={styles.link}>
- 可以在GraphQL playground里查看category对象的结构,确认需要取用的属性名。
3. 添加默认值避免异常
为了防止category为空或未定义时链接出错,可以给category设置 fallback 值:
- 如果是纯文本字段:
const category = post.category || 'blog' <Link to={`/${category}/${post.slug}`} className={styles.link}>
- 如果是引用类型,先判断对象是否存在:
const categorySlug = post.category?.slug || 'blog' <Link to={`/${categorySlug}/${post.slug}`} className={styles.link}>
4. 确认gatsby-node.js的页面路径配置
虽然文章URL能正常访问,但要确保页面生成时的路径和首页Link的格式完全一致:
- 打开
gatsby-node.js,检查createPages中的路径生成代码,比如:
exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions const result = await graphql(` query { allContentfulPost { nodes { slug category { slug } } } } `) result.data.allContentfulPost.nodes.forEach(node => { createPage({ path: `/${node.category.slug}/${node.slug}`, component: require.resolve('./src/templates/post.js'), context: { slug: node.slug, }, }) }) }
确保path的格式和首页Link的to完全匹配,避免因路径不一致导致的跳转问题。
内容的提问来源于stack exchange,提问作者kawamottyan
相关产品推荐
相关产品推荐

