Claude Code Plugins

Community-maintained marketplace

Feedback

초보자 FAQ - "이건 어디서 설정해?" 모든 질문 해결

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name faq-guide
description 초보자 FAQ - "이건 어디서 설정해?" 모든 질문 해결
triggers faq, 어디서, 설정, 질문, where, 찾기

초보자 FAQ 가이드

"이건 어디서 설정해?" 모든 질문에 대한 답변


빠른 찾기 목차

질문 파일 위치
API 키 설정 .env.local
색상 변경 tailwind.config.ts
폰트 변경 src/app/layout.tsx
로고 변경 public/logo.png
페이지 제목 변경 src/app/layout.tsx
결제 설정 .env.local + src/lib/stripe.ts
데이터베이스 연결 .env.local + prisma/schema.prisma
로그인 설정 src/lib/auth.ts
메뉴 추가 src/components/Navigation.tsx
새 페이지 추가 src/app/[페이지명]/page.tsx

1. 환경변수 / API 키

API 키 설정

질문: "OpenAI API 키는 어디에 넣어?"

위치: .env.local (프로젝트 루트)

# .env.local

# AI 서비스
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxx

# 결제
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx

# 데이터베이스
DATABASE_URL=postgresql://user:password@host:5432/db

# 인증
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-here

# 소셜 로그인
GOOGLE_CLIENT_ID=xxxxxxxxxxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxxxxx

# 스토리지
CLOUDFLARE_R2_ACCESS_KEY=xxxxxxxxxxxxx
CLOUDFLARE_R2_SECRET_KEY=xxxxxxxxxxxxx
CLOUDFLARE_R2_BUCKET=my-bucket

주의사항:

  • .env.local은 git에 올리면 안 됨 (.gitignore에 포함되어 있음)
  • NEXT_PUBLIC_ 접두사가 붙은 것만 브라우저에서 접근 가능
  • 배포 시 Vercel/Railway 대시보드에서 환경변수 설정 필요

2. 디자인 / 스타일

색상 변경

질문: "메인 색상을 파란색에서 초록색으로 바꾸고 싶어"

위치: tailwind.config.ts

// tailwind.config.ts
import type { Config } from 'tailwindcss';

const config: Config = {
  theme: {
    extend: {
      colors: {
        // 여기서 색상 변경!
        primary: {
          50: '#f0fdf4',   // 가장 밝은
          100: '#dcfce7',
          200: '#bbf7d0',
          300: '#86efac',
          400: '#4ade80',
          500: '#22c55e',  // 메인 색상
          600: '#16a34a',
          700: '#15803d',
          800: '#166534',
          900: '#14532d',  // 가장 어두운
        },
      },
    },
  },
};

export default config;

색상 팔레트 생성 도구:


폰트 변경

질문: "글꼴을 바꾸고 싶어"

위치: src/app/layout.tsx

// src/app/layout.tsx

// 방법 1: Google Fonts 사용 (권장)
import { Noto_Sans_KR, Inter } from 'next/font/google';

const notoSansKR = Noto_Sans_KR({
  subsets: ['latin'],
  weight: ['400', '500', '700'],
  variable: '--font-noto',
});

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
});

export default function RootLayout({ children }) {
  return (
    <html lang="ko" className={`${notoSansKR.variable} ${inter.variable}`}>
      <body className="font-noto">
        {children}
      </body>
    </html>
  );
}
// tailwind.config.ts
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        noto: ['var(--font-noto)', 'sans-serif'],
        inter: ['var(--font-inter)', 'sans-serif'],
      },
    },
  },
};

인기 한글 폰트:

  • Noto_Sans_KR - 가독성 좋음
  • Pretendard - 모던함
  • Spoqa_Han_Sans_Neo - 깔끔함

로고 변경

질문: "로고를 바꾸고 싶어"

위치:

  • public/logo.png - 메인 로고
  • public/logo-dark.png - 다크모드 로고
  • public/favicon.ico - 브라우저 탭 아이콘
