如何用Next.js仅渲染网页指定部分而非完整HTML页面?
实现Next.js仅渲染指定
区域的方案
我来帮你搞定这个问题!其实Next.js完全支持这种“局部嵌入”的场景,不用死磕_document.js,换个思路用自定义App配置 + 客户端动态挂载就能轻松实现,下面是具体步骤(以Pages Router为例,App Router也有对应调整方式):
1. 修改自定义App,移除全局HTML骨架
首先打开pages/_app.js,把默认的全局包裹结构去掉,只返回当前页面的组件内容:
// pages/_app.js function MyApp({ Component, pageProps }) { // 不要添加任何全局容器,直接返回页面组件 return <Component {...pageProps} />; } export default MyApp;
2. 配置Next.js生成可嵌入的产物
在next.config.js中添加配置,让Next.js只输出React组件的编译bundle,而非完整HTML页面:
// next.config.js module.exports = { reactStrictMode: true, // 静态导出模式下,指定需要生成的页面路径 exportPathMap: async function () { return { '/': { page: '/' }, // 按需添加其他页面路径 }; }, // 开启独立输出模式,生成可嵌入的独立bundle experimental: { outputStandalone: true, }, };
3. 在现有网站的指定div中挂载Next.js
完成编译后,运行next build && next export生成静态产物,然后在你的非React导航网站的HTML中,针对<div id="nextjs_div"></div>做如下处理:
<!-- 现有网站的HTML结构 --> <body> <!-- 非React实现的导航栏 --> <nav>...</nav> <!-- Next.js的指定挂载区域 --> <div id="nextjs_div"></div> <!-- 引入Next.js编译后的核心bundle --> <script src="/_next/static/chunks/main.js"></script> <script src="/_next/static/chunks/webpack.js"></script> <script src="/_next/static/[你的编译哈希值]/pages/index.js"></script> <!-- 手动挂载Next.js组件到目标div --> <script> // 从Next.js的全局变量中获取页面组件 const NextPageComponent = window.__NEXT_DATA__.props.pageProps; // 用ReactDOM手动挂载 ReactDOM.render( React.createElement(NextPageComponent), document.getElementById('nextjs_div') ); </script> </body>
4. SSR场景的特殊处理(如果需要服务端渲染)
如果你的Next.js页面依赖SSR,不能用静态导出,那就需要自定义服务端入口,让它只返回组件的HTML片段而非完整页面:
// server.js 自定义服务端文件 const { createServer } = require('http'); const { parse } = require('url'); const next = require('next'); const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev }); const handle = app.getRequestHandler(); app.prepare().then(() => { createServer(async (req, res) => { try { const parsedUrl = parse(req.url, true); const { pathname, query } = parsedUrl; // 渲染页面组件的HTML,不包含完整骨架 const fullHtml = await app.renderToHTML(req, res, pathname, query); // 剥离html/body标签,只保留组件内容 const componentHtml = fullHtml.replace(/^<!DOCTYPE html>.*<body>|<\/body>.*<\/html>$/gs, ''); res.setHeader('Content-Type', 'text/html'); res.end(componentHtml); } catch (err) { console.error('处理请求出错:', req.url, err); res.statusCode = 500; res.end('Internal Server Error'); } }).listen(3000, (err) => { if (err) throw err; console.log('> 服务启动成功: http://localhost:3000'); }); });
之后在现有网站中通过AJAX请求这个服务,获取SSR后的组件HTML,插入到#nextjs_div即可。
额外提示
- 若使用Next.js 13+的App Router,需要修改
app/layout.js,去掉<html>和<body>标签,直接返回子组件:
// app/layout.js export default function RootLayout({ children }) { // 不要返回全局html/body标签,直接返回页面内容 return children; }
- 注意样式隔离,避免Next.js的样式影响非React导航区,推荐用CSS Modules或Tailwind的作用域功能。
内容的提问来源于stack exchange,提问作者OSEMA TOUATI
相关产品推荐
相关产品推荐

