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

如何在兼容Next.js 12与13的服务端组件中获取最终URL路径

在Next.js 12(Pages Router)和13(App Router)服务端组件中获取页面URL路径

针对同时适配Next.js 12稳定版和13测试版的服务端组件,需根据两种路由系统的差异分别实现路径获取逻辑,以下是具体方案:

Next.js 12(Pages Router)场景

Pages Router中,服务端组件无法直接获取请求上下文,需通过页面的getServerSideProps或getStaticProps函数提取路径信息,再通过props传递给组件。

服务端渲染(SSR)页面

通过getServerSideProps的context参数获取路径:

// pages/[slug].js
export async function getServerSideProps(context) {
  // 获取包含查询参数的完整路径(不含域名)
  const resolvedPath = context.resolvedUrl;
  // 获取请求的域名(从请求头中提取)
  const host = context.req.headers.host;
  // 拼接完整URL
  const fullUrl = `https://${host}${resolvedPath}`;

  return {
    props: { resolvedPath, fullUrl },
  };
}

// 服务端组件接收路径参数
export default function PostPage({ resolvedPath, fullUrl }) {
  return (
    <div>
      <p>页面路径:{resolvedPath}</p>
      <p>完整URL:{fullUrl}</p>
    </div>
  );
}

静态生成(SSG)页面

静态生成时无实时请求上下文,需通过context.params拼接路径,结合环境变量的域名生成完整URL:

// pages/posts/[slug].js
export async function getStaticProps(context) {
  const { slug } = context.params;
  const pagePath = `/posts/${slug}`;
  // 需在.env文件中配置NEXT_PUBLIC_BASE_URL为站点域名(如https://example.com)
  const fullUrl = `${process.env.NEXT_PUBLIC_BASE_URL}${pagePath}`;

  return {
    props: { pagePath, fullUrl },
  };
}

export async function getStaticPaths() {
  return {
    paths: [{ params: { slug: 'first-post' } }],
    fallback: false,
  };
}

export default function PostPage({ pagePath, fullUrl }) {
  return (
    <div>
      <p>页面路径:{pagePath}</p>
      <p>完整URL:{fullUrl}</p>
    </div>
  );
}

Next.js 13(App Router)场景

App Router下的组件默认是服务端组件,可直接通过next/headers提供的headers()方法获取请求头信息,拼接路径。

动态渲染服务端组件

// app/[slug]/page.js
import { headers } from 'next/headers';

export default async function PostPage() {
  const headersList = headers();
  // 获取请求域名
  const host = headersList.get('host');
  // 获取包含查询参数的完整路径(不含域名)
  const pagePath = headersList.get('x-nextjs-url');
  const fullUrl = `https://${host}${pagePath}`;

  return (
    <div>
      <p>页面路径:{pagePath}</p>
      <p>完整URL:{fullUrl}</p>
    </div>
  );
}

静态生成服务端组件

静态生成时无法获取实时请求头,需通过generateStaticParams获取路由参数拼接路径:

// app/posts/[slug]/page.js
export async function generateStaticParams() {
  return [{ slug: 'first-post' }, { slug: 'second-post' }];
}

export default async function PostPage({ params }) {
  const pagePath = `/posts/${params.slug}`;
  const fullUrl = `${process.env.NEXT_PUBLIC_BASE_URL}${pagePath}`;

  return (
    <div>
      <p>页面路径:{pagePath}</p>
      <p>完整URL:{fullUrl}</p>
    </div>
  );
}

兼容双版本的通用实现

若要在同一个组件中适配两种版本,可通过判断API是否存在来区分路由系统,结合props传递和直接获取两种方式:

// components/UniversalServerComponent.js
import { headers } from 'next/headers';

export default function UniversalServerComponent({ pathData }) {
  let pagePath, fullUrl;

  // 判断是否为App Router环境(headers API仅在Next.js 13+可用)
  const isAppRouter = typeof headers === 'function';

  if (isAppRouter) {
    const headersList = headers();
    const host = headersList.get('host');
    pagePath = headersList.get('x-nextjs-url');
    fullUrl = `https://${host}${pagePath}`;
  } else {
    // Pages Router环境,使用props传递的路径数据
    pagePath = pathData.pagePath;
    fullUrl = pathData.fullUrl;
  }

  return (
    <div>
      <p>页面路径:{pagePath}</p>
      <p>完整URL:{fullUrl}</p>
    </div>
  );
}

在Next.js 12中使用

// pages/[slug].js
export async function getServerSideProps(context) {
  const pagePath = context.resolvedUrl;
  const fullUrl = `https://${context.req.headers.host}${pagePath}`;
  return {
    props: { pathData: { pagePath, fullUrl } },
  };
}

export default function Page({ pathData }) {
  return <UniversalServerComponent pathData={pathData} />;
}

在Next.js 13中使用

// app/[slug]/page.js
export default async function Page() {
  return <UniversalServerComponent />;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:01:02