동의 게이트: 사용자가 동의할 때까지 선택적 기능은 실행되지 않습니다
비디오의 규칙을 한 줄로 요약하면: 사용자가 쿠키 배너에서 수락을 클릭할 때까지 추적 픽셀, 분석 또는 타사 스크립트가 로드되지 않습니다. 픽셀이 이미 실행된 후에 나타나는 배너는 아무것도 해결하지 못합니다. 이 스킬은 대기 부분을 구축합니다.
법적 조언이 아닙니다. 코드, 카피 또는 보고서에 "완전히 준수"라고 절대 작성하지 마십시오. 앱이 현재 수행하는 작업과 테스트된 내용을 명시하십시오.
작업 전 확인 사항
- 감사(audit)를 수행하십시오. 이 앱에 대한
consent-audit보고서가 없다면 먼저 실행하십시오. 인벤토리가 필요합니다: 어떤 공급업체, 어디에서 시작되는지, 무엇을 전송하는지. - 소유자에게 추적기당 한 가지 질문을 하십시오: 유지, 게이트, 또는 제거? 추적기가 의사 결정이나 광고에 사용되지 않는다면, 게이트하는 것보다 제거하는 것이 더 낫습니다. 필수 저장소만 있는 사이트에는 배너가 전혀 필요하지 않습니다. 추가하지 마십시오.
- 게시 시 무엇이 릴리스될지 알고 있어야 합니다. 호스팅 빌더(Lovable 등)는 모든 게시되지 않은 변경 사항을 함께 출시합니다. 이를 목록화하고 게시 전에 승인을 받으십시오.
- 퍼스트파티 데이터를 보호하십시오. 게이트된 추적기는 로그인, 결제 또는 앱 자체 데이터베이스 쓰기(학생 작업, 진행 상황, 양식)에 접근해서는 안 됩니다. 보고서에 명시하십시오.
"게이트됨"의 의미 (수정이 충족해야 하는 체크리스트)
로딩
- 하나의 중앙 로더(
src/lib/consent.ts,references/consent.ts참조).index.html, 루트 레이아웃 또는main.tsx에 픽셀, GTM, gtag, PostHog 또는 리플레이<script>가 없습니다. - 선택적 스크립트는 페치되지 않습니다. 단순히 초기화되지 않는 것이 아닙니다. 동적
import()또는 스크립트 주입은 옵트인 후에만 발생합니다. - 대기 중인 이벤트가 재생되지 않습니다: 동의 전 페이지뷰는 삭제되며 늦게 전송되지 않습니다.
- 서버 측 전달(Meta Conversions API,
/api/track, 에지 함수)은 요청과 함께 전송된 동일한 저장된 선택을 확인합니다. - 호스트 주입 분석은 소스에서 꺼져 있거나(Lovable → 설정 → 방문자 분석 끄기, Vercel/Netlify/Cloudflare 분석 끄기), 주입 전에 게이트되어야 합니다. 스크립트가 로드된 후 제거하는 것은 너무 늦습니다. 첫 번째 요청이 이미 나갔기 때문입니다.
- Google 동의 모드(GA/Ads가 남아 있는 경우):
gtag('consent','default',{ad_storage:'denied',analytics_storage:'denied',ad_user_data:'denied',ad_personalization:'denied'})그리고 gtag 스크립트 자체도 이 스킬의 기본 설정에서 옵트인을 기다려야 합니다. "고급"이 아닌 "기본" 동의 모드를 사용하십시오. 고급 모드는 동의 전에 쿠키 없는 핑을 보내기 때문입니다.
배너
- 선택적 수락과 선택적 거절이 동등하게 눈에 띕니다: 같은 크기, 같은 스타일, 같은 클릭 수. 추가로 설정 옵션이 있습니다.
- 카테고리 토글(분석, 광고 등)은 체크 해제된 상태로 시작합니다.
- 배너 닫기(X / Escape)는 거절을 의미합니다.
- 선택은 버전과 만료(6~12개월)와 함께 저장됩니다. 공급업체 목록이 변경되면 버전이 올라가고 다시 묻습니다.
- 바닥글에 지속적인 "개인정보 선택" 링크가 있어 설정을 다시 열 수 있습니다.
- 철회 시 향후 호출이 중지되고 앱 소유의 선택적 쿠키 및 저장소(
_ga*,_fbp,_gcl_au,_ttp,ph_*,ajs_*,_hj*,_clck)가 인증에 영향을 주지 않고 삭제됩니다. - Global Privacy Control(
navigator.globalPrivacyControl === true)은 광고/판매/공유에 대해 거절로 처리되며, 배너는 이를 존중했음을 표시합니다.
동의 후에도 전송되는 내용
- 픽셀 또는 분석 페이로드에 이메일, 전화번호, 이름 또는 생년월일 데이터가 없습니다(Meta 고급 매칭 없음,
identify(email)없음). 정말 필요한 경우에만 불투명 ID를 사용하십시오. - URL은
?query및#fragment없이 전송됩니다(선물 코드, 재설정 토큰, 검색어). 공급업체가 이를 제거할 수 없으면 해당 공급업체를 제거하십시오. - 퀴즈 답변, 채팅 내용, 건강/금융/생년월일 데이터 또는 양식 필드에서 아무것도 전송되지 않습니다.
- 비디오 페이지: 강의 또는 코스 비디오를 재생하는 페이지에 광고 픽셀이 없습니다(연방 비디오 프라이버시 보호법 위험). 법률 고문이 달리 명시하지 않는 한.
고지
- 공개 경로에 있는 개인정보/쿠키 고지. 바닥글과 가입/로그인 페이지에서 링크됩니다. 실제 공급업체와 카테고리를 나열합니다. 실제 운영자 이름과 연락처 이메일만 사용하십시오. 주소, DPO 또는 법적 주장을 절대 만들어내지 마십시오.
구현 방법
- 로컬 코드 / Claude Code:
references/consent.ts를 앱에 복사하고, 각 선택적 공급업체를loader로 등록하고, 하드 코딩된 태그를 삭제하고, 앱 자체 컴포넌트로 배너를 구축하고, 바닥글 링크를 연결하십시오. diff를 작게 유지하고 앱 스타일을 따르십시오. - Lovable / Bolt / v0 / Replit (에이전트 빌드):
~/.claude/skills/consent-audit/references/prompts.md에서 수정 프롬프트(또는 제거 프롬프트)를 붙여넣으십시오. 그런 다음 직접 확인하십시오. 에이전트의 요약을 신뢰하지 마십시오.
완료되었다고 말하기 전에 증명하십시오 (필수)
이 테스트를 미리보기에서 실행한 다음, 게시 후 라이브 URL에서 다시 실행하십시오. Claude의 내장 브라우저에서 저장소가 지워진 새 탭을 사용한 다음 read_network_requests 및 javascript_tool(document.cookie, localStorage)을 사용하십시오:
| 테스트 | 통과 조건 |
|---|---|
| 신규 방문, 클릭 없음 | 광고, 분석 또는 리플레이 도메인에 대한 요청 0개; 선택적 쿠키 또는 저장소 없음 |
| 거절 후 2번의 페이지 이동 | 여전히 0; 배너 사라짐; 선택 저장됨 |
| 분석만 수락 | 분석 로드됨; 광고 픽셀 로드되지 않음 |
| 새로고침 | 선택 기억됨; 배너 없음 |
| 바닥글 링크를 통한 철회 | 향후 호출 중지; 선택적 쿠키 지워짐; 여전히 로그인 상태 |
GPC 켜짐(navigator.globalPrivacyControl 강제 true) | 클릭 없이 광고 거부됨 |
| 클라이언트 측 탐색(SPA) | 경로 변경 시 추적기 침입 없음 |
| 테스트 계정으로 로그인 | 추적기 요청에 이메일 또는 사용자 ID 없음 |
| 빌드 + 타입 검사 | 통과 |
보고: 변경된 파일, 증거와 함께 각 테스트 결과(본 도메인 또는 "없음"), 실행되지 않은 테스트와 이유, 함께 출시된 게시되지 않은 변경 사항, 그리고 "법적 조언이 아닙니다. 광고를 운영하거나 캘리포니아/EU 방문자를 대상으로 하는 경우 법률 고문의 검토를 받으십시오."