首页 > 解决方案 > NextJS 在服务器上返回 _error 页面,但在客户端返回登录页面?

问题描述

我有一个奇怪的问题,老实说,我什至不知道从哪里开始寻找。

我有一个 NextJS 应用程序,它在 pages/api 部分内置了一个 GraphQL 端点。它仍然很基本,我主要只是构建了登录/注册功能。

我注意到一个问题,即我的 currentUser 查询正在不应该运行它的页面上运行(例如 /login 和 /register)。我发现在我的 Page 组件包装器上是 _error 路由由于某种原因被触发,即使它没有显示客户端。该组件只是将 main 包装在 _app.tsx 中。

这是页面组件包装器:

/* eslint-disable @typescript-eslint/no-explicit-any */
// third-party
import React, { ReactChild, ReactChildren } from 'react';
import { useRouter } from 'next/router';
import { AnimateSharedLayout } from 'framer-motion';

// custom components
import CustomDrawer from 'components/common/Drawer';
import Navbar from 'components/common/Navbar';

// styles
import CommonPageStyles from './CommonPageStyles';

interface AuxProps {
  children: ReactChild | ReactChildren;
}

const Page: React.FC = ({ children }: AuxProps) => {
  const router = useRouter();
  console.log(router.route);
  const isLoggedOut =
    router.route === '/_error' || // temporary fix
    router.route === '/login' ||
    router.route === '/register' ||
    router.route === '/terms-and-conditions';

  const isOnboarding = router.route === '/onboarding';

  const renderPage = () => {
    console.log({ isLoggedOut });
    console.log({ isOnboarding });

    if (isLoggedOut && !isOnboarding) {
      return (
        <div style={{ padding: '0', height: '100%', width: '100%' }}>
          {children}
        </div>
      );
    } else if (!isLoggedOut && isOnboarding) {
      return (
        <div style={{ padding: '64px 0 0 0', height: '100%', width: '100%' }}>
          <Navbar simple />
          {children}
        </div>
      );
    } else {
      return (
        <div className="page-container">
          <Navbar />
          <CustomDrawer />
          <div className="inner-wrap">{children}</div>
        </div>
      );
    }
  };

  return (
    <AnimateSharedLayout>
      <CommonPageStyles>{renderPage()}</CommonPageStyles>
    </AnimateSharedLayout>
  );
};

export default Page;

我在此组件中放置了三个控制台日志:一个用于router.route,一个用于我的自定义变量isLoggedInisOnboarding. 当我刷新 /login 页面时,这是我在服务器上看到的:

/login
{ isLoggedOut: true }
{ isOnboarding: false }
/_error
{ isLoggedOut: true }
{ isOnboarding: false }

但是客户端正在像往常一样呈现登录页面。

所以我构建了一个粗略的自定义 _error 页面来尝试调试:

function Error({ statusCode }) {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : 'An error occurred on client'}
    </p>
  );
}

Error.getInitialProps = ({ res, err }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
  console.log({ statusCode });
  return { statusCode };
};

export default Error;

现在我在服务器上看到了这个:

{ isLoggedOut: true }
{ isOnboarding: false }
event - build page: /_error
wait  - compiling...
event - compiled successfully
{ statusCode: 404 }
/_error
{ isLoggedOut: true }
{ isOnboarding: false }

如您所见,返回的错误 statusCode 是 404,但我不知道为什么!有没有人对为什么会发生这种情况有任何建议?

标签: next.js

解决方案


弄清楚了!

我忘记了next-pwa在最初构建这个项目时我已经安装了这个包。这会生成一个 manifest.json,它在 _document.tsx 中被引用。这个文件没有被构建,导致 404。我只是删除了这个包和对它的任何引用,这似乎已经解决了这个问题!


推荐阅读