在Next.js中,WordPress后台无对应数据时如何返回404页面?
问题描述
现有如下JSON分类配置数据:
[ { "taxonomy_slug": "product_cat", "taxonomy_name": "Categories", "frontend_slug": "product-category" }, { "taxonomy_slug": "product_tag", "taxonomy_name": "Tags", "frontend_slug": "product-tag" }, { "taxonomy_slug": "gift_box_size", "taxonomy_name": "Gift Box Sizes", "frontend_slug": "gift_box_size" }, { "taxonomy_slug": "product-type", "taxonomy_name": "Type", "frontend_slug": "product-type" } ]
需要为每个分类的frontend_slug生成对应页面,目标URL格式如下:
product-category/{category_item_slug}product-tag/{tag_item_slug}gift_box_size/{gift_box_size_item_slug}product-type/{product-type_item_slug}
当前文件结构:
|-> pages |-> [taxonomy-frontend-slug] |-> [taxonomy-item-slug].js
现有[taxonomy-item-slug].js代码如下:
import { useRouter } from 'next/router' import productTaxonomy from '@gb-data/productTaxonomy.json' export async function getStaticPaths() { const paths = productTaxonomy.map((taxonomyData) => { return { params: { "taxonomy-frontend-slug": `/${taxonomyData.frontend_slug}` } } }) console.log('getStaticPaths', paths) return { paths: paths, fallback: false, } } export async function getStaticProps(context) { console.log('getStaticProps context', context) return { props: {} } } export default function TaxonomyItemPage() { const router = useRouter() console.log('router.query', router.query); return ( <div> TaxonomyItemPage </div> ) }
需求:当WordPress后台不存在对应分类项数据时,返回404页面。
实现方案
要实现不存在的分类项返回404,需要从静态路径生成和动态数据校验两个环节处理:
1. 修正getStaticPaths,生成所有合法分类项路径
当前代码只生成了分类的前端slug路径,未包含具体分类项slug。需要先从WordPress获取每个分类下的所有项,再生成完整的合法路径。
假设你可以通过WordPress REST API获取分类项(接口格式示例:https://你的WP站点域名/wp-json/wp/v2/{分类slug}),修改getStaticPaths如下:
import productTaxonomy from '@gb-data/productTaxonomy.json' // 封装获取WordPress分类项的函数 async function getTaxonomyItems(taxonomySlug) { const res = await fetch(`https://your-wordpress-site.com/wp-json/wp/v2/${taxonomySlug}`) if (!res.ok) throw new Error(`获取${taxonomySlug}分类项失败`) return res.json() } export async function getStaticPaths() { // 遍历所有分类,批量获取每个分类下的项并生成路径 const allPaths = await Promise.all( productTaxonomy.map(async (taxonomy) => { const items = await getTaxonomyItems(taxonomy.taxonomy_slug) // 为每个分类项生成完整路径参数 return items.map(item => ({ params: { "taxonomy-frontend-slug": taxonomy.frontend_slug, "taxonomy-item-slug": item.slug } })) }) ) // 扁平化路径数组 const paths = allPaths.flat() return { paths, fallback: 'blocking' // 开启阻塞式回退,处理新增分类项的访问请求 } }
2. 在getStaticProps中校验分类项合法性,返回404
预生成的路径可能对应已被删除的分类项,因此需要在getStaticProps中再次校验当前访问的分类项是否存在,不存在则返回notFound: true触发404。
修改getStaticProps如下:
export async function getStaticProps(context) { const { params } = context const { "taxonomy-frontend-slug": frontendSlug, "taxonomy-item-slug": itemSlug } = params // 匹配当前前端slug对应的WordPress分类 const taxonomy = productTaxonomy.find(t => t.frontend_slug === frontendSlug) if (!taxonomy) { return { notFound: true } // 分类不存在,返回404 } // 获取该分类下的所有项,校验当前itemSlug是否有效 const items = await getTaxonomyItems(taxonomy.taxonomy_slug) const itemExists = items.some(item => item.slug === itemSlug) if (!itemExists) { return { notFound: true } // 分类项不存在,返回404 } // 若存在,返回分类项数据给页面组件 const itemData = items.find(item => item.slug === itemSlug) return { props: { taxonomy, itemData }, revalidate: 86400 // 可选:设置每日自动刷新页面缓存,同步WP后台内容 } }
3. 页面组件优化(可选)
开启fallback: 'blocking'后,首次访问未预生成的路径会触发服务器端渲染,可在组件中添加加载状态:
import { useRouter } from 'next/router' export default function TaxonomyItemPage({ taxonomy, itemData }) { const router = useRouter() // 处理阻塞式回退时的加载状态 if (router.isFallback) { return <div>加载中...</div> } return ( <div> <h1>{taxonomy.taxonomy_name}: {itemData.name}</h1> {/* 渲染分类项的具体内容 */} </div> ) }
关键说明
fallback: 'blocking':既保留预生成路径的性能优势,又能处理新增分类项的访问,避免合法新内容返回404。- 双重校验:预生成路径+
getStaticProps实时校验,确保已删除的分类项访问会返回404。 - 缓存策略:
revalidate参数可定期刷新页面缓存,保证前端内容与WordPress后台同步。
内容的提问来源于stack exchange,提问作者jameshwart lopez
相关产品推荐
相关产品推荐

