From 5bd474278cbbabcff18028a0dc3b8c0a1989f8aa Mon Sep 17 00:00:00 2001
From: Mimic890 <144267059+Mimic890@users.noreply.github.com>
Date: Wed, 4 Nov 2026 22:46:51 +0300
Subject: [PATCH 1/2] feat: add a favicon link and GET /favicon.ico
---
internal/server/pages.go | 15 +++++++++++++++
internal/server/pages_test.go | 20 ++++++++++++++++++++
internal/server/server.go | 1 +
internal/server/web/static/favicon.svg | 1 +
internal/server/web/templates/layout.html | 1 +
5 files changed, 38 insertions(+)
create mode 100644 internal/server/web/static/favicon.svg
diff --git a/internal/server/pages.go b/internal/server/pages.go
index aa63a2a..f2c9d3a 100644
--- a/internal/server/pages.go
+++ b/internal/server/pages.go
@@ -92,6 +92,7 @@ type pages struct {
tmpl map[string]map[string]*template.Template // lang → page → template
css []byte
cssV string
+ mark []byte // built-in mark, for /favicon.ico
scripts map[string]script // file name → script
fonts fs.FS
@@ -162,6 +163,9 @@ func newPages(log *slog.Logger, cfg *config.Config, d Deps) *pages {
}
p.scripts[name] = script{body: b, url: versioned("/static/"+name, b)}
}
+ if p.mark, err = webFS.ReadFile("web/static/favicon.svg"); err != nil {
+ panic(err)
+ }
p.fonts, err = fs.Sub(webFS, "web/static/fonts")
if err != nil {
panic(err)
@@ -587,6 +591,17 @@ func (p *pages) style(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write(p.css)
}
+// favicon never answers 404: it redirects to the bucket logo when there is one, else serves the built-in mark.
+func (p *pages) favicon(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Cache-Control", "public, max-age=3600") // the logo can appear or go with any sync
+ if ix := p.index(); ix != nil && ix.Logo {
+ http.Redirect(w, r, "/assets/logo.svg", http.StatusFound)
+ return
+ }
+ w.Header().Set("Content-Type", "image/svg+xml")
+ _, _ = w.Write(p.mark)
+}
+
func (p *pages) font(w http.ResponseWriter, r *http.Request) {
name := r.PathValue("file")
if ext := path.Ext(name); ext != ".woff2" && ext != ".txt" {
diff --git a/internal/server/pages_test.go b/internal/server/pages_test.go
index c91658d..93cdf21 100644
--- a/internal/server/pages_test.go
+++ b/internal/server/pages_test.go
@@ -274,3 +274,23 @@ func TestStatic(t *testing.T) {
}
}
}
+
+func TestFavicon(t *testing.T) {
+ ix := testIndex(1)
+ s := newSite(t, testConfig(), ix)
+ mustContain(t, s.get("/").Body.String(), ``)
+ for _, idx := range []*content.Index{ix, nil} { // nil: still starting, no index yet
+ s.idx.Store(idx)
+ rec := s.get("/favicon.ico")
+ if rec.Code != 200 || rec.Header().Get("Content-Type") != "image/svg+xml" || !strings.HasPrefix(rec.Body.String(), "