코딩스토리/개발관련

NextJS - Layout.tsx Props Invaild 에러

Tech&Fin 2024. 2. 16. 10:23
반응형

목차 - 클릭하면 이동합니다.

    NextJS - Layout.tsx - Props Invaild Error 발생

    NextJS의 최신 버전으로 프로젝트를 만들기 위해 2024.02.16일 기준 NextJS 최신 버전인 14.1.0을 이용해서 프로젝트를 생성하는 도중 아래와 같은 에러가 발생하였습니다.

    [web@instance-technfin c-app]$ yarn build
       ▲ Next.js 14.1.0
    
       Creating an optimized production build ...
     ✓ Compiled successfully
       Linting and checking validity of types  ..Failed to compile.
    
    src/app/[locale]/layout.tsx
    Type error: Layout "src/app/[locale]/layout.tsx" has an invalid "default" export:
      Type "AppLayoutProps" is not valid.

     

    다국어 페이지를 지원하기 위해 Next-Intl을 추가한 것 외에는 소스 추가가 많지 않은 상태이기 때문에 Layout.tsx의 소스코드는 아래와 같이 매우 간단한 상태입니다.

    import { ReactNode } from "react";
    import type { Metadata, Viewport } from "next";
    
    //** Next-Intl */
    import { NextIntlClientProvider, useMessages } from "next-intl";
    
    interface AppLayoutProps {
      children: ReactNode;
      locale: string;
    }
    
    export const metadata: Metadata = {
      title: "C-App",
      description: "The C-App for you.",
      icons: {
        icon: "/favicon.ico",
      },
    };
    
    export const viewport: Viewport = { initialScale: 1, width: "device-width" };
    
    export default function AppLayout({ children, locale }: AppLayoutProps) {
      //* Get all messages
      const messages = useMessages();
    
      return (
        <html lang={locale}>
          <body>
            <NextIntlClientProvider locale={locale} messages={messages}>
              {children}
            </NextIntlClientProvider>
          </body>
        </html>
      );
    }

     

    개발 모드에서는 발생하지 않고 build 시에만 발생하는 것으로 보아 코드상 문제는 없는듯 싶고 에러 메세지에서도 나오듯이 Linting Checking시 Type에 대하여 검증하다가 발생한 오류일 가능성이 높아 보입니다.

    해결 방법

    열심히 구글링을 해본 결과 NextJS의 App Router를 사용하는 경우 Layout.tsx의 Props에는 children외에 임의의 Props를 설정하면 에러가 발생하는 것 같았습니다.

     

    하지만 Next-Intl을 사용하기 위해서는 locale 정보를 Props에 넘겨야 하는 상황이었기에 확인해보니 params 형태로 넘기면 가능할 것 같다는 부분을 확인하였습니다.

     

    locale을 직접 넘기는 방법 대신 params를 이용하여 아래와 같이 변경하였습니다.

     

    import { ReactNode } from "react";
    import type { Metadata, Viewport } from "next";
    
    //** Next-Intl */
    import { NextIntlClientProvider, useMessages } from "next-intl";
    
    interface AppLayoutProps {
      children: ReactNode;
      params: { locale: string };
    }
    
    export const metadata: Metadata = {
      title: "C-App",
      description: "The C-App for you.",
      icons: {
        icon: "/favicon.ico",
      },
    };
    
    export const viewport: Viewport = { initialScale: 1, width: "device-width" };
    
    export default function AppLayout({
      children,
      params: { locale },
    }: AppLayoutProps) {
      //* Get all messages
      const messages = useMessages();
    
      return (
        <html lang={locale}>
          <body>
            <NextIntlClientProvider locale={locale} messages={messages}>
              {children}
            </NextIntlClientProvider>
          </body>
        </html>
      );
    }

     

    다시한번 빌드를 진행해 보도록 하겠습니다.

     

    [web@instance-technfin c-app]$ yarn build
       ▲ Next.js 14.1.0
    
       Creating an optimized production build ...
     ✓ Compiled successfully
     ✓ Linting and checking validity of types    
     ✓ Collecting page data    
     ✓ Generating static pages (4/4) 
     ✓ Collecting build traces    
     ✓ Finalizing page optimization    
    
    Route (app)                              Size     First Load JS
    ┌ ○ /_not-found                          885 B            85 kB
    └ λ /[locale]                            927 B          85.1 kB
    + First Load JS shared by all            84.1 kB
      ├ chunks/69-1b6d135f94ac0e36.js        28.9 kB
      ├ chunks/fd9d1056-cc48c28d170fddc2.js  53.4 kB
      └ other shared chunks (total)          1.83 kB
    
    
    ƒ Middleware                             49.5 kB
    
    ○  (Static)   prerendered as static content
    λ  (Dynamic)  server-rendered on demand using Node.js

     

    오류가 발생하지 않고 정상적으로 빌드가 완료 되었습니다.

     

     

    위와 같이 다국적 페이지 적용도 정상적으로 동작하는 것을 확인하였습니다.

     

    결론

    NextJS 13 이후로 App Router 방식이 적용 되었는데 이전 12 버전의 Page Router 방식과는 변화가 많이 생긴 것 같습니다.

     

    NextJS 12는 이미 서비스가 종료된 것으로 알고 있기 때문에 계속해서 사용하기 보다는 13 또는 최신 버전인 14로 업그레이드를 하는 것을 추천 드립니다.

     

    업그레이드 과정중에 변경해야 할 부분이 많고 오늘과 같은 오류들이 많이 발생할 수 있는데, 하나씩 해결해 나가면서 탄탄한 기본 프로그램 바탕을 만들어 놓는 것이 좋지 않을까 생각 됩니다.

    반응형