Next.js 13无法获取Shopify Product Handle的问题求助
解决方案
首先明确:Next.js 13 有两种路由模式(App Router 和 Pages Router),你的错误核心是路由API使用不当,结合你的代码场景,分两种情况解决:
情况1:使用 App Router(Next.js 13 默认模式)
如果你的项目是基于 app/ 目录的App Router:
- 修正路由文件结构:确保动态路由页面的路径为
app/products/[handle]/page.js([handle]是动态参数占位符,必须用方括号包裹) - 替换路由API:App Router 不再使用
useRouter,而是用useParams来获取动态路由参数
修正后的 page.js 代码:
'use client'; // 必须加这个指令,因为useParams是客户端组件API import { useParams } from 'next/navigation'; function ProductDetails() { const params = useParams(); const productHandle = params.handle; // 这里的handle对应路由里的[handle] console.log("Product Handle:", productHandle); // 后续可以用这个handle发起Shopify GraphQL查询 return ( <div> <h1>Product Details</h1> {productHandle && <p>当前商品Handle:{productHandle}</p>} </div> ); } export default ProductDetails;
同时,你的 Homepage.js 里的 Link 无需修改(href={/products/${product.node.handle}} 是正确的),注意去掉多余的 legacyBehavior(App Router 的 Link 不需要这个属性):
{products.map((product) => ( <Link key={product.node.id} href={`/products/${product.node.handle}`}> {/* 商品卡片内容 */} </Link> ))}
情况2:使用 Pages Router(基于 pages/ 目录)
如果你的项目是传统的 Pages Router:
- 修正路由文件结构:动态路由页面路径应为
pages/products/[handle].js - 修正
useRouter的用法:router.query直接包含动态参数,无需解构query属性,同时要处理参数未加载的情况
修正后的代码:
import { useRouter } from 'next/router'; function ProductDetails() { const router = useRouter(); const { handle } = router.query; // 直接从router.query取handle // 因为Next.js在客户端 hydration 时可能会先返回undefined,所以要做判断 if (!handle) { return <div>加载中...</div>; } console.log("Product Handle:", handle); return ( <div> <h1>Product Details</h1> <p>当前商品Handle:{handle}</p> </div> ); } export default ProductDetails;
错误原因说明
你遇到的 TypeError: Cannot destructure property 'query' of 'router.query' as it is undefined:
- 若用App Router:
useRouter是 Pages Router 的API,在App Router中调用时返回的对象没有query属性,导致router.query为 undefined - 若用Pages Router:
router.query在页面初始加载时可能为 undefined(客户端 hydration 阶段),直接解构会报错,需要先判断存在性
内容的提问来源于stack exchange,提问作者Vivek Viradia
相关产品推荐
相关产品推荐

