Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
콘솔에는 이렇게 찍히고 있어서 글꼴을 잘못 설정한건가 했다.

하지만 문제는 이 두 파일이었다...
app/layout.tsx
import localFont from "next/font/local";
import { ReactNode } from "react";
import "./globals.css";
const GothicA1 = localFont({
src: [
{ path: "/fonts/GothicA1-Regular.ttf", weight: "400", style: "normal" },
{ path: "/fonts/GothicA1-Medium.ttf", weight: "500", style: "normal" },
{ path: "/fonts/GothicA1-SemiBold.ttf", weight: "600", style: "normal" },
{ path: "/fonts/GothicA1-Bold.ttf", weight: "700", style: "normal" },
],
variable: "--gothic-a1",
});
const IBMPlexSans = localFont({
src: [
{ path: "/fonts/IBMPlexSans-Regular.ttf", weight: "400", style: "normal" },
{ path: "/fonts/IBMPlexSans-Medium.ttf", weight: "500", style: "normal" },
{
path: "/fonts/IBMPlexSans-SemiBold.ttf",
weight: "600",
style: "normal",
},
{ path: "/fonts/IBMPlexSans-Bold.ttf", weight: "700", style: "normal" },
],
variable: "--ibm-plex-sans",
});
const BebasNeue = localFont({
src: [
{ path: "/fonts/BebasNeue-Regular.ttf", weight: "400", style: "normal" },
],
variable: "--bebas-neue",
});
const RootLayout = ({ children }: { children: ReactNode }) => {
return (
<html
lang="ko"
className={`${GothicA1.variable} ${IBMPlexSans.variable} ${BebasNeue.variable} font-gothic`}
>
<body>{children}</body>
</html>
);
};
export default RootLayout;
app/[locale]/layout.tsx
import { NextIntlClientProvider } from "next-intl";
import { getMessages, setRequestLocale } from "next-intl/server";
import { notFound } from "next/navigation";
import { routing } from "@/i18n/routing";
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
const { locale } = await params;
if (!routing.locales.includes(locale as "en" | "ko")) {
notFound();
}
setRequestLocale(locale);
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
이 두파일의 결과는

html의 body 태그 속에 또 html과 body 넣은....ㅋ
결론 : 공식문서를 잘 읽자. & ai를 맹신하지 말자 ^^ claude가 하라는데로 했는데.... 헛소리한거였다. 교차 검증은 필수.
'공부한것 > React' 카테고리의 다른 글
[React] useCallback - 함수 memoization (0) | 2022.08.05 |
---|---|
[React] 프로젝트에서 계속 두 번씩 렌더링 되는 현상 해결하기 (0) | 2022.08.04 |
[React] useMemo, memoization 공부하기! (0) | 2022.08.03 |
[React] useRef (0) | 2022.07.29 |
[React] useEffect (0) | 2022.07.29 |
댓글