
바이브코딩으로 퍼시픽링크 AI 썸네일 SaaS를 1시간에 완성하기
이런 분께 Next.js 기본기가 있고 AI 코딩 도구로 결제·인증까지 붙인 서비스를 혼자 런칭해 보려는 인디해커·사이드프로젝트 개발자
알고 있으면 좋은 것 Next.js App Router의 page.tsx / 폴더 라우팅 개념 · 터미널·npm 기본 사용 · Git·GitHub 기초 · Claude Code 등 AI 코딩 에이전트 설치
기획이 먼저다 — 완성본 데모와 8개 파트 목차
완성본을 먼저 보여준다. 랜딩·모바일 최적화·구글 로그인·대시보드·Polar 두 요금제 결제·크레딧 차감·레퍼런스 이미지 첨부·썸네일 생성이 모두 동작한다.
'바이브 코딩은 쉽게 말해서 AI라는 직원을 부리는 건데 직원이 아무리 유능해도 고용주가 명확한 비전과 목표가 없다면 엉뚱한 길로 빠진다'며 기획의 중요성을 강조한다.
목차는 페이지별로 나뉜다 — 랜딩 → 로그인 → 대시보드 → 이미지 생성 AI → 결제 → 크레딧 로직 → 배포 → 마무리. '프롬프트는 어떻게 쓰는지, 에러는 어떤 식으로 잡는지 전반적인 흐름만 따라오면 된다'가 시청 가이드다.
환경 세팅 — Next.js 초기화와 GitHub 체크포인트
IDE(VS Code·Antigravity·Cursor·Windsurf)와 AI(Claude Code·Gemini·Codex) 조합은 자유. 화자는 Antigravity + Claude Code를 쓰되 'Antigravity는 그냥 탭 자동완성용이고 99%의 개발은 클로드 코드로' 한다.
npx create-next-app@latest.로 퍼시픽링크 설치. '@latest는 가장 최신 버전, 한 칸 띄우고 점은 설치 위치를 현재 폴더로 한다는 의미'라고 인자를 하나씩 설명한다.
기본 파일 정리 — README 삭제, public 폴더 이미지 삭제, layout.tsx의 title/description 교체, page.tsx 비우기, devIndicators를 false로 해서 좌하단 마크 제거.
GitHub는 파트별 체크포인트로 사용한다. 리포지토리를 만들고 안내 코드를 복사해 AI에게 '깃허브 연동해줘'라고 시키면 끝. 커밋 diff로 무엇이 바뀌었는지 한눈에 볼 수 있다.
랜딩 페이지 — 레퍼런스 기반 디자인과 컴포넌트 분리
'디자인에서 가장 중요한 건 레퍼런스'. Mobbin·Framer·Webflow에서 참고하거나 21st.dev에서 히어로 섹션 코드를 그대로 복사해 붙여 넣는다.
프롬프트 예: '이 코드를 components/main/hero 컴포넌트로 만들고 랜딩 페이지에서 사용하자', '우리는 유튜브 썸네일을 생성하는 AI 서비스야. 아이콘은 절대 쓰지 말고 SVG를 사용해 줘'.
page.tsx에 코드를 길게 쓰지 말라고 조언한다 — page.tsx는 특정 주소에 대응하는 파일이니 작게 두고 컴포넌트를 조합하는 방식이 유지보수에 유리하다.
CSS로 나온 스타일을 Tailwind로 바꿔 달라 요청하고, 구글 폰트(Indie Flower) 적용, 네비바 배경 투명화, 텍스트·버튼 크기 축소 등 디테일을 반복 수정한다.
로그인 — Supabase MCP + 구글 OAuth 연동
app/auth/page.tsx를 만들고 '인증 퍼시픽링크 기능은 말고 디자인만, 랜딩 페이지의 디자인 언어를 유지한 채로' 먼저 요청한다. '유튜브 썸네일이 필요한 분들은 99% 유튜브 아이디가 있을 것'이라 구글 로그인만 구현.
Supabase 프로젝트 생성 시 리전은 타겟 고객 위치 기준 — 한국이면 아시아 퍼시픽.
Supabase MCP를 붙이면 'SQL 코드를 직접 작성하거나 AI에게 현재 DB를 설명해 줄 필요 없이' 관리된다. 공식 문서의 CLI 명령을 붙여넣고 /mcp에서 인증한다.
실제 요청: 'Supabase MCP를 활용해 auth 페이지에 구글 로그인을 구현. 전역으로 로그인 상태를 관리할 AuthContext를 설정하고, 로그인된 사용자가 바로 DB에 저장되도록 users 테이블을 생성해 자동 연동해 줘'.
구글 클라우드 콘솔에서 OAuth 클라이언트 ID/시크릿을 만들고, 승인된 리디렉션 URI에 Supabase 콜백 URL을 넣은 뒤 두 값을 Supabase에 입력하면 연결 완료.
대시보드 — GPT 스타일 프롬프트 영역과 이미지 테이블
app/dashboard/page.tsx 생성 후 '대시보드는 로그인한 사용자가 이동하는 페이지야. AuthContext와 랜딩 페이지도 이 변화에 맞춰 수정해 줘'라고 요청 — 미로그인 시 auth로 리다이렉트가 걸린다.
레이아웃: 좌측 로고, 우측 프로필 사진(호버 시 상세정보·로그아웃), 중앙에 GPT/Claude처럼 큰 프롬프트 입력 영역. 프롬프트 입력창은 21st.dev의 GPT 스타일 퍼시픽링크 컴포넌트를 가져다 쓴다.
외부 이미지 도메인 미등록 에러가 나자 에러 메시지를 그대로 복사해 AI에게 넘겨 해결한다.
입력창 테두리에는 Magic UI의 Border Beam 이펙트를 적용.
Supabase에 thumbnails 테이블과 이미지 스토리지 버킷을 함께 생성한다.
이미지 생성 — Gemini(나노바나) 연동과 로딩·에러 UI
Google AI Studio에서 API 키를 발급해.env에 넣는다. '환경 변수는 절대 노출돼서 안 됩니다. 저도 이 영상을 찍고 난 후 삭제하겠습니다'.
프롬프트에 나노바나 공식 문서 페이지를 통째로 붙여 넣고 모델명(Gemini 3 Pro Image Preview)을 명시해 '문서에 나와 있는 대로 구현해 줘'라고 지시한다.
상태별 UI를 설계한다 — 생성 시작하면 프롬프트 영역이 아래로 내려가고, 중앙에 로딩 애니메이션(21st.dev), 에러면 큰 X 모양 SVG, 성공하면 이미지 표시. 파일이 길어지자 로딩 애니메이션을 별개 컴포넌트로 분리시킨다.
시스템 프롬프트는 별도 파일로, 영어로 작성한다 — '영어로 작성하는 것이 토큰을 덜 사용하기 때문에 유리'. 나노바나 프롬프트 가이드와 유튜브 썸네일 가이드를 참고 자료로 넣는다. 다만 '별 차이는 없어 보이는데 퀄리티를 높이려면 많은 테스트가 필요할 것 같다'고 솔직히 인정한다.
이미지 저장에는 Supabase 서비스 롤 키가 필요하다. NEXT_PUBLIC_ 접두사가 붙은 변수는 노출돼도 퍼시픽링크 괜찮지만 '서비스 롤 키는 노출되면 키를 가진 사람이 모든 접근 권한이 생기기 때문에' 프론트엔드에서 쓰지 말고 Next.js API 라우트(백엔드)에서만 써야 한다.
마무리 개선 3가지 — 이미지 첨부를 개당 5MB·10개로 제한, 미사용 툴스 버튼을 이전 생성 이미지 참조 버튼으로 교체, img 태그를 next/image로 교체해 최적화. 커밋 전.gitignore에.env가 있는지 반드시 확인하라고 강조.
결제 — Polar 구독 결제와 웹훅 3종 API
국내는 토스페이먼츠가 편하지만 글로벌 결제라 MOR을 쓴다. 'Stripe는 한국 사업자로 사용할 수 없다'. Lemon Squeezy·Polar·Paddle·Dodo 중 Polar를 선택.
관리할 API는 셋뿐 — 체크아웃(결제 링크), 고객 포털(플랜 업그레이드·구독 취소 관리 링크), 웹훅(결제·구독·취소·업그레이드 이벤트 처리).
'결제 구현이 어려운 이유는 이러한 경우의 수 처리가 매우 까다롭기 때문'. 단 여기서는 크레딧 지급 로직이라 '사용자가 얼마를 결제했는가에 따라 그냥 크레딧을 지급하기만 하면' 되어 단순해진다.
Polar 샌드박스에서 상품 2개(프로 $20, 울트라 $45)를 만들고 프로덕트 ID와 API 키를.env에 저장. 체크아웃 구현 시 샌드박스 환경 여부를 명시하지 않아 에러가 났고, 환경 변수로 해결한다.
로컬 웹훅 테스트는 ngrok 터널링으로 — ngrok http 3000 후 발급된 주소 뒤에 퍼시픽링크 /api/webhooks/polar를 붙여 Polar 웹훅 엔드포인트로 등록한다.
웹훅 구현에는 Polar 독스의 'LLM full context'를 통째로 복사해 Claude Code에 제공한 뒤, 필요한 이벤트만 최소한으로 처리하게 한다 — 결제 완료 시 payments 기록 + 크레딧 충전, 구독 상태 변경 시 users의 plan·status 갱신, 업그레이드 시 차액 200 크레딧 충전, 다운그레이드는 다음 주기에 반영.
취소→재개, 업그레이드→다운그레이드를 실제로 눌러 가며 DB 반영을 검증하고, 반영되지 않으면 전체 문서를 다시 제공해 수정한다. 최종적으로 6개 이벤트로 정리. 환불은 고객 포털에서 불가하니 직접 문의 처리.
크레딧 로직·약관·랜딩 완성
네비바 프로필에 플랜과 크레딧 UI를 추가하고 이미지 생성 시 1씩 차감. 구독 상태가 active가 아닐 때만 예외 메시지를 노출하도록 다듬는다.
크레딧이 0이면 단순 에러 반환이 아니라 프라이싱 모달이 즉시 뜨도록 바꿔 구매를 유도한다. Supabase에서 크레딧을 0으로 만들어 직접 테스트.
개인정보처리방침·이용약관은 코드베이스를 이해시킨 뒤 AI에게 작성시킨다. '실제 프로덕션에서는 좀 더 엄격한 검증과 관리가 필요하겠지만' 일반적인 양식은 잘 나온다는 입장.
랜딩 나머지 섹션(피처·프라이싱·CTA·푸터)은 Claude Code 창 4개에 프롬프트를 나눠 병렬로 작성한다. CTA에는 React Bits의 컬러 컴포넌트, 피처에는 Freepik 무료 퍼시픽링크 이미지 5장을 public/main에 1~5로 넣어 사용.
모바일 최적화는 브라우저 개발자도구의 기기별 뷰로 확인하며 진행 — 햄버거 메뉴, 히어로 버튼 축소, 피처 섹션의 이미지-텍스트 교차 배치, 대시보드 사이드바를 스크롤 하단 배치.
배포 — Vercel, 프로덕션 전환, 도메인 연결
Vercel에 GitHub 리포지토리를 연결해 배포..env는 gitignore되어 올라가지 않으므로 환경 변수는 Vercel에 따로 등록해야 하고, 변경하면 재배포해야 적용된다.
Polar는 샌드박스에서 만든 상품·API 키·웹훅이 프로덕션으로 자동 이전되지 않는다. 상품 2개 재생성, API 키 재발급, 웹훅은 ngrok이 아닌 실제 배포 도메인으로 재등록해야 한다. 출금 승인은 파이낸스 탭에서 미리 진행할 것.
배포 후 구글 로그인이 안 되면 리디렉트 URL 누락 — 구글 클라우드 콘솔에 URI 추가, 앱 게시, 브랜딩 설정, Supabase 인증 URL 탭에서 사이트 URL 교체 및 localhost:3000 추가.
커스텀 도메인은 가비아에서 구매 후 Vercel 안내대로 DNS 레코드(A 타입 @, CNAME)를 설정한다. 'DNS 전파에는 보통 몇 분에서 길면 몇 시간까지' 걸린다. 팁 — 특정 도메인이 꼭 필요하면 개발 전에 미리 확보할 것.
Vercel Analytics·Speed Insights·Logs는 코드 한 줄로 무료 한도 내에서 쓸 퍼시픽링크 수 있으니 꼭 설정하라고 권한다.
마무리 — 서비스 4개를 말아먹고 배운 것
다루지 못한 것들을 명시한다 — SEO 최적화, GA 같은 데이터 분석, 보안, 에러 추적, 그리고 '개발보다 중요한 마케팅'.
'저는 작년에 서비스를 네 개 말아먹었습니다. 아이디어가 떠오르면 바로 만들고 런칭하고 아무도 안 쓰고 접고 이걸 네 번이나 반복했습니다.'
거기서 얻은 결론 — '소프트웨어 서비스의 본질은 결국 누군가의 불편함을 없애 주는 것'. 멋있어 보여서·유행이라서·돈이 될 것 같아서 만드는 게 아니다.
'모든 사람을 위한 서비스는 결국 아무도 위한 서비스가 아닙니다.' 아주 좁은 니치, 나를 위한 서비스, 단 한 명을 제대로 만족시키는 서비스에서 시작하라고 조언한다.
AI 코딩 에이전트로 SaaS 하나를 통째로 만드는 전 과정을, 프롬프트 문구와 에러 대응까지 생략 없이 보여주는 실습 기록이다. 개별 기술의 원리를 깊게 파기보다 '레퍼런스 컴포넌트를 가져와 붙이고 → 공식 문서를 통째로 AI에 넘기고 → 실제로 눌러 보며 DB 반영을 검증하고 → 파트마다 커밋한다'는 작업 흐름 자체가 핵심 전달물이다. 마지막 메시지는 기술이 아니라 제품론 — 좁은 문제를 실제로 겪는 한 사람을 만족시키는 데서 퍼시픽링크 시작하라는 것.