Next.js + TypeScript 프로젝트 세팅과 폴더 구조 설계

지헌·2025년 3월 23일

채용 공고에 Next가 너무 많이 올라오기 때문에 기존의 프로젝트 React, vite, TypeScript 로 구성된 내용을 Next로 마이그레이션 할려고 한다.

그 과정 중에 App 라우터를 사용할려고 하는데 Next.js 13 이상에서 서버 컴포넌트와 클라이언트 컴포넌트를 구분할 때 "use Client" 지시어를 사용해줍니다.

이 과정에서 어떻게 ssr을 적용하는지 컴포넌트를 적절히 구분하여 원하는 페이지의 SEO 기능을 개선하는지 고민을 하다가 이 과정을 정리하면서 확실히 구분하여 배우기 위해 이 글을 시작하게 되었습니다.

프로젝트 세팅

1. 프로젝트 생성

npx create-next-app@latest

  • Typescript 여부 Yes
  • Eslint 여부 Yes
  • Tailwind CSS 여부 yes
  • src/ 사용 여부 no
  • App Router 사용 여부 Yes
  • 기본 alias 설정 여부 No(따로 설정 예정)

2. 파비콘 수정

public 폴더에 수정할 이미지를 추가해주고

// layout.tsx
export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

이 부분을

export const metadata: Metadata = {
  title: "반복",
  description: " 페이지의 내용을 간략히 설명",
  icons: {
    icon: "/banbok.svg",
  },
};

이렇게 수정해주면 변경이 된다

3. 폴더 구조

next는 폴더 이름을 통해 url이 구성되기 때문에 여기서 꼬이면 많이 까다로울거라고 생각했기 때문에 초반에 제일 신경을 많이 써서 찾아보고 참고한 부분이다.

그래서 Next.js 13버전부터 생긴 Route group & private folder을 사용하여 route 폴더와 그 외 폴더를 깔끔하게 분리할 계획입니다.

이렇게 분리해주는 이유는 components/page.tsx 이런식으로 작성하게되면 app router는 components라는 네이밍을 가진 route를 생성하여 불필요한 경로로 접속되는 경우를 방지하기 위함입니다.

Route group

Route group은 말그대로 route가 될 수 있는 페이지들을 하나의 그룹으로 묶을 수 있게 해줍니다.

문법은 간단하게 (name) 이런식으로 폴더 네이밍을 작성해주시면 됩니다.

Private folder

문법은 _folder 이런식으로 작성하면 이 폴더는 route로 생성되지 않습니다.

추가적으로 해당 방법은 App Router의 규칙이 맞지 않고 Next.js 13 이상에서는 저런 네이밍 컨벤션을 사용하지 않는다고 해서 검색을 해본 결과 명확하지 않아 좀 더 많은 경험을 통해 정해야할거 같습니다.
_components → components
_hooks → hooks
_type → types
_zustand → store

4. 라우터 이동

기존 React 프로젝트에서는 useNavigate 나 Link 를 사용했다면Next에서는 import { useRouter } from "next/navigation";를 사용해줍니다.

  const router = useRouter();

    const handleTitleClick = () => {
      router.push("/");
    };

추가적으로 Error: × You're importing a component that needs useRouter. This React hook only works in a client component. To fix, mark the file (or its parent) with the "use client" directive.
useRouter 훅은 클라이언트 컴포넌트에서만 사용할 수 있기 때문에 "use Client"를 사용해주어야 한다.

5. "use client"

제일 초반에 헤매게 되는 부분이다.

use Client는 클라이언트 컴포넌트로 선언하는 지시어인데 이를 사용하면 서버 컴포넌트가 아닌 클라이언트 컴포넌트로 설정이 되기 때문에 SSR을 사용할 수 없다.

그래서 초기에 컴포넌트를 어떻게 지정해줘야할지 많이 고민하였다.

page router VS app router

  • page router : 기본적으로 CSR이 적용 getServerSideProps 함수를 사용하여 SSR 적용
  • app router : 기본적으로 SSR 적용 "use client"를 사용하여 CSR 적용

6. 이미지 불러오기

Next에서는 import 문으로 이미지를 불러오면 오류가 발생할 수 있습니다.

그래서 public 폴더 내부 이미지는 import가 아니라 절대 경로(/assets/...)로 접근해야합니다.

그래서 기존의 React에서 이미지를 불러오는 방식인

import kakao_icon from "../../../../public/assets/icon/kakao_icon.svg"; 

아닌 절대경로를 통해

<img src="/assets/icon/kakao_icon.svg" alt="카카오 아이콘" className="w-5 h-5" />

이렇게 바로 적용시키면 된다.

추가적으로 Next.js의 Image 컴포넌트 사용하면 최적화를 할 수 있다.

import Image from "next/image";

export function KakaoLogin() {
  const handleKakaoLogin = () => {
    window.location.href = `${process.env.NEXT_PUBLIC_API_URL}/v1/oauth/kakao`;
  };

  return (
    <button
      onClick={handleKakaoLogin}
      className="mt-2 p-2 w-full flex items-center justify-center gap-2 border-2 border-yellow-300 rounded-lg hover:bg-yellow-300 transition-colors"
      aria-label="카카오 로그인"
    >
      <div className="transform scale-150">
        <Image src="/assets/icon/kakao_icon.svg" alt="카카오 아이콘" width={20} height={20} />
      </div>
      <span>카카오 로그인</span>
    </button>
  );
}

Image 컴포넌트를 사용할 때 tailwind CSS는 적용이 안된다.

profile
차곡차곡 그만 쌓아올리고 취업해서 부딪쳐보고 싶은

0개의 댓글