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

Next.js 13.5.2集成Apollo Client时路由实例缺失报错求助

问题解决:Next.js 13.5.2 + Apollo Client 路由实例缺失报错

问题原因

next/router 仅能在客户端组件中使用,你的Apollo Client配置文件(withApollo.tsx)可能在服务器端渲染流程中被执行。即使添加了typeof window !== "undefined"的判断,模块级别的import Router from "next/router"语句会先在服务器端被处理,此时不存在路由实例,直接触发"No router instance found"错误。

解决方案

方案1:动态导入Router(推荐)

将Router的导入改为运行时动态导入,确保仅在客户端环境下加载路由模块:

import { onError } from "@apollo/client/link/error";

const ErrorLink = onError(async ({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    for (const err of graphQLErrors) {
      console.log(
        `[GraphQL error]: Message: ${err.message}, Location: ${err.locations}, Path: ${err.path}`
      );
      if (err.message.includes("not authenticated") && typeof window !== "undefined") {
        // 动态导入next/router,仅在客户端执行
        const { default: Router } = await import("next/router");
        Router.push("/login");
      }
    }
  }
  if (networkError) console.log(`[Network error]: ${networkError}`);
});

方案2:拆分Apollo Client的客户端/服务器端配置

如果你的Apollo Client在服务器端(如getServerSideProps)和客户端都需要初始化,可将Error Link仅添加到客户端的Apollo配置中:

// withApollo.tsx
import { ApolloClient, InMemoryCache, createHttpLink, from } from "@apollo/client";
import { onError } from "@apollo/client/link/error";

function createApolloClient(isServer: boolean) {
  const links = [createHttpLink({ uri: "/api/graphql" })];

  // 仅在客户端添加Error Link
  if (!isServer) {
    const ErrorLink = onError(async ({ graphQLErrors }) => {
      if (graphQLErrors) {
        for (const err of graphQLErrors) {
          if (err.message.includes("not authenticated")) {
            const { default: Router } = await import("next/router");
            Router.push("/login");
          }
        }
      }
    });
    links.unshift(ErrorLink);
  }

  return new ApolloClient({
    ssrMode: isServer,
    link: from(links),
    cache: new InMemoryCache(),
  });
}

export default createApolloClient;

方案3:改用App Router的路由方式(若使用App Router)

如果你使用的是Next.js 13+的App Router,应替换next/router为next/navigation的useRouter钩子。由于Apollo Link无法直接使用React Hooks,可在页面组件中捕获Apollo错误并跳转:

// 客户端组件中使用useQuery
"use client";
import { useQuery } from "@apollo/client";
import { useRouter } from "next/navigation";
import { GET_DATA } from "../queries";

export default function MyPage() {
  const router = useRouter();
  const { error } = useQuery(GET_DATA);

  if (error?.graphQLErrors?.some(err => err.message.includes("not authenticated"))) {
    router.push("/login");
  }

  // 页面内容...
}

验证

修改后,触发"not authenticated"错误时,客户端应能正确跳转到登录页,且服务器端不再抛出路由实例缺失的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:32:50