Communitygithub.com

랜딩 페이지 생성

완전한 맞춤형 Next.js 랜딩 페이지를 처음부터 구축합니다. /landing-page 명령어로 트리거됩니다.

랜딩 페이지 생성란 무엇인가요?

이 스킬은 사용자가 제공한 회사명, 업종, 슬로건, 타겟 고객, CTA 목표를 기반으로 완전한 맞춤형 Next.js 랜딩 페이지를 자동 생성하는 오케스트레이터입니다. '/landing-page' 명령어로 실행되며, 먼저 'landing-page-copy' 스킬을 호출하여 콘텐츠 브리프를 생성하고, 이후 'landing-page-seo'(SEO 계획)와 'ui-ux-pro-max'(디자인 인텔리전스)를 병렬로 실행합니다. 생성된 콘텐츠, 디자인 토큰(색상, 타이포그래피, 애니메이션 스타일 등), SEO 메타데이터를 통합하여 최신 Next.js 16, React 19, Tailwind CSS, Framer Motion 스택으로 완전한 정적 사이트를 빌드합니다. 모든 파일은 수동 편집 없이 자동으로 생성되며, TypeScript 타입 체크를 통과한 후 최종 빌드 결과를 보고합니다. 지원 플랫폼은 Claude Code, Cursor, Codex 등 AI 어시스턴트 환경입니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Demian-T/plugin-landing-page-creation/tree/HEAD/skills/landing-page

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

랜딩 페이지 — 오케스트레이터

출력 디렉토리: ./generated/{slug}-landing (현재 작업 디렉토리 기준, 또는 LANDING_PAGE_OUTPUT_DIR 환경 변수로 설정 가능)


1단계 — 입력 파싱

|로 인자를 분할 (trim 적용):

  • [0] → company_name (없으면 업종에 맞는 창의적인 이름 생성)
  • [1] → industry (없으면 추론)
  • [2] → tagline_hint (선택 사항)
  • [3] → target_audience (선택 사항)
  • [4] → cta_goal (선택 사항, 기본값: "무료로 시작하기")

slug = company_name을 소문자로 변환하고, 악센트 제거, 공백을 하이픈으로 대체.

출력 경로 확인:

OUTPUT_DIR="${LANDING_PAGE_OUTPUT_DIR:-./generated}/{slug}-landing"

2단계 — 콘텐츠 브리프 (landing-page-copy)

landing-page-copy 스킬을 호출하여 파싱된 입력을 전달합니다. 전체 CONTENT_BRIEF 출력이 반환될 때까지 기다립니다.

브리프에는 다음이 포함됩니다: 히어로 카피, 기능, 사용 후기, FAQ, 소개, 가격 플랜, 블로그 글, 사례 연구, 내비게이션 레이블. 이 카피는 생성된 사이트의 모든 텍스트에 대한 진실 공급원입니다 — 코드 생성 중에 카피를 임의로 생성하지 마십시오.


3단계 — 디자인 + SEO (병렬 실행)

3-A. 디자인 인텔리전스 (ui-ux-pro-max)

다음 3개 명령어를 병렬로 실행:

python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry}" --design-system -p "{company_name}"
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry}" --domain color -n 3
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry} landing page" --domain typography -n 3

참고: ui-ux-pro-max 스킬이 설치되어 있어야 합니다. 없으면 업종 및 브랜드 컨텍스트에서 직접 디자인 브리프를 합성하세요.

디자인 브리프로 합성:

  • 시각적 분위기 (3-5개 형용사)
  • 색상 팔레트: primary, secondary, accent, bg, bg-soft, bg-card, surface, text, text-muted, text-inverse, border, border-subtle, dot
  • 타이포그래피: 제목 글꼴 + 본문 글꼴 (Google Fonts에 존재해야 함)
  • 레이아웃 결정: 히어로 유형, 기능 레이아웃, 사용 후기 스타일
  • 애니메이션 스타일: 미묘함 / 보통 / 화려함
  • 시그니처 디테일: 이 페이지를 기억에 남게 만드는 독특한 시각적 요소 하나

3-B. SEO 계획 (landing-page-seo)

landing-page-seo 스킬을 company_name, industry 및 CONTENT_BRIEF와 함께 호출합니다. 전체 SEO_PLAN 출력이 반환될 때까지 기다립니다.

계획에는 다음이 포함됩니다: 페이지별 메타 태그, 스키마 마크업 유형, 사이트맵 설정, Core Web Vitals 빌드 힌트, AI SEO 힌트.


4단계 — 모든 파일 작성

{OUTPUT_DIR}를 생성한 다음, Write 도구를 사용하여 모든 파일을 처음부터 작성합니다. 모든 카피는 CONTENT_BRIEF를, 모든 메타/스키마는 SEO_PLAN을 사용합니다. 템플릿이나 플레이스홀더 텍스트는 사용하지 않습니다.

4-A. 인프라

package.json:

