aboutsummaryrefslogtreecommitdiffstats
path: root/web/frontend.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-12 21:44:23 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-12 21:44:23 -0800
commit9db2500fb340ef304c0f15f4379bc33589df9a63 (patch)
tree55495be30810f55aa1115ad2b392f97ce8650efb /web/frontend.go
parentde96851d8eb0a0b45d7bf0cee67339fea54349f0 (diff)
downloadneko-9db2500fb340ef304c0f15f4379bc33589df9a63.tar.gz
neko-9db2500fb340ef304c0f15f4379bc33589df9a63.tar.bz2
neko-9db2500fb340ef304c0f15f4379bc33589df9a63.zip
Scaffold new frontend and close NK-t0nmbj
Diffstat (limited to 'web/frontend.go')
-rw-r--r--web/frontend.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/web/frontend.go b/web/frontend.go
new file mode 100644
index 0000000..c3ee038
--- /dev/null
+++ b/web/frontend.go
@@ -0,0 +1,55 @@
+package web
+
+import (
+ "net/http"
+ "path/filepath"
+ "strings"
+
+ rice "github.com/GeertJohan/go.rice"
+)
+
+func ServeFrontend(w http.ResponseWriter, r *http.Request) {
+ // The box is at "web", so we look for "../frontend/dist" relative to it
+ // rice will find this box by the string literal
+ box := rice.MustFindBox("../frontend/dist")
+
+ // Get the file path from the URL
+ path := r.URL.Path
+ // rice box paths shouldn't start with /
+ path = strings.TrimPrefix(path, "/")
+
+ // If path is empty, it's index.html
+ if path == "" {
+ path = "index.html"
+ }
+
+ // Try to open the file
+ f, err := box.Open(path)
+ if err != nil {
+ // If file not found, serve index.html for client-side routing
+ // But only if it's not looking for a specific static asset (like .js, .css)
+ // Simple heuristic: if it has an extension, it's probably an asset
+ if !strings.Contains(filepath.Base(path), ".") {
+ f, err = box.Open("index.html")
+ if err != nil {
+ http.Error(w, "frontend not found", http.StatusNotFound)
+ return
+ }
+ // Important: update path so ServeContent sets correct Content-Type
+ path = "index.html"
+ } else {
+ // It might be a real 404 for an asset
+ http.Error(w, "not found", http.StatusNotFound)
+ return
+ }
+ }
+ defer f.Close()
+
+ d, err := f.Stat()
+ if err != nil {
+ http.Error(w, "internal error", http.StatusInternalServerError)
+ return
+ }
+
+ http.ServeContent(w, r, path, d.ModTime(), f)
+}