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

Strapi+Next.js App Router中SSR组件使用GraphQL+Apollo请求的问题

解决服务器组件中Apollo查询报错的方案

错误原因

你当前的Apollo Client实例是在标记了"use client"的文件中创建的,属于客户端专属API,无法在服务器组件(App Router中的默认组件)中直接调用client.query(),因此触发报错。

方案一:直接用Fetch发送GraphQL请求(无需Apollo)

服务器组件本身支持async/await,可以直接通过原生Fetch向Strapi的GraphQL接口发送请求,这是最简单的无依赖方案:

修改app/page.tsx:

import { RootFooter, RootMain } from "@/compoents/organisms";

export default async function Home() {
  const STRAPI_URL = process.env.STRAPI_URL || "http://localhost:1337";
  
  const res = await fetch(`${STRAPI_URL}/graphql`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      query: `
        {
          todos(sort: "id:desc") {
            data {
              id
              attributes {
                todoText
                createdAt
              }
            }
          }
        }
      `
    }),
    // 根据需求设置缓存策略,Next.js支持多种缓存选项
    cache: "force-cache"
  });

  if (!res.ok) throw new Error("请求数据失败");
  
  const { data } = await res.json();
  console.log(data, "data");

  return (
    <>
      <RootMain>
        <h1 className="text-white">{data.todos.data[0]?.attributes.todoText || "暂无数据"}</h1>
      </RootMain>
      <RootFooter />
    </>
  );
}

方案二:创建服务器端专属Apollo Client实例

如果仍想使用Apollo的查询能力,需要在非客户端文件中创建服务器端的Apollo Client(禁用客户端特性):

  1. 创建lib/apollo-server.ts(不要加"use client"):
import { InMemoryCache, ApolloClient } from "@apollo/client";

const STRAPI_URL = process.env.STRAPI_URL || "http://localhost:1337";

export function createServerApolloClient() {
  return new ApolloClient({
    uri: `${STRAPI_URL}/graphql`,
    cache: new InMemoryCache(),
    ssrMode: true, // 开启SSR模式,禁用客户端渲染相关逻辑
  });
}
  1. 修改app/page.tsx:
import { RootFooter, RootMain } from "@/compoents/organisms";
import { GETQUERY } from "@/query/schema";
import { createServerApolloClient } from "@/lib/apollo-server";

export default async function Home() {
  // 每次请求创建新的客户端实例,避免缓存污染
  const client = createServerApolloClient();
  const { data } = await client.query({ query: GETQUERY });
  
  console.log(data, "data");
  return (
    <>
      <RootMain>
        <h1 className="text-white">{data.todos.data[0]?.attributes.todoText || "暂无数据"}</h1>
      </RootMain>
      <RootFooter />
    </>
  );
}

替代方案:使用轻量GraphQL请求库

如果觉得Apollo过于厚重,可以选择更适合服务器端的轻量库,比如graphql-request:

  1. 安装依赖:
npm install graphql-request graphql
  1. 修改app/page.tsx:
import { RootFooter, RootMain } from "@/compoents/organisms";
import { request, gql } from "graphql-request";

const STRAPI_GQL_URL = process.env.STRAPI_URL || "http://localhost:1337/graphql";

export default async function Home() {
  const query = gql`
    {
      todos(sort: "id:desc") {
        data {
          id
          attributes {
            todoText
            createdAt
          }
        }
      }
    }
  `;

  const data = await request(STRAPI_GQL_URL, query);
  console.log(data, "data");

  return (
    <>
      <RootMain>
        <h1 className="text-white">{data.todos.data[0]?.attributes.todoText || "暂无数据"}</h1>
      </RootMain>
      <RootFooter />
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:32:03