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

Next.js中创建动态index.js实现[country]/[state]/[city]全静态生成

实现多级路由全静态生成的操作步骤

1. 先定义全局静态地区数据源

因为所有内容部署前完全确定,先把层级结构定义为可全局调用的常量,比如存到/data/regions.js里:

// /data/regions.js
export const regions = {
  "加拿大": {
    "魁北克省": ["蒙特利尔市"],
    "安大略省": ["多伦多市"]
  },
  "美国": {
    "北卡罗来纳州": ["夏洛特市"],
    "佛罗里达州": ["奥兰多市"]
  }
}

你之前省/州页面需要请求时生成的核心原因是:没有给省/州对应的动态路由预声明所有可能的路径参数,Next.js只能在用户请求时临时生成页面。

2. 调整pages目录结构,匹配路由规则

你的pages目录要按如下结构组织:

pages/
├── index.js // 根页面:展示国家列表
└── [country]
    ├── index.js // 国家页:展示对应国家的省/州列表
    └── [state]
        ├── index.js // 省/州页:展示对应州的城市列表
        └── [city].js // 你已经完成的城市详情页

3. 逐个实现各层级页面的静态生成逻辑

所有动态路由的fallback都设置为false,确保未在构建时预生成的路径直接返回404,不会触发请求时生成逻辑。

3.1 根页面 pages/index.js

属于固定路由,不需要getStaticPaths,直接用getStaticProps拉取国家列表即可:

// pages/index.js
import Link from 'next/link'
import { regions } from '../data/regions'

export default function Home({ countries }) {
  return (
    <div>
      <h1>国家列表</h1>
      <ul>
        {countries.map(country => (
          <li key={country}>
            <Link href={`/${encodeURIComponent(country)}`}>{country}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

export function getStaticProps() {
  return {
    props: {
      countries: Object.keys(regions)
    }
  }
}

3.2 国家层级动态页 pages/[country]/index.js

用getStaticPaths预声明所有国家的路径参数:

// pages/[country]/index.js
import Link from 'next/link'
import { regions } from '../../data/regions'

export default function CountryPage({ country, states }) {
  return (
    <div>
      <h1>{country} - 省/州列表</h1>
      <ul>
        {states.map(state => (
          <li key={state}>
            <Link href={`/${encodeURIComponent(country)}/${encodeURIComponent(state)}`}>{state}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

export function getStaticPaths() {
  const paths = Object.keys(regions).map(country => ({
    params: { country }
  }))
  return { paths, fallback: false }
}

export function getStaticProps({ params }) {
  const country = params.country
  const states = Object.keys(regions[country])
  return {
    props: { country, states }
  }
}

3.3 省/州层级动态页 pages/[country]/[state]/index.js

预声明所有国家+州的组合参数:

// pages/[country]/[state]/index.js
import Link from 'next/link'
import { regions } from '../../../data/regions'

export default function StatePage({ country, state, cities }) {
  return (
    <div>
      <h1>{country} {state} - 城市列表</h1>
      <ul>
        {cities.map(city => (
          <li key={city}>
            <Link href={`/${encodeURIComponent(country)}/${encodeURIComponent(state)}/${encodeURIComponent(city)}`}>{city}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

export function getStaticPaths() {
  const paths = []
  Object.entries(regions).forEach(([country, states]) => {
    Object.keys(states).forEach(state => {
      paths.push({
        params: { country, state }
      })
    })
  })
  return { paths, fallback: false }
}

export function getStaticProps({ params }) {
  const { country, state } = params
  const cities = regions[country][state]
  return {
    props: { country, state, cities }
  }
}

4. 验证构建效果

执行next build命令后,终端会输出所有预生成的页面,你可以看到所有国家页、省/州页、城市页都被标记为静态页面(显示○符号),访问时直接返回静态资源,不会触发服务端渲染逻辑。

提示:如果使用Next.js 13+ App Router,将getStaticPaths替换为对应路由段的generateStaticParams方法即可,逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 19:27:03