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

Next 14中generateMetaData无法将id参数设为页面标题求助

问题:Next.js无法将路由参数id设置为页面标题

我刚学习Next.js,遇到一个问题:无法将路由参数id设置为页面标题。id能够正常获取到字符串,且Layout配置正确。我尝试使用generateStaticParams,但也未成功。

相关代码

src/app/characters/[id]/page.tsx

import graphqlClient from "@/lib/client";
import GET_CHARACTER from "@/lib/graphql/character";
import { CharacterDetail } from "@/components/characters";
import { notFound } from "next/navigation";
import { Metadata } from "next";

type Props = {
  params: {
    id: string;
  };
};
export async function generateMetaData({ params }: Props): Promise<Metadata> {
  const id = params.id;
  console.log(id);
  return { title: id };
}

const CharacterPage = async ({ params }: Props) => {
  try {
    await generateMetaData({ params });
    const { id } = params;
    const {
      data: { character },
    } = await graphqlClient.query<{ character: Character }>({
      query: GET_CHARACTER,
      variables: { id },
    });
    return (
      <div className="container">
        <CharacterDetail character={character} />
      </div>
    );
  } catch (error) {
    return notFound();
  }
};

export default CharacterPage;

src/app/layout.tsx

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import React from "react";
import { HeaderLayout, FooterLayout, MainLayout } from "@/components/layout";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: {
    template: "%s | Rick and Morty",
    default: "Rick and Morty",
  },
  description: "Rick and Morty by ortima",
};
interface RootLayoutProps {
  children: React.ReactNode;
}
const RootLayout: React.FC<RootLayoutProps> = ({ children }) => {
  return (
    <html lang="en">
      <body className={inter.className}>
        <HeaderLayout />
        <MainLayout>{children}</MainLayout>
        <FooterLayout />
      </body>
    </html>
  );
};

export default RootLayout;

解决方法

1. 修正元数据生成函数的拼写错误

Next.js 13+ App Router中,用于生成页面元数据的标准函数名是generateMetadata,你代码里写成了generateMetaData(最后一个字母为d而非t),这会导致Next.js无法识别该函数,自然不会应用你设置的标题。

修改后的函数:

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const id = params.id;
  console.log(id);
  return { title: id };
}

2. 移除手动调用元数据函数的冗余代码

页面组件里不需要手动调用generateMetadata,Next.js会自动在服务器端执行该函数生成元数据,直接删除以下代码:

// 删除此行
await generateMetaData({ params });

3. 进阶:显示角色名称而非id(可选)

如果想让页面标题显示角色真实名称而非id,可以在generateMetadata中调用GraphQL接口获取角色数据,返回角色名称作为title:

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  try {
    const { id } = params;
    const {
      data: { character },
    } = await graphqlClient.query<{ character: Character }>({
      query: GET_CHARACTER,
      variables: { id },
    });
    return { title: character.name };
  } catch (error) {
    return { title: `Character ${params.id}` };
  }
}

修改完成后,页面标题会自动应用设置的值,结合Layout中的模板字符串,最终会显示类似1 | Rick and Morty(或Rick Sanchez | Rick and Morty)的标题。

内容的提问来源于stack exchange,提问作者Timur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:27