Next.js 中在 getStaticProps 中处理查询参数的推荐方案

next.js 的 getstaticprops 默认不支持运行时查询参数,但可通过 nuqs 库在静态生成阶段安全、类型安全地解析和序列化 url 查询参数,实现 ssr/ssg 场景下的参数驱动数据预取。

在 Next.js 中,getStaticProps 是在构建时(build time)执行的函数,因此它无法访问客户端发起的动态查询参数(如 ?category=tech&page=2)——因为此时请求尚未发生,context 中也没有 req.query。这是设计使然,而非限制。若需基于查询参数生成静态页面,正确路径是:提前声明所有可能的参数组合,并通过 getStaticPaths 预生成对应路径(如 /posts?category=tech 不合法,应转为 /posts/category/tech 或 /posts/tech)

但现实场景中,常需保留查询参数语义(例如排序、筛选、分页),同时兼顾 SEO 与静态能力。此时,NUQS(Next URL Query State)成为 2025 年广受推荐的现代解决方案。它并非“让 getStaticProps 直接读 query”,而是提供一套类型安全、服务端友好的工具链,在 getStaticProps 和客户端之间统一管理 URL 参数的序列化与反序列化:

✅ 支持服务端(getStaticProps / getServerSideProps)和客户端(React 组件)共享同一套参数定义
✅ 自动生成 TypeScript 类型,避免手动解析 URLSearchParams
✅ 内置编码/解码、默认值、数组/布尔/数字类型自动转换
✅ 与 App Router 和 Pages Router 均兼容(Pages Router 示例见下)

使用示例(Pages Router)

// pages/posts.tsx
import { useQueryState, parseAsInteger, parseAsString } from 'nuqs';

// 定义参数 schema(类型即文档)
const [category, setCategory] = useQueryState('category', parseAsString.withDefault('all'));
const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1));

export default function PostsPage() {
  return (
    
      

Posts: {category} (Page {page})

); } // ✅ 在 getStaticProps 中“模拟”查询参数(用于预渲染关键变体) export async function getStaticProps({ params }: { params: { slug?: string[] } }) { // 示例:预生成 category=tech & page=1 的静态版本 const initialData = await fetchPosts({ category: 'tech', page: 1 }); return { props: { initialData, // 可选:注入初始 query state 到页面 props,供客户端 hydration 用 initialQuery: { category: 'tech', page: 1 } }, revalidate: 60 }; }
⚠️ 注意事项: getStaticProps 本身永远不能动态响应 window.location.search;NUQS 的价值在于统一参数协议,让静态预渲染(如首页默认视图)与后续客户端交互无缝衔接; 若需全量参数组合静态化(如 10 个分类 × 5 页),请结合 getStaticPaths 显式返回 paths: [{ params: { category: 'tech', page: '1' } }, ...],并采用动态路由 /posts/[category]/[page]; NUQS 不替代 getStaticPaths,而是补足其灵活性——尤其适合“部分参数需静态化、部分留待客户端交互”的混合场景。

总之,NUQS 是当前 Next.js 生态中处理查询参数最成熟、类型优先、服务端就绪的库。它不违背 SSG 原则,反而通过设计约束推动更可维护的 URL 状态管理实践。