"AI가 내 웹사이트를 만들었습니다" 데모에서 아무도 보여주지 않는 것
요약
AI가 생성한 코드를 실제 웹사이트로 배포하는 과정에서 발생하는 '마법 같은 순간'의 실체를 파헤칩니다. 데모에서 생략되는 HTML 추출, 호스팅 API 호출, URL 획득이라는 단순한 기술적 단계를 설명합니다.
핵심 포인트
- AI 생성 사이트 배포는 복잡한 DevOps가 아닌 단순한 API 호출 과정임
- HTML 추출은 DOM 변형을 감지하는 MutationObserver로 가능함
- Netlify, Vercel 등은 배포를 위한 표준 HTTP API를 제공함
- 데모의 화려함 뒤에는 단순한 fetch 요청과 JSON 응답이 존재함
솔직히 말해서, 정말 힘든 한 주였습니다. Google의 검토 팀이 "불필요한 권한 요청"을 이유로 플래그를 지정한 Chrome 확장 프로그램 업데이트를 디버깅하는 데 사흘을 보냈습니다. 알고 보니 두 버전 전 리팩토링(refactor) 후에 삭제하는 것을 잊어버린 단 하나의 activeTab 스코프 때문이었습니다. 사흘 동안 단 한 줄이라도 말이죠.
게다가, 한 사용자가 자신의 FTP 배포가 "아무런 반응 없이 조용히 끝났다"며 왜 그런지 묻는 이메일을 보냈습니다. 그 사용자의 호스팅 제공업체가 데이터 센터 IP로부터의 익명 연결에 대해 속도 제한(rate-limiting)을 걸고 있었다는 사실을 깨닫는 데 부끄러울 정도로 오랜 시간이 걸렸습니다. 로컬에서 테스트할 때는 절대 겪을 수 없는 일이었습니다.
어쨌든, 계획했던 한 주는 아니었습니다. 하지만 이 일은 제가 꼭 써보고 싶었던 무언가를 상기시켜 주었습니다.
모든 "AI로 웹사이트를 만들었습니다" 데모가 생략하는 똑같은 10초
여러분은 이런 데모를 수백 번은 보셨을 겁니다. 누군가 ChatGPT나 Claude를 열고 프롬프트(prompt)를 입력하면, 아름다운 랜딩 페이지가 나타나고... 그러고 나서 영상이 그냥 끝나버립니다. 실제 URL로 전환됩니다. "보세요, 배포되었습니다!"라고 보여주죠.
그 사이에는 무슨 일이 일어나는지 아무도 보여주지 않습니다.
그 공백은 마치 화면 밖에서 아주 심각한 인프라 결정이 내려지고 있는 것처럼, 즉 매우 어려운 부분인 것처럼 취급됩니다. 프레임워크(Framework) 선택. 서버 설정(Server config). 여러분이 이미 알고 있어야만 하는 DevOps 지식 같은 것들 말이죠.
하지만 그런 건 없습니다. 그 공백은 아마도 매우 지루한 코드 80줄 정도일 뿐입니다.
그 공백에서 실제로 일어나고 있는 일
마케팅을 걷어내고 보면, "AI 생성 사이트 → 실제 URL"은 세 가지의 매력 없는 단계로 이루어집니다:
1단계: HTML 찾기.
AI의 응답은 페이지 위의 단순한 텍스트일 뿐입니다. 만약 ChatGPT, Claude, 또는 Gemini라면, 그 텍스트는 스트리밍(streaming)되는 동안 DOM 내의 <pre><code 블록에 놓여 있습니다.
const observer = new MutationObserver(() => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(scanForHtmlBlocks, 600);
...
그게 전부입니다. 파싱 라이브러리(parsing library)도 필요 없습니다. 여러분은 그저 DOM의 변형(mutating)이 멈추기를 기다렸다가, 코드 블록의 텍스트가 HTML 문서처럼 보이는지 확인하기만 하면 됩니다.
2단계: 호스팅 API에 어딘가에 배치해 달라고 요청하기.
Netlify, Vercel, 그리고 GitHub Pages는 정확히 이 용도로 사용 가능한 일반 HTTP API를 제공합니다. 배포(deploy)란 본질적으로 파일이 첨부되고 헤더에 토큰이 포함된 POST 요청입니다. 마법 같은 것은 없습니다. 어떤 REST API를 호출할 때 작성하는 요청과 동일한 형태입니다.
await fetch('https://api.netlify.com/api/v1/sites', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
...
3단계: URL 돌려받기.
API는 라이브 URL과 함께 응답합니다. 이것이 데모의 "마법" 같은 부분입니다. 단지 JSON 필드일 뿐입니다.
그것이 진정한 격차의 전부입니다. 아무도 이를 보여주지 않는 이유는 보여줄 것이 없기 때문입니다. 그것은 기능(feature)이 아니라 fetch 호출일 뿐입니다.
실제로 짜증 나는 부분
여기가 사소하지 않은 부분이며, 아무도 이야기하지 않는 부분입니다:
- 여러분이 관찰하고 있는 DOM은 다른 사람의 프론트엔드(frontend)에 속해 있으며, 예고 없이 변경됩니다. ChatGPT, Claude, Gemini 모두 끊임없이 UI 업데이트를 배포하며, 그들 중 누구도 여러분에게 안정적인 클래스 이름(class name)을 보장하지 않습니다. CSS 클래스가 아닌 구조적 방식(
<!DOCTYPE,<html>)으로 매칭하는 것이 제가 몇 주 이상 버텨온 유일한 방법입니다. - 단일 AI 응답에는 하나 이상의 코드 블록이 포함될 수 있습니다. 전체 페이지와 별도로 설명된 CSS 수정 사항이 함께 올 수 있습니다. "첫 번째
<pre>태그"를 가져오는 방식은 예상보다 더 자주 잘못된 태그를 선택합니다. - 배포하기 전에 신뢰할 수 없는 HTML을 미리 보기(preview)하는 순간, 여러분은 다른 사람의
<script>태그를 렌더링하게 됩니다.sandbox속성이 잠긴iframe이 이 전체 파이프라인에서 배포 호출 자체보다 더 실질적인 역할을 수행하고 있습니다. - 그리고 사람들이 실제로 가장 먼저 묻는 질문은 "어떤 호스트를 지원하나요"가 아니라 "내 FTP 비밀번호는 어디에 입력하나요"입니다. 이 질문 하나가 이 목록의 다른 어떤 것보다 아키텍처(architecture)를 더 크게 결정합니다.
이 중 그 어떤 것도 프레임워크(framework)를 필요로 하지 않습니다. MutationObserver, fetch 호출, 그리고 실제 운영 환경(production)에서 여러분을 괴롭힐 위 두세 가지 사항에 주의를 기울이는 것이 필요할 뿐입니다.
제가 이 이야기를 하는 이유
결국 저는 위의 모든 기능을 HTML Deployer라는 Chrome 확장 프로그램으로 구축하게 되었습니다. 이 프로그램은 ChatGPT/Claude/Gemini 상단에 위치하여 앞서 언급한 탐지(detection) + 미리보기(preview) + 배포(deploy) 단계를 수행하며, Netlify, Vercel, GitHub Pages, FTP 또는 자체 호스팅 엔드포인트(self-hosted endpoint)로 푸시할 수 있게 해줍니다. 수동으로 진행하고 싶다면 ZIP 내보내기 기능도 제공합니다.
하지만 저는 여러분이 단순히 이 도구의 존재를 아는 것보다, 그 격차(gap)가 어떻게 발생하는지 그 _방법(how)_을 알고 이 글을 읽기를 바랍니다. 만약 여러분이 유사한 것을 만들어 보았고 위에서 언급한 것과는 다른 벽에 부딪혔다면, 댓글을 통해 진심으로 그 이야기를 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기