Next.js如何配置动态路由以支持CMS自定义页面路径访问?
修复方案
1. 调整路由文件结构
你遇到的404问题核心是Next.js Pages Router默认按物理文件路径匹配路由,不存在对应文件就会返回404。你需要将根目录下pages/index.js重命名为pages/[[...perm]].js,这是Next.js的可选捕获所有路由规则:
- 匹配所有一级路径:
/aboutus、/contact、/都会命中这个文件 - 路径参数会自动注入到
query.perm数组中,比如访问/aboutus时query.perm = ['aboutus'],访问根路径时query.perm = undefined
2. 修正代码逻辑
调整后完整的[[...perm]].js代码:
import React from "react"; import { useRouter } from "next/router"; import Head from "next/head"; import Layout from "../components/layout/layout"; function DynamicPage({ resData }) { const router = useRouter(); // 页面不存在时可自定义缺省展示内容 if (!resData) return <div>页面不存在</div>; return ( <> <Head> <title>{resData.Title}</title> <meta property="og:description" name="description" content={resData.MetaDescription} key="description" /> <meta property="og:keywords" name="keywords" content={resData.Keywords} key="keywords" /> <meta property="og:title" name="title" content={resData.MetaTitle} key="title" /> <meta property="og:author" name="author" content="test" key="author" /> <link rel="stylesheet" href="/assets/minimalist-blocks/content.css" /> <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet" type="text/css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous" ></script> </Head> <Layout> {/* 用React官方API插入HTML,替代手动DOM操作,避免渲染冲突 */} <div className="ic-container" dangerouslySetInnerHTML={{__html: resData.PageContent}}></div> </Layout> </> ); } export async function getServerSideProps(context) { const { perm } = context.query; // perm是数组,取第一个元素作为页面permalink,根路径默认传空或者指定首页标识 const permalink = perm ? perm[0] : ''; let resData = null; try { const fetchResponse = await fetch("http://localhost:3001/asa/page/pageByPer/" + permalink); const data = await fetchResponse.json(); if (data?.isExist > 0 && data?.page?.length > 0) { resData = data.page[0]; } else { // 页面不存在返回Next官方404页,不需要可以注释掉走自定义缺省逻辑 return { notFound: true }; } } catch (e) { console.log(e); // 接口报错也返回404或者错误页 return { notFound: true }; } return { props: { resData, }, }; } export default DynamicPage;
3. 全局入口逻辑说明
你提到的类似原生React的App.js全局入口逻辑,完全可以在_app.js中实现:
- 可以通过
useRouter()获取当前访问路径,做全局权限校验、埋点等逻辑 - 如果用到浏览器原生API,需要加
typeof window !== 'undefined'判断,避免服务端渲染时报错
额外优化建议
- 当前直接插入HTML的逻辑存在XSS风险,建议在后端返回内容时做安全过滤,或者前端引入
DOMPurify对resData.PageContent做消毒处理后再插入 - 全局引入的第三方JS、CSS可以放到
_document.js中统一加载,避免每个页面重复引入
内容的提问来源于stack exchange,提问作者maifs
相关产品推荐
相关产品推荐

