next.js 13 client-side exception

jihyun·2023년 9월 23일
0

TIL

목록 보기
17/17

next.js 13버전으로 신규 프로젝트 관리자 페이지를 작업중이다.
stable이 되었길래 실무에서 써보고 있는데, 아직은 우당탕탕하는 중

client-side exception?

로컬에서 작업이랑 빌드는 잘 되는데 배포환경(staging)에서만 메뉴에서 다른 페이지로 이동할 때 랜덤하게 client exception error가 발생했다.

콘솔창을 봐도 크게 도움을 얻지 못했다. ^^

스택오버플로우에도 같은 오류는 있는데 내 경우 데이터 페칭과는 관련이 없었다.

next.js 공식문서에 client side error에 대한 내용이 있었다.

프로젝트에는 이미 error.tsx 파일이 있는데???? 하면서 보다 보니 힌트를 얻을 수 있었다.

루트 레이아웃이나 템플릿에서 발생하는 에러는 global-error.js로 처리해줘야한다.

"use client";

export default function GlobalError({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  console.log("global error", error);
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  );
}

global-error.tsx 파일을 추가해보니, 정말 에러페이지가 작동했고, global error로 콘솔에서도 확인이 됐다.
작동하지 않던 error 페이지가 작동하는 걸 보니 template 파일은 없어서 layout.tsx 파일 내의 문제임을 알 수 있었다.


export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <AuthContext>
          <ReduxProvider>
            <ReactQueryClientProvider>
              <div className="root">
                <AntdRegistry>
                  <StyledComponentsRegistry>
                    {children}
                  </StyledComponentsRegistry>
                </AntdRegistry>
              </div>
            </ReactQueryClientProvider>
          </ReduxProvider>
        </AuthContext>
      </body>
    </html>
  );
}

<AntdRegistry>는 antd가 적용되기 전에 날것의 html이 잠깐 보이길래 antd 공식문서를 보고 추가했다.

<StyledComponentsRegistry>는 styled-components를 사용하기 위해 next.js 공식문서를 보고 추가했다.

혹시나 하고 ant design 공식문서를 다시 확인했더니 cache를 선언하는 부분이 바뀌어있었다...(!?)

"use client";

import React from "react";
import { StyleProvider, createCache, extractStyle } from "@ant-design/cssinjs";
import type Entity from "@ant-design/cssinjs/es/Cache";
import { useServerInsertedHTML } from "next/navigation";

const StyledComponentsRegistry = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  //전
  const cache = createCache();
  //후
  const cache = React.useMemo<Entity>(() => createCache(), [createCache]);
  useServerInsertedHTML(() => (
    <style
      id="antd"
      dangerouslySetInnerHTML={{ __html: extractStyle(cache, true) }}
    />
  ));
  return <StyleProvider cache={cache}>{children}</StyleProvider>;
};

export { StyledComponentsRegistry as AntdRegistry };

이렇게 수정하고 나니까 잘 작동했다. ^_^

배포환경에서만 랜덤하게 발생한 데다가 콘솔에서 힌트를 못 얻어서 걱정했는데, 공식문서를 따라가다보니 예상보다는 금방 해결했다.

1) Root layout은 server component가 디폴트이고 client component일 수 없다.
2) error는 가장 가까운 상위 경로의 error boundary에 의해 처리되고, app/error.js는 layout이나 template에서 발생하는 에러는 처리하지 못한다.
3) 꺼진 공식문서도 다시보자

0개의 댓글