Yōten: A social tracker for your language learning journey built on the atproto.

fix: statically served assets

brookjeynes.dev 7b4371df 7b9f4bcc

verified
Changed files
+58 -18
internal
server
handlers
static
+5 -2
.dockerignore
··· 1 1 *.db 2 2 *.db-* 3 - **/*/**/*templ.go 4 3 jwks.json 5 - static/* 6 4 fly.toml 5 + 6 + */**/*templ.go 7 + 8 + static/files 9 + 7 10 run.sh
+4 -1
.gitignore
··· 1 1 *.db 2 2 *.db-* 3 3 jwks.json 4 + 4 5 */**/*templ.go 5 - static/* 6 + 7 + static/files 8 + 6 9 run.sh
+6 -6
Dockerfile
··· 19 19 RUN /go/bin/templ generate 20 20 21 21 # Create the directory structure for static assets 22 - RUN mkdir -p ./internal/web/state/static 22 + RUN mkdir -p ./static/files 23 23 24 24 # Download frontend libraries into the static folder 25 - RUN curl -sLo ./static/htmx.min.js https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js 26 - RUN curl -sLo ./static/lucide.min.js https://unpkg.com/lucide@0.525.0/dist/umd/lucide.min.js 27 - RUN curl -sLo ./static/alpinejs.min.js https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js 28 - RUN curl -sLo ./static/htmx-toaster.min.js https://unpkg.com/htmx-toaster@0.0.20/dist/htmx-toaster.min.js 25 + RUN curl -sLo ./static/files/htmx.min.js https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js 26 + RUN curl -sLo ./static/files/lucide.min.js https://unpkg.com/lucide@0.525.0/dist/umd/lucide.min.js 27 + RUN curl -sLo ./static/files/alpinejs.min.js https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js 28 + RUN curl -sLo ./static/files/htmx-toaster.min.js https://unpkg.com/htmx-toaster@0.0.20/dist/htmx-toaster.min.js 29 29 30 - RUN tailwindcss -i ./input.css -o ./static/style.css --minify 30 + RUN tailwindcss -i ./input.css -o ./static/files/style.css --minify 31 31 32 32 RUN go build -v -o /run-app ./cmd/server/main.go 33 33
+24 -8
internal/server/handlers/static.go
··· 1 1 package handlers 2 2 3 3 import ( 4 - "io/fs" 5 4 "log" 6 5 "net/http" 7 6 "strings" ··· 10 9 ) 11 10 12 11 func (h *Handler) HandleStatic() http.Handler { 12 + var finalHandler http.Handler 13 + 13 14 if h.Config.Core.Dev { 14 - return http.StripPrefix("/static/", http.FileServer(http.Dir("static"))) 15 + fileSystem := http.Dir("./static/files") 16 + fileServer := http.FileServer(fileSystem) 17 + finalHandler = NoCache(http.StripPrefix("/static/", fileServer)) 18 + } else { 19 + fs, err := static.FS() 20 + if err != nil { 21 + log.Fatal("failed to create embedded static file system:", err) 22 + } 23 + fileSystem := fs 24 + fileServer := http.FileServer(fileSystem) 25 + finalHandler = Cache(http.StripPrefix("/static/", fileServer)) 15 26 } 16 27 17 - sub, err := fs.Sub(static.StaticFiles, "static") 18 - if err != nil { 19 - log.Fatal("failed to find static folder:", err) 20 - } 21 - return Cache(http.StripPrefix("/static/", http.FileServer(http.FS(sub)))) 28 + return finalHandler 22 29 } 23 30 24 31 func Cache(h http.Handler) http.Handler { ··· 29 36 // Cache minified js for a year 30 37 w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") 31 38 } else { 32 - w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") 39 + w.Header().Set("Cache-Control", "public, max-age=3600") 33 40 } 34 41 35 42 h.ServeHTTP(w, r) 36 43 }) 37 44 } 45 + 46 + func NoCache(h http.Handler) http.Handler { 47 + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 48 + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") 49 + w.Header().Set("Pragma", "no-cache") 50 + w.Header().Set("Expires", "0") 51 + h.ServeHTTP(w, r) 52 + }) 53 + }
+18
static/static.go
··· 1 + package static 2 + 3 + import ( 4 + "embed" 5 + "io/fs" 6 + "net/http" 7 + ) 8 + 9 + //go:embed files 10 + var StaticFiles embed.FS 11 + 12 + func FS() (http.FileSystem, error) { 13 + subFS, err := fs.Sub(StaticFiles, "files") 14 + if err != nil { 15 + return nil, err 16 + } 17 + return http.FS(subFS), nil 18 + }
+1 -1
tailwindcss.sh
··· 1 1 #! /bin/bash 2 2 3 - tailwindcss -w -i ./input.css -o ./static/style.css 3 + tailwindcss -w -i ./input.css -o ./static/files/style.css