Next.js配置exportPathMap静态导出动态路由/home页报错排查
Next.js 默认对未配置任何数据获取方法(getStaticProps/getServerSideProps/getInitialProps)的页面开启自动静态优化(Auto Export),这类页面会在构建阶段被编译为不依赖服务端运行时的纯静态HTML文件,不支持构建时注入query参数。
你当前的[pageRoute].tsx组件没有添加任何数据获取方法,属于自动静态优化的页面,此时在exportPathMap中尝试给该路由传入query参数,Next.js会直接抛出错误——纯静态页没有服务端逻辑处理传入的参数,参数无法在构建阶段被注入到预渲染的HTML中。
另外你当前的实现完全依赖客户端useRouter在浏览器端读取路由参数渲染内容,本质是客户端路由渲染,构建阶段Next.js无法识别你需要为/home路径生成独立的静态文件。
静态导出场景下,pages路由的动态路径预渲染优先使用Next.js内置的getStaticPaths+getStaticProps实现,不需要在exportPathMap中手动传query参数,兼容性和性能都更好。
步骤1:修改动态路由文件[pageRoute].tsx
添加静态生成所需的配置方法,将路由参数通过props传入组件渲染,而不是完全依赖客户端读取router.query:
import { useRouter } from 'next/router'; import React from 'react'; import { PAGE_ROUTES } from '../constants/config'; import Home from './Home/Home'; import type { GetStaticPaths, GetStaticProps } from 'next'; type Props = { pageRoute: string }; export default function Base({ pageRoute }: Props) { const router = useRouter(); // 处理路由 fallback 加载状态 if (router.isFallback) return <div>加载中...</div> let RenderComponent = <div>404: 页面不存在</div>; switch (pageRoute) { case PAGE_ROUTES.HOME: { RenderComponent = <Home />; break; } default: break } return ( <div className='flex flex-col items-center max-w-sm mx-auto'> {RenderComponent} </div> ); } // 声明所有需要预渲染为静态文件的动态路由 export const getStaticPaths: GetStaticPaths = async () => { return { paths: [ // 所有要生成静态页的路由参数都在这里声明,比如home、about等 { params: { pageRoute: 'home' } } ], // 静态导出无服务端运行时,fallback必须设为false fallback: false } } // 构建时将路由参数作为props传入组件 export const getStaticProps: GetStaticProps = async (context) => { return { props: { pageRoute: context.params?.pageRoute as string } } }
步骤2:简化next.config.js配置
不需要在exportPathMap中手动添加/home的映射,getStaticPaths声明的路径会被Next.js自动识别,生成对应的静态HTML文件:
/** @type {import('next').NextConfig} */ module.exports = { reactStrictMode: true, exportPathMap: async function (defaultPathMap) { return { '/': { page: '/' } // 无需手动配置/home路由映射 }; }, };
不推荐的兼容方案:如果你一定要使用
exportPathMap传query的写法,可以按照错误提示,在[pageRoute].tsx中添加空的getInitialProps关闭自动静态优化:// 添加在组件文件末尾 Base.getInitialProps = () => ({})该方案会让页面失去纯静态优化的性能优势,首屏加载需要依赖客户端JS执行后才能渲染内容,非必要不使用。
内容的提问来源于stack exchange,提问作者Shivam Sahil

