`/s` 는 nginx `location ^~ /s/` 에 안 걸려 맨 아래 `location /` 로 떨어진다. 그래서 404 가 아니라 **빌더 SPA 셸이 200 으로** 나가고 있었다 — 실측 2026-09-08: `/s` 3.1KB `<title>Web4Ai</title>` · `/s/` 6.7KB 목록. 404 도 목록도 아닌 세 번째 페이지가 오리진에 있었던 셈이다. 목록만 슬래시가 붙어 있던 이유도 이것 하나였다. 색인 요청·사이트맵이 canonical 과 어긋나면 구글이 제출분을 "대체 페이지(적절한 표준 태그가 있음)" 로 분류한다 — 슬러그 쪽에서 이미 밟은 함정인데(prerender.ts 주석) 목록만 반대 형태로 남아 있었다. - nginx/site.conf.example: `location = /s` 로 목록 index.html 직접 서빙, `/s/` 는 301. `^~ /s/` 의 `index index.html` 은 남긴다 — `/s/<slug>/` 가 그걸로 열린다 - 같은 파일: `absolute_redirect off`. TLS 를 앞단 Apache 가 끊어 nginx 의 `$scheme` 는 늘 `http` 다 — 기본값대로 절대 URL 을 내면 https 페이지가 http 로 내려간다 - prerender.ts: `indexUrl` 의 `+ '/'` 제거. canonical·og:url·사이트맵·llms.txt 가 이 값 하나를 쓴다 - directory.ts · AGENTS.md · DEVLOG.md: 슬래시 규칙과 근거 갱신 검증: `nginx -t` 통과 · `tsc --noEmit` 통과 · 컨테이너 실측 `/s`→200 목록 · `/s/`→301 `Location: /s`(상대) · `/s/<slug>`→200 · `/s/<slug>/`→200 · `/nope`→200 앱 셸(변화 없음) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129XqVdjDk9JmMNFAepBJvs |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| .env.example | ||
| components.json | ||
| eslint.config.js | ||
| orval.config.ts | ||
| package.json | ||
| react-router.config.ts | ||
| tsconfig.json | ||
| vite.config.ts | ||