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

Next.js调用API实现SEO的最佳方式是什么?SWR与getServerSideProps如何选择?

问题解答

现有SWR写法的执行逻辑

你目前用的useSWR是纯客户端运行的React Hook,所有数据请求逻辑只会在用户浏览器加载完页面JS后才触发,服务端返回给浏览器/爬虫的初始HTML里只有"Loading..."的占位文本,搜索引擎爬不到你的实际视频内容,完全满足不了SEO需求。

基于getServerSideProps的改造方案

getServerSideProps是Next.js专门用来做服务端数据预取的API,每次页面请求都会先在服务端运行这个方法拉取API数据,再把数据注入到页面组件的props里,最后返回的HTML已经是渲染好全部内容的版本,爬虫直接就能拿到所有内容,正好匹配你的需求。
改造后的完整代码如下:

import React from "react";

// 该方法仅在服务端运行,不会暴露到客户端
export async function getServerSideProps() {
  try {
    const res = await fetch("my_url_api");
    const data = await res.json();
    // 把获取到的数据作为props传给页面组件
    return {
      props: {
        data
      }
    }
  } catch (err) {
    // 数据请求出错时可以自行处理,比如返回错误状态
    return {
      notFound: true
    }
  }
}

export default function App({ data }) {
  // 因为getServerSideProps已经完成数据拉取,不需要Loading状态
  if (!data) return "An error has occurred.";

  return (
    <div>
      <div>
        <h1>Esta es la web</h1>
      </div>
      {
        data.videos.map(({ item, title, embed, rate, default_thumb: { src } }, index) =>
          // 循环项需要添加唯一key,实际场景建议用item的唯一id替代index
          <React.Fragment key={index}>
            <h3>{title}</h3>
            <img src={src} alt="视频缩略图" />
            <iframe width="1225" height="625" src={embed}></iframe>
            <p>{rate}</p>
          </React.Fragment>
        )
      }
    </div>
  );
}

可选方案:结合SWR使用

如果你后续还需要SWR的客户端缓存、数据自动重校验等能力,也可以通过fallback参数把服务端预取的数据传给SWR,既保证SEO效果,又能享受SWR的客户端特性:

import React from "react";
import useSWR from "swr";

const fetcher = (url) => fetch(url).then((res) => res.json());

export async function getServerSideProps() {
  const res = await fetch("my_url_api");
  const data = await res.json();
  return {
    props: {
      fallback: {
        "my_url_api": data
      }
    }
  }
}

export default function App({ fallback }) {
  const { data, error } = useSWR(
    "my_url_api",
    fetcher,
    { fallback }
  );

  if (error) return "An error has occurred.";
  return (
    <div>
      <div>
        <h1>Esta es la web</h1>
      </div>
      {
        data.videos.map(({ item, title, embed, rate, default_thumb: { src } }, index) =>
          <React.Fragment key={index}>
            <h3>{title}</h3>
            <img src={src} alt="视频缩略图" />
            <iframe width="1225" height="625" src={embed}></iframe>
            <p>{rate}</p>
          </React.Fragment>
        )
      }
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:24:02