// src/components/Logo.tsx
import Image from 'next/image';

export function Logo() {
  return (
    <Image
      src="/logo.png"      // ← 이 파일 교체
      alt="MySaaS Logo"
      width={120}
      height={40}
      priority
    />
  );
}

파비콘 생성:

  1. 512x512 PNG 로고 준비
  2. https://realfavicongenerator.net 에서 생성
  3. 생성된 파일들을 public/ 폴더에 복사

3. 페이지 / 라우팅

페이지 제목 변경

질문: "브라우저 탭에 뜨는 제목을 바꾸고 싶어"

위치: src/app/layout.tsx (전체) 또는 각 페이지의 page.tsx

// src/app/layout.tsx - 전체 사이트 기본값
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: {
    default: 'MySaaS - 서비스 설명',        // 기본 제목
    template: '%s | MySaaS',               // 페이지별 제목 템플릿
  },
  description: '서비스 설명 150자 이내',
};

// src/app/pricing/page.tsx - 개별 페이지
export const metadata: Metadata = {
  title: '요금제',  // → "요금제 | MySaaS" 로 표시됨
  description: '다양한 요금제를 확인하세요',
};

새 페이지 추가

질문: "새 페이지를 만들고 싶어"

위치: src/app/[페이지명]/page.tsx

# 예: /about 페이지 만들기
mkdir src/app/about
touch src/app/about/page.tsx
// src/app/about/page.tsx
export const metadata = {
  title: '소개',
  description: '회사 소개 페이지',
};

export default function AboutPage() {
  return (
    <div className="container mx-auto py-8">
      <h1 className="text-3xl font-bold">회사 소개</h1>
      <p>내용...</p>
    </div>
  );
}

URL 구조:

src/app/page.tsx           → /
src/app/about/page.tsx     → /about
src/app/blog/page.tsx      → /blog
src/app/blog/[slug]/page.tsx → /blog/hello-world (동적 라우트)

메뉴 추가

질문: "상단 네비게이션에 메뉴를 추가하고 싶어"

위치: src/components/Navigation.tsx 또는 src/components/Header.tsx

// src/components/Navigation.tsx

const menuItems = [
  { href: '/', label: '홈' },
  { href: '/features', label: '기능' },
  { href: '/pricing', label: '요금제' },
  { href: '/about', label: '소개' },      // ← 새 메뉴 추가
  { href: '/contact', label: '문의' },    // ← 새 메뉴 추가
];

export function Navigation() {
  return (
    <nav>
      {menuItems.map((item) => (
        <Link key={item.href} href={item.href}>
          {item.label}
        </Link>
      ))}
    </nav>
  );
}

4. 인증 / 로그인

로그인 설정

질문: "구글 로그인을 추가하고 싶어"

위치:

  1. .env.local - API 키
  2. src/lib/auth.ts - 설정

Step 1: Google Cloud Console 설정

  1. https://console.cloud.google.com 접속
  2. 새 프로젝트 생성
  3. APIs & Services → Credentials → Create Credentials → OAuth 2.0
  4. Authorized redirect URIs: http://localhost:3000/api/auth/callback/google

Step 2: 환경변수 설정

# .env.local
GOOGLE_CLIENT_ID=xxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxx

Step 3: auth.ts 설정

// src/lib/auth.ts
import GoogleProvider from 'next-auth/providers/google';

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    // 다른 프로바이더 추가...
  ],
};

로그인 페이지 커스터마이징

질문: "로그인 페이지 디자인을 바꾸고 싶어"

위치: src/app/(auth)/login/page.tsx

// src/app/(auth)/login/page.tsx
'use client';

import { signIn } from 'next-auth/react';

