본문 바로가기

AI 개발

TanStack Start, shadcn, TypeScript 로 대시보드 만들기

반응형

0. 사전 준비

  • Node.js: 18 이상 권장 (LTS)
  • 패키지 매니저: pnpm 또는 npm 중 하나 (예시는 pnpm 사용, 원하는 패키지 매니저로 바꿔도 됩니다)
  • Git: 버전 관리용(선택)

확인 명령어:

node -v
pnpm -v   # 또는 npm -v

1. TanStack Start 앱 생성

TanStack Start 공식 CLI로 새 프로젝트를 만듭니다.

# 프로젝트 생성 (질문에 따라 입력)
npx create-start-app@latest

권장 답변 예시

  • 프로젝트 이름: orcish-tanstack-dashboard (원하는 이름 가능)
  • Tailwind: Yes (빠른 경로)
  • ESLint: Yes
  • Add-ons: (선택) shadcn/ui 포함 여부는 상관없습니다. 포함해도 되고, 아래에서 CLI로 다시 설치/추가 가능합니다.
  • Examples: No

설치가 끝나면 폴더로 이동 후 개발 서버 실행:

cd orcish-tanstack-dashboard
pnpm dev  # 또는 npm run dev

터미널에 표시되는 로컬 주소로 접속(예: http://localhost:xxxx). 초기 랜딩 페이지가 보이면 성공입니다.


2. shadcn/ui Blocks로 대시보드 추가

shadcn/ui는 “Blocks”라는 완성형 섹션을 CLI로 바로 추가할 수 있습니다. dashboard-01 블록을 프로젝트에 주입합니다.

# 프로젝트 루트에서 실행
npx shadcn add dashboard-01

이 명령을 실행하면 예시 파일들이 자동으로 추가됩니다. 대표적으로:

app/
  dashboard/
    page.tsx
    data.json

참고: CLI 실행 중 프레임워크/경로 관련 질문이 나올 수 있습니다. 기본값을 선택하면 자동으로 알맞게 배치됩니다.

이제 개발 서버(켜져 있다면 자동 반영) 화면에서 /dashboard 경로로 진입하면 샘플 대시보드가 동작합니다.


3. 홈(랜딩) 페이지에 대시보드 연결

영상처럼 프로젝트 진입 시 대시보드가 바로 보이게 하려면, 라우팅을 홈(/)에서 대시보드로 연결합니다. 방법은 2가지입니다.

방법 A) /에서 대시보드 페이지로 리다이렉트(간단)

app/routes/index.tsx(또는 app/routes/ 아래의 홈 라우트 파일)에 다음처럼 리다이렉트를 추가하세요.

// app/routes/index.tsx
import { redirect } from "@tanstack/start"; // 사용 중인 버전에 맞는 헬퍼를 임포트하세요

export default function Index() {
  // 클라이언트/서버 라우팅 방식에 따라 구현이 다를 수 있습니다.
  // 가장 단순한 방법: 링크 버튼 제공
  if (typeof window !== 'undefined') {
    window.location.replace('/dashboard');
  }
  return null;
}

: TanStack Start의 라우팅/리다이렉트 API는 버전에 따라 달라질 수 있습니다. 위처럼 단순 이동을 쓰거나, 공식 문서의 리다이렉트 유틸을 활용해도 됩니다.

방법 B) /dashboard/page.tsx 내용을 홈 라우트로 복사(영상과 유사)

app/dashboard/page.tsx의 JSX를 복사하여 홈 라우트 파일(예: app/routes/index.tsx)에 붙여넣고, data.json 임포트 경로만 맞춰주면 됩니다.

// app/routes/index.tsx (예시)
import data from "../dashboard/data.json"; // 경로는 프로젝트 구조에 맞게 조정

export default function Page() {
  return (
    <main>
      {/* dashboard-01에서 복사해 온 섹션들 */}
      {/* ... 카드/차트/테이블 ... */}
    </main>
  );
}

주의: 복사 방식은 파일이 분산되므로, 유지보수는 리다이렉트 방식(A)을 추천합니다.


4. 기본 헤더/레이아웃 정리(선택)

영상에서는 초기 템플릿의 헤더를 제거했습니다. TanStack Start는 루트 레이아웃 파일(일반적으로 app/routes/__root.tsx)에서 전역 레이아웃을 구성합니다. 해당 파일을 열어 불필요한 헤더/로고를 삭제하거나 주석 처리하세요.

// app/routes/__root.tsx (개념 예시)
export default function Root({ children }: { children: React.ReactNode }) {
  return (
    <div className="min-h-dvh">
      {/* 필요 시 전역 헤더 삭제 */}
      {children}
    </div>
  );
}

실제 초기 템플릿의 마크업 구조는 프로젝트 생성 시 선택 옵션/버전에 따라 조금씩 다릅니다. 핵심은 전역 레이아웃에서 헤더를 빼고 children만 렌더링하도록 조정하는 것입니다.


5. 다크 모드 적용 (ThemeProvider + ModeToggle)

