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

Next.js中getInitialProps/getServerSideProps仅服务端渲染问题求助

Next.js 按需渲染:SSR适配SEO + 客户端跳转优化

问题分析

你需要实现:搜索引擎爬取时用服务端渲染(SSR)保证SEO,用户通过<next/Link>跳转时用客户端渲染(避免服务端重复请求慢API),但当前用getInitialProps或getServerSideProps存在两个问题:

  1. getServerSideProps仅在服务端执行请求,哪怕客户端跳转也会触发服务端API调用,导致等待15秒的慢响应;
  2. 用getInitialProps时客户端未触发请求,大概率是getData方法存在服务端专属逻辑(比如依赖服务端环境变量、仅在Node.js环境运行),或是API存在跨域限制。

解决方案

方案1:区分爬虫/用户,结合服务端渲染与客户端请求

核心思路:通过请求头判断访问者是爬虫还是普通用户,爬虫走服务端请求,普通用户走客户端请求。

步骤1:在getServerSideProps中做判断

export const getServerSideProps = async (context) => {
  const userAgent = context.req.headers['user-agent'] || '';
  // 匹配主流搜索引擎爬虫UA,可按需扩展
  const isCrawler = /bot|crawler|spider|googlebot|bingbot|yandexbot/i.test(userAgent);

  if (isCrawler) {
    // 爬虫访问:服务端请求API,返回渲染所需数据
    const data = (await getData({ id: context.query.id })).data;
    return { props: { data } };
  } else {
    // 普通用户:返回空数据,由客户端自行请求
    return { props: { data: null } };
  }
};

步骤2:页面组件中客户端请求数据

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

export default function ProductPage({ data: initialData }) {
  const [data, setData] = useState(initialData);
  const router = useRouter();

  useEffect(() => {
    if (!data) {
      // 客户端场景:发起API请求
      const fetchProduct = async () => {
        // 若API存在跨域/服务端权限限制,改用Next.js API路由代理
        const res = await fetch(`/api/products/${router.query.id}`);
        const productData = await res.json();
        setData(productData);
      };
      fetchProduct();
    }
  }, [data, router.query.id]);

  if (!data) {
    return <div>加载中...</div>;
  }

  // 渲染产品内容
  return (
    <div>
      <h1>{data.name}</h1>
      {/* 其他产品信息 */}
    </div>
  );
}

补充:API路由代理(若API不可直接在客户端访问)

如果你的数据API需要服务端权限(比如密钥),创建pages/api/products/[id].js作为代理:

export default async function handler(req, res) {
  const { id } = req.query;
  // 这里调用原始API,可安全使用服务端环境变量
  const data = (await getData({ id })).data;
  res.status(200).json(data);
}

方案2:用getInitialProps修复客户端请求(Next.js 13之前版本)

getInitialProps默认在客户端跳转时会在浏览器中执行,若客户端未触发请求,检查以下两点:

  1. 确保getData方法兼容客户端环境:比如使用浏览器原生fetch,而非仅Node.js可用的请求库;
  2. 解决API跨域问题:通过上述API路由代理方式转发请求。

修复后的getInitialProps示例:

ProductPage.getInitialProps = async (context) => {
  // 若在客户端,直接请求代理API;服务端可直接调用原始API
  const baseUrl = context.req ? 'https://your-api-domain.com' : '';
  const res = await fetch(`${baseUrl}/api/products/${context.query.id}`);
  const data = await res.json();
  
  return { data };
};

关键优化点

  • API性能优化:15秒的响应时间完全无法接受,优先优化API本身(比如添加缓存、数据库索引、异步处理),否则无论哪种方案都无法解决用户体验问题;
  • 爬虫UA覆盖:扩展爬虫正则表达式,覆盖更多主流搜索引擎,避免漏判;
  • 加载状态处理:客户端请求时显示加载动画,避免空白页面。

内容的提问来源于stack exchange,提问作者Hooman Limouee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:15:50