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

Next.js动态路由结构搭建求助(TypeScript环境)

Next.js + TypeScript 动态路由实现方案

目录结构设计

Pages Router(Next.js 12及以下,适合新手入门)

pages/
├── index.tsx          # 主域名首页(匹配 /)
├── [chain].tsx        # 匹配 /eth 这类单参数路径
└── [chain]/
    └── [dexOrToken].tsx  # 匹配 /eth/uni 或 /eth/0xr83urt36sdt45t

App Router(Next.js 13+ 推荐方案)

app/
├── page.tsx           # 主域名首页(匹配 /)
└── [chain]/
    ├── page.tsx       # 匹配 /eth 这类单参数路径
    └── [dexOrToken]/
        └── page.tsx   # 匹配 /eth/uni 或 /eth/0xr83urt36sdt45t

核心路由逻辑

Next.js 通过[]包裹参数名实现动态路由匹配:

  • 根路径/ → 对应首页组件
  • /[chain] → 匹配任意单层级路径,参数chain自动传递到对应组件
  • /[chain]/[dexOrToken] → 匹配二级路径,通过参数特征(比如是否以0x开头)区分是DEX名称还是Token地址,无需拆分两个独立路由

页面组件实现示例

Pages Router 版本

1. [chain].tsx(单参数页面)

import { useRouter } from 'next/router';
import type { NextPage } from 'next';

const ChainPage: NextPage = () => {
  const router = useRouter();
  const { chain } = router.query;

  // 此处根据chain调用API加载链相关数据
  return (
    <div>
      <h1>当前链:{chain}</h1>
      {/* 渲染链对应内容 */}
    </div>
  );
};

export default ChainPage;

2. [chain]/[dexOrToken].tsx(二级参数页面)

import type { GetServerSideProps, NextPage } from 'next';

// 定义组件props类型
interface DetailProps {
  chain: string;
  contentData: {
    address?: string;
    name?: string;
    // 补充你的实际数据字段
  };
  isToken: boolean;
}

const ChainDetailPage: NextPage<DetailProps> = ({ chain, contentData, isToken }) => {
  return (
    <div>
      <h1>当前链:{chain}</h1>
      {isToken ? (
        <section>
          <h2>Token详情</h2>
          <p>地址:{contentData.address}</p>
          {/* 渲染Token相关内容 */}
        </section>
      ) : (
        <section>
          <h2>DEX详情</h2>
          <p>名称:{contentData.name}</p>
          {/* 渲染DEX相关内容 */}
        </section>
      )}
    </div>
  );
};

// 服务器端获取数据(SEO友好)
export const getServerSideProps: GetServerSideProps<DetailProps> = async (context) => {
  const { chain, dexOrToken } = context.params as { chain: string; dexOrToken: string };
  const isToken = dexOrToken.startsWith('0x');

  // 根据参数类型请求对应API
  const apiUrl = isToken 
    ? `你的API地址/tokens/${chain}/${dexOrToken}` 
    : `你的API地址/dexs/${chain}/${dexOrToken}`;
  
  const res = await fetch(apiUrl);
  const contentData = await res.json();

  return {
    props: { chain, contentData, isToken }
  };
};

export default ChainDetailPage;

App Router 版本(Next.js 13+)

[chain]/[dexOrToken]/page.tsx(服务器组件,自动SSR)

// 默认是服务器组件,无需标记'use client'
export default async function ChainDetailPage({ params }: { params: { chain: string; dexOrToken: string } }) {
  const { chain, dexOrToken } = params;
  const isToken = dexOrToken.startsWith('0x');

  // 直接在组件内请求API(服务器端执行)
  const apiUrl = isToken 
    ? `你的API地址/tokens/${chain}/${dexOrToken}` 
    : `你的API地址/dexs/${chain}/${dexOrToken}`;
  
  const res = await fetch(apiUrl, { cache: 'no-store' }); // 禁用缓存,保证实时数据
  const contentData = await res.json();

  return (
    <div>
      <h1>当前链:{chain}</h1>
      {isToken ? (
        <section>
          <h2>Token详情</h2>
          <p>地址:{contentData.address}</p>
        </section>
      ) : (
        <section>
          <h2>DEX详情</h2>
          <p>名称:{contentData.name}</p>
        </section>
      )}
    </div>
  );
}

关键注意事项

  • 参数区分逻辑:通过0x前缀判断Token地址是简单可行的方案,若有特殊情况可结合API校验(比如请求Token接口返回404则判定为DEX)
  • TypeScript类型:尽量避免使用any,为API返回数据定义接口类型,提升代码健壮性
  • 数据加载策略:服务器端渲染(SSR)适合需要SEO的场景,客户端渲染(CSR)适合交互性强的页面,可根据需求选择

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:45:15