next.js 13버전으로 신규 프로젝트 관리자 페이지를 작업중이다.
stable이 되었길래 실무에서 써보고 있는데, 아직은 우당탕탕하는 중
로컬에서 작업이랑 빌드는 잘 되는데 배포환경(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) 꺼진 공식문서도 다시보자