diff --git a/backend/internal/api/handlers.go b/backend/internal/api/handlers.go index 109109a..8300b2d 100644 --- a/backend/internal/api/handlers.go +++ b/backend/internal/api/handlers.go @@ -351,11 +351,12 @@ func randomHex(n int) (string, error) { // single block, disable that setting (Bots -> Managed robots.txt -> Off). func (s *Server) handleRobotsTXT(w http.ResponseWriter, r *http.Request) { origin := s.sitemapOrigin(r) - body := "# allow crawling everywhere except admin, search, and internal api\n" + + body := "# allow crawling everywhere except admin, search, and admin api\n" + "User-agent: *\n" + "Disallow: /admin\n" + "Disallow: /search\n" + - "Disallow: /api/\n" + + "Disallow: /api/admin/\n" + + "Allow: /api/\n" + "Allow: /\n\n" + "# Block AI training / scraping crawlers\n" + "User-agent: Amazonbot\nDisallow: /\n" + diff --git a/backend/internal/api/handlers_test.go b/backend/internal/api/handlers_test.go index 1d353a6..cbf0319 100644 --- a/backend/internal/api/handlers_test.go +++ b/backend/internal/api/handlers_test.go @@ -1503,8 +1503,11 @@ func TestSitemapAndRobots(t *testing.T) { if !strings.Contains(robotsBody, "Disallow: /search") { t.Errorf("robots.txt missing Disallow: /search") } - if !strings.Contains(robotsBody, "Disallow: /api/") { - t.Errorf("robots.txt missing Disallow: /api/") + if !strings.Contains(robotsBody, "Disallow: /api/admin/") { + t.Errorf("robots.txt missing Disallow: /api/admin/") + } + if !strings.Contains(robotsBody, "Allow: /api/") { + t.Errorf("robots.txt missing Allow: /api/") } } @@ -1619,7 +1622,7 @@ func TestStaticFallbackRouting(t *testing.T) { t.Errorf("GET / = %d, want 200", rec.Code) } body := rec.Body.String() - if !strings.Contains(body, ``) { + if !strings.Contains(body, ``) { t.Errorf("GET / missing news API preload, got: %s", body) } if !strings.Contains(body, ``) { diff --git a/backend/internal/api/server.go b/backend/internal/api/server.go index a2e7038..cd29498 100644 --- a/backend/internal/api/server.go +++ b/backend/internal/api/server.go @@ -333,6 +333,7 @@ func (s *Server) Handler() http.Handler { func (s *Server) writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("X-Robots-Tag", "noindex") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(v); err != nil { s.slog.Error("api: encode response", "error", err) @@ -493,7 +494,7 @@ func (s *Server) serveIndexHTML(w http.ResponseWriter, r *http.Request) { var preloadImage string if cleanPath == "" || cleanPath == "index.html" { - extraPreloads.WriteString("\t\t\n") + extraPreloads.WriteString("\t\t\n") extraPreloads.WriteString("\t\t\n") homeTitle := "NeuralWire | AI News, Neural Networks & Future Computation"