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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:09:02