Next.js布局中如何通过SSG在Footer实现SEO友好的服务端数据获取?
针对你遇到的Layout无法直接使用getStaticProps/getServerSideProps,又不想每个页面手动传参的问题,给你几个服务端层面的解决方案:
1. 在_app.js中通过getInitialProps全局注入数据
对于Pages Router项目,可以在全局的_app.js里用getInitialProps一次性获取Footer数据,然后传递给Layout组件,所有页面都会自动继承这个数据,无需逐个页面处理:
// pages/_app.js import Layout from '../components/Layout'; function MyApp({ Component, pageProps, footerData }) { return ( <Layout footerData={footerData}> <Component {...pageProps} /> </Layout> ); } MyApp.getInitialProps = async (appContext) => { // 服务端请求Footer数据 const res = await fetch('你的数据源地址'); const footerData = await res.json(); // 保留页面原有props const appProps = await App.getInitialProps(appContext); return { ...appProps, footerData }; }; export default MyApp;
这个方法在Next.js 12及以下的Pages Router中完全可用,13+ Pages Router也兼容。
2. Next.js 13+ App Router:直接在服务器组件中Fetch数据
如果你用的是App Router,Layout默认是服务器组件,可以直接在组件内部发起请求,SSG构建时会预渲染这些数据,完全符合SEO需求,不需要额外的getStaticProps:
// app/layout.js async function RootLayout({ children }) { // 服务端请求Footer数据,默认缓存用于SSG const res = await fetch('你的数据源地址', { cache: 'force-cache' }); const footerContent = await res.json(); return ( <html lang="zh-CN"> <body> {children} <footer> <p>{footerContent.copyright}</p> <nav>{footerContent.links.map(link => <a key={link.id} href={link.url}>{link.name}</a>)}</nav> </footer> </body> </html> ); } export default RootLayout;
3. 构建时生成静态JSON文件
如果Footer数据更新频率低,可以在构建阶段用脚本生成静态JSON文件,直接在Layout中导入,属于纯静态预渲染,SEO友好:
- 写一个生成数据的脚本:
// scripts/generate-footer-data.js const fs = require('fs'); const path = require('path'); async function generateFooterData() { const res = await fetch('你的数据源地址'); const footerData = await res.json(); // 写入public目录 fs.writeFileSync(path.join(process.cwd(), 'public/footer-data.json'), JSON.stringify(footerData)); } generateFooterData();
- 修改package.json的构建脚本,先执行生成脚本:
"scripts": { "build": "node scripts/generate-footer-data.js && next build", "dev": "next dev" }
- 在Layout组件中直接导入使用:
// components/Layout.js import footerData from '../public/footer-data.json'; function Layout({ children }) { return ( <> {children} <footer> <p>{footerData.copyright}</p> </footer> </> ); } export default Layout;
4. 通过自定义_document.js直接渲染Footer
在_document.js中用getInitialProps获取数据,直接在HTML模板里渲染Footer,全程服务端处理,不需要客户端请求:
// pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document'; class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx); // 服务端获取Footer数据 const res = await fetch('你的数据源地址'); const footerData = await res.json(); return { ...initialProps, footerData }; } render() { const { footerData } = this.props; return ( <Html> <Head /> <body> <Main /> <footer> <p>{footerData.copyright}</p> {/* 其他Footer内容 */} </footer> <NextScript /> </body> </Html> ); } } export default MyDocument;
内容的提问来源于stack exchange,提问作者Osman Goni Sufy
相关产品推荐
相关产品推荐