shadcn/ui 문서의 Vite 다크 모드 가이드를 따라 ThemeProviderModeToggle을 추가합니다.

5-1) ThemeProvider 생성

components/theme-provider.tsx 파일을 새로 만들고 아래 내용을 추가하세요.

// components/theme-provider.tsx
import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  return (
    <NextThemesProvider
      attribute="class"
      defaultTheme="system"
      enableSystem
      disableTransitionOnChange
    >
      {children}
    </NextThemesProvider>
  );
}

참고: 프로젝트에 따라 next-themes 설치가 필요할 수 있습니다. 오류가 나면 아래를 실행하세요.

pnpm add next-themes

5-2) 루트 레이아웃에 Provider 적용

app/routes/__root.tsx에서 ThemeProvider로 전역을 감쌉니다.

// app/routes/__root.tsx (개념 예시)
import { ThemeProvider } from "@/components/theme-provider";

export default function Root({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider>
      {children}
    </ThemeProvider>
  );
}

5-3) ModeToggle 컴포넌트 추가

components/mode-toggle.tsx 파일을 만들고 아래처럼 구성합니다.

// components/mode-toggle.tsx
import { Moon, Sun } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useTheme } from "next-themes";

export function ModeToggle() {
  const { setTheme } = useTheme();
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="icon" aria-label="Toggle theme">
          <Sun className="h-5 w-5" />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => setTheme("light")}>Light</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("dark")}>Dark</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("system")}>System</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

5-4) 헤더(또는 우측 상단)에 토글 배치

전역 헤더를 사용한다면 그 영역에, 대시보드 상단 바가 있다면 그 자리에 ModeToggle을 넣어주세요.

// 예: app/routes/__root.tsx 일부
import { ModeToggle } from "@/components/mode-toggle";

export default function Root({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider>
      <div className="min-h-dvh">
        <header className="flex items-center justify-end p-4">
          <ModeToggle />
        </header>
        {children}
      </div>
    </ThemeProvider>
  );
}

이제 라이트/다크 모드 전환이 실시간으로 적용됩니다.


6. 스타일 확인 및 미세 조정

  • 반응형: 브라우저 폭을 줄여 사이드바/카드/차트가 자연스럽게 재배치되는지 확인
  • 다크 모드: 각 카드, 차트, 테이블의 대비/가독성 확인
  • 아이콘: lucide-react가 필요 시 자동 설치되지만, 에러가 뜨면 pnpm add lucide-react 실행

7. 흔한 오류 & 해결법

  1. npx shadcn add dashboard-01가 안 될 때

    • 최신 shadcn CLI 사용 중인지 확인: npx shadcn@latest ... 형태로 실행해 보세요.
    • 프레임워크 선택 단계에서 TanStack 또는 React/Vite가 맞는지 체크.
  2. Theme 관련 타입/의존성 에러

    • next-themes 미설치 → pnpm add next-themes
    • Provider import 경로가 @/components/theme-provider와 일치하는지 확인
  3. 경로 에러 (Cannot find module '@/...')

    • tsconfig.jsonpaths 설정과 import 경로가 일치하는지 확인 (@/* alias 등)
  4. 포트 충돌

    • 다른 앱이 같은 포트를 사용 중이면 dev 서버가 다른 포트를 선택합니다. 터미널에 표시된 주소로 접속하세요.

8. (선택) 최신 Tailwind v4 경로 요약

  • 일부 공식 가이드는 TanStack Start 프로젝트를 Tailwind 미포함으로 만든 뒤, Tailwind v4를 별도로 설치하도록 안내합니다.

  • 이 경로를 택하면 아래 순서로 진행하세요.

    1. npx create-start-app@latest 실행 시 Tailwind: No
    2. Tailwind v4 설치 가이드에 따라 tailwindcss 및 PostCSS 플러그인 설치/설정
    3. npx shadcn init → 컴포넌트 설정 후 npx shadcn add dashboard-01
    4. 5장 다크 모드 설정 동일

처음 따라 하기에는 본 가이드의 “빠른 경로”가 더 수월합니다. v4로 넘어가고 싶다면 새 브랜치에서 시도하세요.


9. 커스터마이징 아이디어

  • 카드 데이터 교체: app/dashboard/data.json의 값들을 실제 비즈니스 데이터로 교체
  • 차트 연동: 서버/DB 데이터를 불러와 차트/테이블 갱신 (TanStack Query 권장)
  • 라우팅 확장: Projects, Analytics 등 섹션을 라우트로 분리
  • i18n: 한국어 UI 텍스트 적용 및 날짜/숫자 포맷 현지화

10. 마무리 체크리스트

  • /dashboard 또는 /에서 대시보드가 보인다
  • 사이드바/차트/테이블이 반응형으로 동작한다
  • ModeToggle로 라이트/다크 전환이 된다
  • ESLint/TypeScript 에러 없이 빌드된다

부록: 자주 쓰는 스크립트

pnpm dev           # 개발 서버 시작
pnpm build         # 프로덕션 빌드
pnpm preview       # 로컬 프리뷰
반응형