Indexare: /index.html duplicat, /admin fără noindex și grupul din robots.txt
Patru scăpări mici pe partea de indexare, niciuna vizibilă azi pentru un vizitator. https://hyperice.md/index.html răspunde 200 și servește shell-ul brut, adică o a doua adresă pentru pagina de start, fără titlu în română, fără canonical și fără date structurate. /admin se servește fără antet X-Robots-Tag, deci depinde exclusiv de robots.txt ca să nu apară în rezultate. Iar robots.txt-ul servit nu mai e cel din repo: Cloudflare inserează un bloc propriu înaintea lui, ceea ce lasă două grupuri User-agent: * și blochează o parte din roboții de AI fără ca noi să fi cerut asta.
Ce am găsit
/index.html servește shell-ul brut, indexabil
curl -s -o /tmp/i.html -w "%{http_code}" https://hyperice.md/index.html
→ 200
În corp: <html lang="en">, <title>Hyperice | Recovery & Wellness Technology</title> — titlul generic din shell, în timp ce pagina de start reală are <title>Tehnologie de recuperare și wellness | Hyperice Moldova</title>.
-
grep -o 'rel="canonical"[^>]*' /tmp/i.html→ gol, niciun canonical -
grep -o 'name="robots"[^>]*' /tmp/i.html→ gol, niciun noindex - în robots.txt-ul servit nu există nicio linie
Disallow: /index.html
Cauza: frontend/nginx.conf:157-159, location / { try_files $uri @spa; }. /index.html e fișier real pe disc, deci try_files $uri îl servește direct și nu mai trece prin renderer, care stă la location @spa. Varianta cu limbă nu are problema: curl -o /dev/null -w "%{http_code}" https://hyperice.md/en/index.html → 404.
Riscul de descoperire e mic azi: grep -c "index.html" peste sitemap-ul descărcat → 0, iar pagina de start nu face link acolo. Dar dacă un crawler ajunge la adresă dintr-un link vechi sau dintr-o unealtă de scanare, indexează versiunea goală în locul celei bune, ori le împarte pe amândouă.
/admin se servește fără X-Robots-Tag
curl -s -D- -o /dev/null https://hyperice.md/admin | grep -i x-robots
→ niciun rezultat. Pagina răspunde 200, iar în corp nu există <meta name="robots"> și nici canonical.
Cauza: frontend/nginx.conf:163-165, location /admin { try_files $uri /index.html; } — se servește shell-ul comun, care nu poate purta un noindex propriu fără să-l pună pe toate paginile.
Singura protecție azi e Disallow: /admin din robots.txt. „Disallow" înseamnă „nu intra", nu „nu afișa": dacă cineva pune undeva un link către /admin, adresa poate apărea în rezultate fără să fi fost citită.
robots.txt servit are două grupuri User-agent: *
frontend/nginx.conf:225-227 generează exact patru linii:
return 200 "User-agent: *\n$robots_policy: /\nDisallow: /admin\nDisallow: /api/\n\nSitemap: https://$host/sitemap.xml\n";
Dar curl -s https://hyperice.md/robots.txt | wc -l → 67. Cloudflare inserează un bloc propriu ÎNAINTEA celui al nostru, delimitat de # BEGIN Cloudflare Managed content și # END Cloudflare Managed Content. Fișierul servit are deci două grupuri User-agent: *:
- primul, al Cloudflare:
User-agent: *+Content-Signal: search=yes,ai-train=no,use=reference+Allow: / - al doilea, al nostru:
User-agent: *+Allow: /+Disallow: /admin+Disallow: /api/+Sitemap:
Grupurile cu același nume de user-agent se combină — e comportamentul cerut de RFC 9309 și implementat de Google și de Bing — deci pentru crawlerele serioase regulile noastre rămân în vigoare. Riscul e limitat la crawlerele simple, care iau doar primul grup care se potrivește și nu văd nicio interdicție.
Observat separat: pe https://api.hyperice.md/robots.txt se servește DOAR blocul Cloudflare, fără Disallow și fără Sitemap, pentru că acolo răspunde Express, nu nginx-ul din frontend/. Nu e o gaură de indexare: paginile randate de acolo poartă canonical spre hyperice.md — curl -H "X-Original-URI: /" https://api.hyperice.md/api/render → rel="canonical" href="https://hyperice.md/".
ClaudeBot, CCBot și ceilalți roboți de AI sunt blocați din setările implicite Cloudflare
În blocul # BEGIN Cloudflare Managed content există câte un Disallow: / pentru: Amazonbot, Applebot-Extended, Bytespider, CCBot, ClaudeBot, CloudflareBrowserRenderingCrawler, Google-Extended, GPTBot, meta-externalagent — plus Content-Signal: search=yes,ai-train=no,use=reference.
Nimic din asta nu vine de la noi: fișierul generat la frontend/nginx.conf:227 are patru linii și nu numește niciun bot.
Ce NU e blocat, verificat prin absență din listă: Googlebot, Bingbot, Applebot în varianta simplă (cea pentru Siri și Spotlight), OAI-SearchBot și ChatGPT-User (căutarea din ChatGPT), PerplexityBot.
Indexarea în Google nu e atinsă, iar Google-Extended controlează doar antrenarea Gemini, nu poziția în Search. Ce se pierde efectiv e ClaudeBot și CCBot (Common Crawl): asistenții de tip Claude nu pot citi magazinul ca să-l recomande cuiva care întreabă de unde cumpără un Hypervolt în Moldova, iar Common Crawl e sursa din care se hrănesc multe unelte terțe. Pentru un magazin mic, „mă recomandă asistenții AI" e canal de vânzare. Nu e un defect și nu încalcă nicio cerință din checklistul de lansare — e o alegere care azi e moștenită din setările implicite în loc să fie asumată, iar decizia îi revine lui Vitalie.
De făcut
-
În frontend/nginx.conf, înaintea bloculuilocation /(linia 157), adaugălocation = /index.html { return 301 /; }.absolute_redirect off;e deja setat (linia 118), deci redirectul iese relativ și nu costă un hop suplimentar prin regula http→https. Fișierul rămâne servit intern detry_files /index.htmldin@spa_shell(linia 207) — unlocation =nu afectează redirecturile interne. -
În frontend/nginx.conf, înlocation /admin(linia 163), adaugăadd_header X-Robots-Tag "noindex, nofollow" always;. -
În Cloudflare, zona hyperice.md, secțiunea AI Crawl Control / Managed robots.txt: fie oprește gestionarea automată a robots.txt și rămâne doar fișierul nostru, fie mută Disallow: /adminșiDisallow: /api/în conținutul gestionat, ca să existe un singur grupUser-agent: *. -
Vitalie decide dacă blocarea roboților de AI rămâne. Dacă vrem vizibilitate în asistenți, se scot din blocare cel puțin ClaudeBot și CCBot, opțional și GPTBot, sau se oprește complet blocul gestionat. Dacă preferăm ca textele și pozele să nu fie folosite la antrenarea modelelor, se lasă exact cum e, dar ca alegere asumată.
Criteriu de acceptare
-
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}" https://hyperice.md/index.html→301 -> https://hyperice.md/. Pagina de start rămâne 200, cu titlul în română și canonical către sine. Plasa de siguranță funcționează în continuare: cu backend-ul oprit, site-ul se încarcă tot din shell. -
curl -s -D- -o /dev/null https://hyperice.md/admin | grep -i x-robots→x-robots-tag: noindex, nofollow. Panoul se încarcă și funcționează la fel, iar pagina de start NU capătă antetul:curl -s -D- -o /dev/null https://hyperice.md/ | grep -i x-robotsrămâne gol. -
curl -s https://hyperice.md/robots.txt | grep -c '^User-agent: \*'→1, iar în acel unic grup aparDisallow: /adminșiDisallow: /api/. LiniaSitemap: https://hyperice.md/sitemap.xmlrămâne prezentă. - După decizia despre roboții de AI,
curl -s https://hyperice.md/robots.txtreflectă alegerea — ClaudeBot și CCBot absente din listă dacă le deschidem. Googlebot și Bingbot rămân nelistate în orice variantă.
Depinde de
Ultimele două puncte nu se pot repara din repo: blocul e adăugat de Cloudflare după ce nginx a răspuns, iar reglajul se face în panoul Cloudflare de cine deține contul zonei hyperice.md. Alegerea despre roboții de AI e decizie de produs și îi aparține lui Vitalie.