{
  "name": "{slug}-landing",
  "version": "0.1.0",
  "private": true,
  "scripts": { "dev": "next dev", "build": "next build", "start": "next start" },
  "dependencies": {
    "next": "^16.2.7",
    "react": "^19.2.0",
    "react-dom": "^19.2.0",
    "lucide-react": "^0.474.0",
    "framer-motion": "^12.40.0"
  },
  "devDependencies": {
    "@next/mdx": "^16.2.7",
    "@mdx-js/loader": "^3.0.0",
    "@mdx-js/react": "^3.0.0",
    "@types/mdx": "^2.0.0",
    "typescript": "^5",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "tailwindcss": "^3.4.1",
    "postcss": "^8.5.10",
    "autoprefixer": "^10.0.1"
  }
}

버전: 검증된 스택 Next 16 + React 19 + framer-motion 12 + lucide-react 0.474 (build output: 'export' OK). next를 14.2.0으로 고정하거나 react/react-dom을 ^18로 고정하지 마십시오 (취약한 버전 — 2025-12-11 Next 중요 권고). lucide-react는 >= 0.474여야 합니다 (0.378 및 < 0.474 버전은 React 19 피어를 선언하지 않아 npm install이 실패합니다).

next.config.js:

const withMDX = require('@next/mdx')()
module.exports = withMDX({
  output: 'export',
  images: { unoptimized: true },
  pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
})