export default function LoginPage() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="bg-white p-8 rounded-xl shadow-lg max-w-md w-full">
        <h1 className="text-2xl font-bold text-center mb-6">로그인</h1>

        <button
          onClick={() => signIn('google', { callbackUrl: '/dashboard' })}
          className="w-full bg-white border py-3 rounded-lg flex items-center justify-center gap-2"
        >
          <GoogleIcon />
          Google로 로그인
        </button>

        <div className="my-4 text-center text-gray-500">또는</div>

        <form>
          <input
            type="email"
            placeholder="이메일"
            className="w-full p-3 border rounded-lg mb-3"
          />
          <input
            type="password"
            placeholder="비밀번호"
            className="w-full p-3 border rounded-lg mb-4"
          />
          <button className="w-full bg-primary-500 text-white py-3 rounded-lg">
            이메일로 로그인
          </button>
        </form>
      </div>
    </div>
  );
}

5. 결제

결제 설정

질문: "Stripe 결제를 연동하고 싶어"

위치:

  1. .env.local - API 키
  2. src/lib/stripe.ts - Stripe 설정
  3. src/app/api/webhooks/stripe/route.ts - 웹훅

Step 1: Stripe 대시보드 설정

  1. https://dashboard.stripe.com 가입
  2. Developers → API keys에서 키 복사
  3. Developers → Webhooks → Add endpoint

Step 2: 환경변수

# .env.local
STRIPE_SECRET_KEY=sk_test_xxxxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx

Step 3: 가격 설정

// src/config/pricing.ts
export const PLANS = {
  free: {
    name: '무료',
    price: 0,
    priceId: null,
    features: ['기본 기능', '월 100회 사용'],
  },
  pro: {
    name: '프로',
    price: 9900,
    priceId: 'price_xxxxxxxxxxxxx',  // Stripe에서 생성한 Price ID
    features: ['모든 기능', '무제한 사용', '우선 지원'],
  },
};

가격 변경

질문: "구독 가격을 바꾸고 싶어"

위치:

  1. Stripe Dashboard → Products
  2. src/config/pricing.ts
// src/config/pricing.ts
export const PLANS = {
  starter: {
    name: '스타터',
    price: 4900,           // ← 가격 변경
    monthlyPriceId: 'price_xxx',
    yearlyPriceId: 'price_yyy',
    yearlyPrice: 49000,    // 연간 (2개월 할인)
  },
  pro: {
    name: '프로',
    price: 14900,          // ← 가격 변경
    monthlyPriceId: 'price_xxx',
    yearlyPriceId: 'price_yyy',
    yearlyPrice: 149000,
  },
};

6. 데이터베이스

데이터베이스 연결

질문: "데이터베이스 연결은 어떻게 해?"

위치:

  1. .env.local - 연결 URL
  2. prisma/schema.prisma - 스키마 정의

Step 1: 데이터베이스 생성 (예: Supabase)

  1. https://supabase.com 가입
  2. 새 프로젝트 생성
  3. Settings → Database → Connection string 복사

Step 2: 환경변수 설정

# .env.local
DATABASE_URL="postgresql://postgres:password@db.xxxxx.supabase.co:5432/postgres"

Step 3: Prisma 설정

# 마이그레이션 생성 및 적용
npx prisma migrate dev --name init

# DB에서 타입 생성
npx prisma generate

# DB 확인
npx prisma studio

테이블 추가

질문: "새 테이블을 추가하고 싶어"

위치: prisma/schema.prisma

// prisma/schema.prisma

// 새 모델 추가
model Product {
  id          String   @id @default(cuid())
  name        String
  description String?
  price       Float
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  userId      String
  user        User     @relation(fields: [userId], references: [id])
}

// User 모델에 관계 추가
model User {
  // ... 기존 필드
  products    Product[]
}
# 마이그레이션 실행
npx prisma migrate dev --name add_products

# 타입 생성
npx prisma generate

7. 이메일

이메일 발송 설정

질문: "이메일 발송은 어떻게 해?"

위치:

  1. .env.local - API 키
  2. src/lib/email.ts - 이메일 설정

Resend 사용 예시:

# .env.local
RESEND_API_KEY=re_xxxxxxxxxxxxx
// src/lib/email.ts
import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

