feature: support serving from subpath (#33)

This commit is contained in:
Henry Dollman
2025-02-04 21:11:08 -05:00
parent c853978bc8
commit 96bd65e637
5 changed files with 25 additions and 23 deletions

View File

@@ -137,9 +137,9 @@ func (h *Hub) Run() {
return err
}
// fix base paths in html if using subpath
basePath := parsedURL.Path
basePath := strings.TrimSuffix(parsedURL.Path, "/") + "/"
indexFile, _ := fs.ReadFile(site.DistDirFS, "index.html")
indexContent := strings.ReplaceAll(string(indexFile), `"./`, `"`+basePath+`/`)
indexContent := strings.ReplaceAll(string(indexFile), "./", basePath)
// set up static asset serving
staticPaths := [2]string{"/static/", "/assets/"}
serveStatic := apis.Static(site.DistDirFS, false)
@@ -150,6 +150,7 @@ func (h *Hub) Run() {
// serve static assets if path is in staticPaths
for i := range staticPaths {
if strings.Contains(e.Request.URL.Path, staticPaths[i]) {
e.Response.Header().Set("Cache-Control", "public, max-age=2592000")
return serveStatic(e)
}
}

View File

@@ -1,10 +1,11 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Beszel</title>
<script>window.BASE_PATH = "%BASE_URL%"</script>
</head>
<body>
<div id="app"></div>

View File

@@ -7,23 +7,18 @@ const routes = {
forgot_password: `/forgot-password`,
} as const
// TODO: fix /static links like favicon and check login
/**
* The base path of the application.
* This is used to prepend the base path to all routes.
*/
export const basePath = window.BASE_PATH || ""
// calculate base path based on current path and position of routes
// this is needed to support serving from subpaths like beszel.com/example-base
export const basePath = (() => {
const baseRoutes = Object.values(routes).map((route) => route.split("/").at(1))
const pathSegments = window.location.pathname.split("/").filter(Boolean)
for (let i = 0; i < pathSegments.length; i++) {
if (baseRoutes.includes(pathSegments[i])) {
// If a route is found, the base path is everything before this segment
return "/" + pathSegments.slice(0, i).join("/")
}
}
return "/" + pathSegments.join("/")
})()
export const prependBasePath = (path: string) => `${basePath}${path}`.replaceAll("//", "/")
/**
* Prepends the base path to the given path.
* @param path The path to prepend the base path to.
* @returns The path with the base path prepended.
*/
export const prependBasePath = (path: string) => (basePath + path).replaceAll("//", "/")
// prepend base path to routes
for (const route in routes) {
@@ -31,8 +26,6 @@ for (const route in routes) {
routes[route] = prependBasePath(routes[route])
}
// console.log("routes", routes)
export const $router = createRouter(routes, { links: false })
/** Navigate to url using router

View File

@@ -69,8 +69,8 @@ export default function SettingsLayout() {
useEffect(() => {
document.title = t`Settings` + " / Beszel"
// redirect to account page if no page is specified
if (page?.route === "settings") {
// @ts-ignore redirect to account page if no page is specified
if (!page?.params?.name) {
redirectPage($router, "settings", { name: "general" })
}
}, [])

View File

@@ -1,5 +1,12 @@
import { RecordModel } from "pocketbase"
// global window properties
declare global {
interface Window {
BASE_PATH: string
}
}
export interface SystemRecord extends RecordModel {
name: string
host: string