디자인 수정하기
템플릿에서 수정 가능한 영역과 유지해야 할 영역
디자인은 확장 지점에서만 바꿉니다. 요청 끝에 "확장 지점에서만 바꾸고 verify_storefront로 검사해줘"를 덧붙이십시오.
수정 가능한 영역
| 영역 | 파일 |
|---|---|
| 브랜드 색·서체·본문 폭 | src/theme.css의 @theme |
| 헤더·전역 내비 | src/components/site-header.tsx |
| 상품 카드 | src/components/product-card.tsx |
| 화면 추가 | src/routes/에 파일 추가(파일 이름이 경로) |
유지해야 할 영역
| 파일 | 역할 |
|---|---|
src/lib/payments.ts · src/lib/payment-options.ts · src/routes/checkout.return.tsx | 결제창 열기, 결제 복귀, 다른 결제수단 재시도 |
src/lib/api.server.ts | 상점 코드 헤더, 구매자 토큰 전달, 방문 식별 쿠키 |
src/lib/session.server.ts · src/start.ts | 구매자 세션 쿠키와 토큰 갱신 |
src/lib/cookies.server.ts | 서버 쿠키의 이름과 속성. 배포 빌드는 이름에 __Host- 접두사를 붙이고 Domain을 주지 않습니다 |
src/lib/analytics.ts | 방문 분석 시작 |
각 라우트의 loader | 서버 함수(createServerFn)로 첫 화면 데이터 받기. TanStack Query를 쓰는 화면은 ensureQueryData로 미리 받기 |
지켜야 할 규칙
verify_storefront가 검사하는 23개 규칙입니다. 어기면 결제나 화면이 오류 없이 실패할 수 있습니다.
| 규칙 id | 규칙 | 어기면 |
|---|---|---|
server-only-env | process.env는 *.server.ts에만 둡니다 | 브라우저에서 그 화면 전체가 오류 |
tenant-header | 상점 코드는 X-Store-Code 헤더로 보냅니다 | 다른 상점 데이터가 보이거나 404 |
no-module-token | 토큰을 모듈 전역 변수에 담지 않습니다 | 다른 구매자의 요청에 토큰이 섞임 |
loader-first | 데이터는 라우트 loader에서 서버 함수로 받습니다. TanStack Query는 loader가 ensureQueryData로 미리 받습니다 | 첫 화면이 비고 검색 노출이 약해짐 |
payment-browser-launch | 결제창은 브라우저에서 @sayren/storefront-sdk/payments의 start·open으로 엽니다 | 결제창이 열리지 않음 |
payment-popup-prepare | 결제 시작이 서버 함수를 거치면 클릭 시점에 payments.prepareWindow()로 창을 엽니다 | 브라우저가 팝업을 막음 |
payment-return-route | 결제 복귀 화면에서 payments.result()로 결과를 읽습니다 | 리다이렉트 결제의 결과를 못 봄 |
payment-processing-status | PROCESSING이면 결제 상태를 다시 조회합니다 | 재결제로 이중 결제 |
payment-amounts-final | 결제 시작 응답의 amounts를 확정 금액으로 반영합니다 | 화면 금액과 결제창 금액이 다름 |
payment-retry | 결제가 실패·취소되면 payments.retry()로 다른 결제 옵션을 다시 시도하게 합니다 | 구매자가 주문서를 처음부터 다시 씀 |
checkout-origin | 복귀 주소는 요청 origin에서 만듭니다 | 한 환경에서만 결제가 됨 |
delivery-quote-preview | 우편번호를 받으면 checkout.quoteDelivery로 배송비를 다시 보여 줍니다 | 추가 배송비가 결제창에서 처음 보임 |
buyer-token-cookie | 구매자 토큰 쌍은 서버에서 HttpOnly 쿠키에 담습니다 | 스크립트로 토큰 유출 |
buyer-session-refresh | 액세스 토큰은 만료 전에 갱신합니다 | 장바구니·주문서에서 갑자기 로그아웃 |
buyer-reconsent | reconsentRequired가 true면 재동의를 받습니다 | 개정 약관 동의 이력이 없음 |
buyer-signup | 이메일·비밀번호 로그인을 받으면 가입 화면도 둡니다(auth.signUp) | 새 구매자가 계정을 만들 수 없음 |
buyer-signout | 로그아웃은 서버에서 auth.signOut()으로 리프레시 토큰을 폐기합니다 | 새 나간 토큰이 계속 유효함 |
analytics-start | 방문 분석은 브라우저에서 한 번 시작합니다 | 애널리틱스가 비어 있음 |
analytics-ids | 서버 API 클라이언트에 방문 식별 쿠키를 싣습니다 | 담기·결제·구매가 퍼널에서 빠짐 |
custom-input-private | 직접 입력값은 서버 함수 본문으로만 보내고 URL·브라우저 저장소·상점 플랫폼 로그에 두지 않습니다 | 구매자가 적은 개인정보가 방문 기록·로그로 샘 |
checkout-availability | 주문을 받지 않는 상점(checkoutAvailable이 false)이면 주문 버튼을 그리지 않습니다(경고) | 주문서까지 가서야 결제가 안 됨 |
server-only-import | *.server.ts(api.server 등)에서 가져온 것은 서버 함수(createServerFn().handler) 안에서만 씁니다 | 버전 빌드가 import 보호로 실패 |
local-import-exists | 상대 경로로 import한 파일은 작업 트리에 둡니다 | 타입 검사와 버전 빌드가 실패 |
현금영수증 입력(결제 흐름)과 쿠키 동의 배너(방문 분석)는 선택입니다.
수정한 뒤 확인
- 에이전트에게
verify_storefront검사를 요청합니다. - 위반이 나오면 결과의
fix대로 고치고 다시 검사하게 합니다. - 테스트 결제로 주문 완료 화면까지 가 봅니다.