feat: IndexNow key, key file and pings

- saving with IndexNow on generates a 32-hex key (crypto/rand);
  indexnow_new_key generates a new one, so the old key file answers 404
- GET /_sitemap/indexnow/{file} serves <key>.txt as text/plain while
  IndexNow is on; the SEO layer maps it to the site root
- after each rebuild in production the added, changed and removed
  addresses on the site host are queued as golem15.sitemap.indexnow jobs
  (at most 10 000 per request, five attempts)
- the job posts {host, key, urlList} to api.indexnow.org through a
  fetchguard client limited to that host and records the answer; 429 and
  5xx retry, 400, 403 and 422 do not
- the IndexNow tab shows the S2 status partial: key or no key, last
  notification or never, and the 403, 422 and 429 callouts
This commit is contained in:
Jakub Zych
2026-11-04 12:26:47 +01:00
parent a10ce2d9de
commit e02d0b173f
13 changed files with 780 additions and 18 deletions

View File

@@ -0,0 +1,15 @@
<div class="summer-callout" role="status">
<p class="summer-callout__text">{{ .Data.Key }}</p>
<p class="summer-callout__text">{{ .Data.Last }}</p>
</div>
{{- if .Data.Callout -}}
{{- if eq .Data.Severity "warning" -}}
<div class="summer-callout summer-callout--warning" role="alert">
<p class="summer-callout__text">{{ .Data.Callout }}</p>
</div>
{{- else -}}
<div class="summer-callout" role="status">
<p class="summer-callout__text">{{ .Data.Callout }}</p>
</div>
{{- end -}}
{{- end -}}