Next.js 13客户端组件添加自定义标题时出现JSON解析错误
Next.js 13 客户端组件使用metadata触发JSON.parse错误的解决方案
问题重现
在Windows 11环境下使用Next.js 13开发时,给标记了"use client"的页面组件导出metadata后,出现以下错误:
error - SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (<anonymous>)
移除export const metadata后代码恢复正常,且服务端组件中使用metadata无异常。
核心原因
Next.js 13的metadata机制仅支持在服务端组件中定义,因为metadata是在服务端渲染阶段生成并注入到HTML中的。客户端组件运行在浏览器环境,无法参与服务端的metadata解析流程,强行导出会导致Next.js内部解析逻辑出错(错误中的"u"来自undefined被尝试JSON解析时的首字符)。
解决方案
方案1:拆分服务端/客户端代码(推荐)
将metadata定义和客户端交互逻辑拆分到不同文件:
- 创建服务端组件文件
page.js,负责定义metadata并引入客户端组件:
export const metadata = { title: `Login - ${process.env.NEXT_PUBLIC_APP_NAME || '默认应用名'}`, }; import LoginClient from './LoginClient'; export default function LoginPage() { return <LoginClient />; }
- 创建客户端组件文件
LoginClient.js,保留原有交互逻辑:
"use client"; import { useState } from "react"; const LoginClient = () => { const [formValues, setFormValues] = useState({ email: "", password: "", }); const handleFormChange = (event) => { const { name, value } = event.target; setFormValues((prevState) => { const newValue = value == null ? "" : value; return { ...prevState, [name]: newValue }; }); }; return <h1>This is the login page</h1>; }; export default LoginClient;
方案2:单文件混合服务端/客户端代码
如果不想拆分文件,可将metadata定义放在"use client"指令之前(Next.js允许同一文件中服务端代码在前,客户端代码在后):
// 服务端代码:定义metadata export const metadata = { title: `Login - ${process.env.NEXT_PUBLIC_APP_NAME || '默认应用名'}`, }; // 客户端代码:组件逻辑 "use client"; import { useState } from "react"; const LoginPage = () => { const [formValues, setFormValues] = useState({ email: "", password: "", }); const handleFormChange = (event) => { const { name, value } = event.target; setFormValues((prevState) => { const newValue = value == null ? "" : value; return { ...prevState, [name]: newValue }; }); }; return <h1>This is the login page</h1>; }; export default LoginPage;
额外检查
确保环境变量NEXT_PUBLIC_APP_NAME已在.env文件中正确配置,避免出现undefined值影响标题生成:
NEXT_PUBLIC_APP_NAME=你的应用名称
内容的提问来源于stack exchange,提问作者PugProvoleta
相关产品推荐
相关产品推荐

