Claude Artifact를 정적 웹 서비스로 독립 호스팅하는 방법
초록
claude.ai 아티팩트(로그인 필요, 비공개)를 기존 도메인/인증서를 재사용해 로그인 없이 볼 수 있는 정적 URL로 노출하는 절차와, 그 과정에서 확인해야 할 안전성 조건을 정리한다.
Claude Artifact를 정적 웹 서비스로 독립 호스팅하는 방법
문제 상황
사령관이 claude.ai/code/artifact/<id> 형태의 Claude 아티팩트(이 경우 Three.js로 만든 지진 시각화 '지구본' 페이지)를 갖고 있었다. 이 URL은 claude.ai 로그인 세션이 있어야 열리는 비공개 링크라, 로그인 없이 아무나(또는 다른 기기에서) 바로 볼 수 있는 일반 웹 URL로 다시 호스팅해달라는 요청을 받았다. 이미 HTTPS와 도메인이 갖춰진 기존 인프라(ari.hyperbook.com)를 그대로 재사용해, 새 서브도메인이나 인증서 없이 처리한 절차를 기록한다.
절차
1. 아티팩트 원본 HTML 확보
Claude Code의 Artifact 읽기 기능으로 아티팩트를 열람하면, 렌더링에 쓰인 완전한 HTML이 로컬 파일로 저장된다. 이 파일을 그대로 복사해서 쓴다 — 재구현하거나 다시 그리지 않는다.
2. 독립 실행 가능 여부 확인 (중요)
Claude 아티팩트 HTML의 <head>에는 claude.ai iframe 안에서만 의미가 있는 "frame-runtime" 부트스트랩 스크립트가 항상 포함돼 있다 (댓글, 실시간 편집 동기화, capability 브리지 등을 postMessage로 부모 프레임과 주고받기 위한 코드). 이 스크립트는 자신이 예상한 부모(claude.ai origin)에 감싸여 있지 않다는 걸 감지하면 조용히 아무 동작도 하지 않고 넘어가도록(no-op) 설계되어 있다 — 즉 독립 페이지로 최상위(top-level) 로드해도 에러 없이 정상 동작한다. 다만 그 대가로 클로드 쪽 기능(실시간 댓글, 편집 반영 등)은 당연히 빠지고, 그 시점의 정적 스냅샷만 남는다.
페이지 본문이 외부 API를 실시간 폴링하거나(window.claude.* 같은) 아티팩트 전용 capability를 직접 호출하고 있지 않은지 본문 코드를 확인해야 한다. 이번 사례는 Three.js CDN과 Google Fonts만 불러오는 완전한 자체완결형 페이지였고, 데이터도 정적 스냅샷(코드에 하드코딩된 지진 데이터)이라 문제가 없었다.
3. 앱 저장소와 분리된 정적 디렉터리에 배치
mkdir -p /home/cmg/static-artifacts
cp <아티팩트 로컬 저장 경로> /home/cmg/static-artifacts/<이름>.html
일회성 콘텐츠를 서비스 앱의 git 저장소(/home/cmg/claude) 안에 넣지 않는 것이 중요하다 — 무관한 바이너리성 콘텐츠가 커밋 이력에 섞이는 것을 피하고, 앱 배포/롤백과 완전히 독립적으로 관리하기 위함이다.
4. nginx에 정확히 일치하는 경로(exact-match location) 추가
기존에 그 도메인의 TLS를 이미 처리하고 있는 server {} 블록 안에, 해당 URL 경로 하나만 정적 파일로 바로 서빙하는 location을 추가한다:
server {
listen 443 ssl;
server_name ari.hyperbook.com;
ssl_certificate /etc/letsencrypt/live/ari.hyperbook.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ari.hyperbook.com/privkey.pem;
location = /ground-truth.html {
alias /home/cmg/static-artifacts/ground-truth.html;
}
location / {
proxy_pass http://127.0.0.1:4173; # 기존 앱은 그대로 프록시
...
}
}
location = (정확히 일치)는 nginx에서 가장 높은 우선순위를 가지므로, 선언 순서와 무관하게 항상 이 규칙이 먼저 적용되고 뒤에 있는 일반 location / 프록시 규칙에 가려질 걱정이 없다.
sudo nginx -t && sudo systemctl reload nginx
Node 앱 재시작이나 재배포는 전혀 필요 없다 — nginx가 해당 경로 요청만 가로채서 파일을 직접 돌려주고, 그 외 모든 경로는 기존 앱으로 그대로 흘러간다.
왜 이 방식인가
- 새 인증서/서브도메인 불필요: 이미 발급된 도메인의 인증서를 그대로 재사용
- 앱과 완전히 분리: git 저장소, 배포 주기, 롤백에 영향 없음
- 정적 파일 직결 서빙: Node를 거치지 않고 nginx가 바로 응답하므로 더 가볍고 빠름
- 우선순위가 구조적으로 보장됨:
location =이 프록시 규칙보다 항상 먼저 매칭되어, 향후 앱 라우팅이 바뀌어도 이 경로가 실수로 앱 쪽으로 흘러갈 위험이 없음
재사용 체크리스트
- 아티팩트 HTML을 로컬로 확보 (재구현 금지, 원본 그대로)
- 본문이 아티팩트 전용 capability(
window.claude.*)나 실시간 외부 폴링에 의존하지 않는지 확인 — 정적 스냅샷/CDN 로드만 있으면 안전 - 서비스 앱 저장소 밖의 별도 디렉터리에 배치
- 기존 인증서를 쓰는 서버 블록에
location =정확 일치 규칙 추가 nginx -t로 문법 검증 후 reload (재시작 아님)
