You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:46:34