Învelișul aplicației se cere de la o adresă pe care nicio pagină nu o are
Rendererul construia fiecare pagină pornind de la învelișul cerut de la nginx-ul frontendului, iar adresa cerută era /index.html — exact adresa pe care o poate tasta un vizitator. Asta le făcea indistincte: regula scrisă pentru vizitator i s-a răspuns și rendererului. Redirectul livrat prin !45 (merged) a fost urmat de renderer, care a primit pagina pe care tocmai o construia și a injectat în ea; producția a măsurat 799.522 de octeți de HTML per vizitator și 146 de etichete canonical într-o oră, iar schimbarea a fost anulată prin !50 (merged).
Ce se schimbă
-
getShellcere/app-shell.html. nginx răspunde acolo cu același fișier, cuX-Robots-Tag: noindex, nofollow, iar nimic nu redirectează spre acea adresă. -
/index.htmlîntoarce 301 către/, cu query string-ul păstrat. -
Cele două reguli
error_page 404trec pe adresa rendererului.error_page <cod> <uri>e un redirect intern: reia potrivirea de locații, deci un corp de 404 care numea/index.htmlar fi primit redirectul de mai sus și orice adresă inexistentă ar fi sărit pe prima pagină. - Plasă de siguranță independentă de nginx:
getShellrefuză un document care poartă unrel="canonical"sau bloculid="seo-content"— ambele scrise doar de renderer — și refuză înainte de scrierea în cache, deci o greșeală costă o cerere, nu un minut de cereri. - Redirectele nu se mai urmăresc la cererea artefactelor de build (
redirect: 'manual'). Urmărirea lor e cauza de transport a incidentului.
Verificare
Configurația a fost exercitată într-un container nginx 1.27 cu fișierul din acest MR și cu build-ul real, plus backendul pornit alături:
| Adresă | Rezultat |
|---|---|
/index.html |
301 -> /
|
/index.html?utm_source=fb&a=1 |
301 -> /?utm_source=fb&a=1
|
/app-shell.html |
200, învelișul brut, zero canonical, X-Robots-Tag: noindex, nofollow
|
/admin |
200, X-Robots-Tag: noindex, nofollow
|
/pagina-care-nu-exista |
404, nu redirect |
/en/index.html |
404 |
/ |
200, 10.400 de octeți, un canonical, un <noscript>, titlul în română |
Contra-proba care lipsea data trecută: pagina de start măsurată după schimbare are un singur canonical și 10 KB, nu 146 și 800 KB. Cu rendererul oprit, / cade pe învelișul static (4.431 de octeți) și adresa inexistentă rămâne 404.
Backend: 609 teste în 40 de fișiere, toate trec. Frontend: 441 de teste în 33 de fișiere, tsc --noEmit -p tsconfig.app.json curat, oxlint cu singurul avertisment preexistent din src/App.tsx.
Ordinea la deploy
Ambele imagini poartă eticheta commit-ului, deci ambele containere se recreează la fiecare deploy, iar frontendul pornește doar după ce backendul e sănătos. Direcția care ar imbrica paginile — backend vechi cu frontend nou — nu poate apărea. Direcția inversă degradează la învelișul static. De aceea getShell nu primește o cale de rezervă spre /index.html: nu ajută direcția care se strică și ar reintroduce chiar amplificatorul din incident.
Efect secundar de reținut
Corpurile de 404 trec acum prin locația învelișului, deci orice 404 poartă X-Robots-Tag: noindex, nofollow. Corect pentru un 404, dar e o schimbare, nu un lucru neutru.
Rămân nebifate ultimele două puncte ale issue-ului: blocul robots.txt inserat de Cloudflare și decizia despre roboții de AI sunt setări de zonă și o decizie de produs, nu se fac din repo.
See #26 (closed)