tsconfig.json: 표준 Next.js tsconfig, ./에 대한 @/* 경로 별칭 및 "jsx": "react-jsx" 포함 (Next 16은 React 자동 런타임 사용 — "preserve"는 빌드 시 자동 재작성됨)

tailwind.config.ts:

  • darkMode: 'class'
  • fontFamily: 제목 + 본문 CSS 변수
  • animation: marquee, float, line-grow
  • keyframes: marquee translateX(0%)→translateX(-50%), float, lineGrow

postcss.config.js: tailwind + autoprefixer

mdx-components.tsx: h1 h2 h3 p ul li strong blockquote를 CSS 변수를 사용하여 스타일이 지정된 요소로 매핑

app/globals.css:

  • @tailwind base/components/utilities
  • :root의 CSS 변수 — 디자인 브리프의 모든 디자인 토큰
  • html.dark { ... } — 다크 모드에 대한 모든 변수 재정의
  • CSS 변수를 사용하는 body, background-color + color에 transition 적용
  • 사용자 정의 유틸리티: .text-gradient, .dot-grid, .glass-card, .bracket-card, .clip-diagonal-bottom, .clip-diagonal-top
  • 규칙: 컴포넌트의 모든 색상 참조는 CSS 변수를 사용합니다 — 하드코딩된 16진수 값 없음

4-B. 컴포넌트

각각 .tsx로 작성합니다. 모든 컴포넌트는 lib/data.ts에서 카피를 읽어옵니다. 모든 색상은 CSS 변수를 통해 지정됩니다.

components/DarkModeToggle.tsx:

  • 'use client', 마운트 시 localStorage 읽기, <html>에서 dark 클래스 전환
  • 환경 설정 저장, lucide-react의 Sun/Moon 아이콘

components/LogoCarousel.tsx:

  • 'use client', 순수 CSS marquee (animate-marquee), JS 스크롤 없음
  • lib/data.ts의 브랜드 이름, 매끄러운 루프를 위해 복제

components/ContactForm.tsx:

  • 'use client', 상태: 'idle' | 'sending' | 'sent' | 'error'
  • 숨겨진 form-name이 있는 <form data-netlify="true" name="contact">
  • 필드: name, email, company, message
  • 제출: fetch('/', { method: 'POST', body: new URLSearchParams(new FormData(form)) })

components/Navbar.tsx: 고정, 스크롤 인식, 모바일 메뉴, <DarkModeToggle />

components/Hero.tsx:

  • useReducedMotion 확인이 포함된 Framer Motion 진입 애니메이션
  • <data value="{stat.value}">가 있는 통계 행 (AI SEO)
  • 디자인 브리지의 시그니처 디자인 디테일

components/Features.tsx: whileInView Framer Motion, 지연 시간 분산

components/Testimonials.tsx: 카드당 whileInView Framer Motion

components/FAQ.tsx:

  • 'use client', 아코디언
  • <dl>/<dt>/<dd> 시맨틱 마크업 (FAQPage 스키마 + AI SEO)

components/Pricing.tsx:

  • 'use client', 월간/연간 청구 전환, −20% 배지 포함
  • price vs price_annual 전환

components/About.tsx: 스토리 + 가치 components/Footer.tsx: 태그라인 + 내비게이션 + 저작권

컴포넌트 규칙:

  • 'use client'는 대화형/브라우저 API 컴포넌트에만 사용
  • 타입 전용 가져오기는 import type { X } 사용
  • 동적 lucide 아이콘: import type { LucideIcon } from 'lucide-react', 그런 다음 (Icons as any)[name] as LucideIcon | undefined. 아이콘 prop 타입은 LucideIcon으로 지정 — React.ComponentType<{size?:number}>가 아님 (lucide의 size는 string|number이므로 좁은 타입은 next build 타입 검사에서 실패)
  • 모든 색상은 CSS 변수 사용 — 하드코딩된 16진수 값 없음
  • 애니메이션은 Framer Motion 사용 (IntersectionObserver 없음)
  • 모든 텍스트는 lib/data.ts에서 가져옴

4-C. 페이지

app/layout.tsx:

  • next/font/google을 통한 Google Fonts
  • SEO_PLAN 홈페이지 메타의 메타데이터
  • JSON-LD: SEO_PLAN의 Organization + WebSite (또는 SoftwareApplication)
  • <head>의 다크 모드 깜빡임 방지:
    try{if(localStorage.getItem('theme')==='dark'||(localStorage.getItem('theme')===null&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark')}}catch(e){}
    
  • <html>에 suppressHydrationWarning
  • <link rel="preconnect" href="https://fonts.googleapis.com">

app/page.tsx: Navbar + Hero + LogoCarousel + Features + Testimonials + Pricing + FAQ + ContactForm + Footer

app/tarifs/page.tsx: SEO_PLAN의 메타데이터 + JSON-LD (Offer + FAQPage) + Navbar + Pricing + FAQ + ContactForm + Footer

app/a-propos/page.tsx: SEO_PLAN의 메타데이터 + JSON-LD (AboutPage + Organization) + Navbar + About + Footer

app/blog/layout.tsx + app/blog/page.tsx: lib/blog.ts의 목록

app/blog/{slug-1}/page.mdx + app/blog/{slug-2}/page.mdx:

  • CONTENT_BRIEF blog[]의 콘텐츠
  • <article> + <time datetime="..."> 시맨틱 래핑
  • 첫 번째 단락에 TL;DR (AI SEO 인용 가능성)

app/cas-clients/layout.tsx + app/cas-clients/page.tsx: lib/case-studies.ts의 목록

app/cas-clients/{slug-1}/page.mdx + app/cas-clients/{slug-2}/page.mdx:

  • CONTENT_BRIEF case_studies[]의 콘텐츠
  • 명시적인 ## 도전 과제 / ## 솔루션 / ## 결과 H2 구조 (AI SEO)
  • SEO_PLAN의 BreadcrumbList JSON-LD

app/sitemap.ts: 모든 페이지 + 게시물 + 사례 연구에 대한 SEO_PLAN sitemap_config

app/robots.ts: 모든 항목 허용, sitemap URL


4-D. 데이터 파일

lib/data.ts — CONTENT_BRIEF의 모든 카피:

export const siteData = {
  nav: { links: [...], cta: "..." },
  hero: { badge, headline_a, subheadline, cta_primary, cta_secondary, social_proof_bar, stats },
  logoCarousel: { section_label, brands: [...] },
  features: { badge, heading, sub, items: [...] },
  testimonials: [...],
  faq: { items: [...] },
  about: { headline, story, values: [...] },
  pricing: { heading, sub, plans: [...] },
  contact: { heading, sub, form_cta },
  footer: { tagline }
}

lib/blog.ts: CONTENT_BRIEF의 블로그 레지스트리 lib/case-studies.ts: CONTENT_BRIEF의 사례 연구 레지스트리

히어로 이미지 — 다음 Unsplash 플레이스홀더 중에서 선택:

  • 기술/SaaS/핀테크: https://images.unsplash.com/photo-1518770660439-4636190af475?w=1600&q=80
  • 건강/웰니스: https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?w=1600&q=80
  • 식품/바이오: https://images.unsplash.com/photo-1504674900247-0877df9cc836?w=1600&q=80
  • 스포츠/피트니스: https://images.unsplash.com/photo-1517836357463-d25dfeac3438?w=1600&q=80
  • 패션/럭셔리: https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1600&q=80
  • 부동산: https://images.unsplash.com/photo-1560518883-ce09059eeffa?w=1600&q=80
  • 교육: https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=1600&q=80
  • 기본값: https://images.unsplash.com/photo-1497366216548-37526070297c?w=1600&q=80

5단계 — 빌드

cd {OUTPUT_DIR}
npm install
npm run build

TypeScript 오류 — 수정 후 재시도:

  • import { X } → 타입 전용 가져오기는 import type { X } 사용
  • 동적 아이콘: (Icons as any)[name] as LucideIcon | undefined (lucide-react에서 타입 가져오기); 아이콘 prop 타입을 LucideIcon으로 지정, ComponentType<{size?:number}> 사용 금지
  • 모든 TypeScript 오류를 수정한 후 성공을 보고하세요

6단계 — 보고

🏢  회사명:    {company_name} — {industry}
🎨  디자인:     {mood} | {heading font} / {body font}
✨  시그니처:   {distinctive detail}
📝  헤드라인:   "{headline_a}"
📄  페이지:      / · /tarifs · /a-propos · /blog · /cas-clients
🔍  SEO:        {page title} | {schema types}
📁  출력:       {OUTPUT_DIR}

로컬 미리보기: cd {OUTPUT_DIR} && npm run dev

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