export async function sendWelcomeEmail(email: string, name: string) {
  await resend.emails.send({
    from: 'MySaaS <noreply@mysaas.com>',
    to: email,
    subject: '환영합니다!',
    html: `<p>안녕하세요 ${name}님, 가입을 환영합니다!</p>`,
  });
}

이메일 템플릿 위치: src/emails/ 또는 src/lib/email-templates/


8. 파일 업로드

이미지 업로드 설정

질문: "이미지 업로드는 어떻게 해?"

위치:

  1. .env.local - 스토리지 키
  2. src/lib/storage.ts - 업로드 설정

Cloudflare R2 예시:

# .env.local
CLOUDFLARE_R2_ACCESS_KEY=xxxxx
CLOUDFLARE_R2_SECRET_KEY=xxxxx
CLOUDFLARE_R2_BUCKET=my-bucket
CLOUDFLARE_R2_ENDPOINT=https://xxxxx.r2.cloudflarestorage.com
// src/lib/storage.ts
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({
  region: 'auto',
  endpoint: process.env.CLOUDFLARE_R2_ENDPOINT,
  credentials: {
    accessKeyId: process.env.CLOUDFLARE_R2_ACCESS_KEY!,
    secretAccessKey: process.env.CLOUDFLARE_R2_SECRET_KEY!,
  },
});

export async function uploadFile(file: File): Promise<string> {
  const key = `uploads/${Date.now()}-${file.name}`;

  await s3.send(new PutObjectCommand({
    Bucket: process.env.CLOUDFLARE_R2_BUCKET,
    Key: key,
    Body: Buffer.from(await file.arrayBuffer()),
    ContentType: file.type,
  }));

  return `${process.env.CLOUDFLARE_R2_PUBLIC_URL}/${key}`;
}

9. 자주 하는 실수

환경변수가 안 읽혀요

원인:

  1. .env.local 파일명이 틀림 (.env 아님!)
  2. 서버를 재시작 안 함
  3. 클라이언트에서 NEXT_PUBLIC_ 없이 접근

해결:

# 서버 재시작
npm run dev

페이지가 404 에러

원인:

  1. 파일명이 page.tsx가 아님
  2. 폴더 위치가 src/app/ 안이 아님
  3. 대소문자 오류

확인:

✅ src/app/about/page.tsx     → /about
❌ src/app/about/About.tsx    → 404
❌ src/pages/about.tsx        → 404 (App Router에서)

데이터베이스 연결 실패

원인:

  1. DATABASE_URL 형식 오류
  2. 데이터베이스 서버가 꺼져있음
  3. IP 화이트리스트 미설정

확인:

# 연결 테스트
npx prisma db push

Stripe 웹훅 실패

원인:

  1. 웹훅 시크릿 오류
  2. 로컬에서 테스트 시 ngrok 미사용
  3. 웹훅 URL 오류

로컬 테스트:

# Stripe CLI 설치 후
stripe listen --forward-to localhost:3000/api/webhooks/stripe

10. 빠른 검색 테이블

하고 싶은 것 파일 위치
메인 색상 변경 tailwind.config.ts
폰트 변경 src/app/layout.tsx
로고 변경 public/logo.png
파비콘 변경 public/favicon.ico
사이트 제목 변경 src/app/layout.tsx
API 키 설정 .env.local
메뉴 추가 src/components/Navigation.tsx
새 페이지 추가 src/app/[이름]/page.tsx
푸터 수정 src/components/Footer.tsx
소셜 로그인 추가 src/lib/auth.ts
결제 연동 src/lib/stripe.ts
이메일 설정 src/lib/email.ts
데이터베이스 스키마 prisma/schema.prisma
환경변수 .env.local
빌드 설정 next.config.js
라우트 리다이렉트 next.config.jsredirects()
404 페이지 src/app/not-found.tsx
에러 페이지 src/app/error.tsx
로딩 UI src/app/loading.tsx
SEO 메타태그 page.tsxmetadata
sitemap src/app/sitemap.ts
robots.txt src/app/robots.ts