Stu Mason
Stu Mason

Activity

StuMason/cleanconnect
TidyLinker.com
TypeScript
Pull Request Merged

PR #135 merged: feat: security headers + public sitemap

Summary

Closes the remaining technical-SEO gaps from the Xanthos audit that fall on the dev side. Stacks on top of the SSR work (#133, #134) — without SSR these would have been pointless because crawlers couldn't read anything anyway.

Security headers middleware (SetSecurityHeaders) Wired into the web group. Sets HSTS (HTTPS-only), X-Frame-Options: SAMEORIGIN, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, and a Permissions-Policy that disables camera/microphone, scopes geolocation to first-party, and opts out of FLoC. Should bump Securityheaders.com grade from D toward A.

CSP intentionally deferred. Too much surface to land safely without a Report-Only soak first (Stripe + Reverb + Sanity + Sentry + Umami + R2 + Inertia inline scripts). Worth a follow-up PR with a tight policy in Content-Security-Policy-Report-Only for a couple of weeks before enforcing.

Public sitemap (/sitemap.xml) Single-file XML. Includes:

  • Homepage, /cleaners, /blog, /faq, /contact
  • All searchable cleaner profiles (uses the existing Searchable scope: visibility=true + onboarding_completed_at + verified or company)
  • All Sanity-managed pages
  • All blog posts Cached for 1 hour. robots.txt now points at it.

This bumps the indexable URL count from "homepage + login" (per the audit) to homepage + 4 marketing pages + N cleaner profiles + Sanity content — a real number for Google to chew on.

Not in this PR: per-service / per-location landing pages. That's content + routing + copy work, weeks not days, and belongs in a separate scoping conversation.

Test plan

  • php artisan test tests/Feature/SitemapTest.php tests/Feature/Middleware/SetSecurityHeadersTest.php — 10 passed
  • Smoke nearby tests (Middleware, PageController, PublicJobController) — 24 passed
  • vendor/bin/pint --dirty — clean
  • After deploy: curl -I https://dev.tidylinker.com/ shows the new headers
  • After deploy: curl https://dev.tidylinker.com/sitemap.xml returns valid XML containing the homepage and at least one cleaner profile URL
  • After deploy: curl https://dev.tidylinker.com/robots.txt ends with Sitemap: https://tidylinker.com/sitemap.xml
+371
additions
-0
deletions
7
files changed