diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ccddb..792bae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Removed several unnecessarily verbose or spammy log messages. - Updated the minimum Docker API used to support the latest Docker versions (via [#370](https://github.com/tale/headplane/pull/370)). - Enhanced the node tag dialog to show a dropdown of assignable tags (via [#362](https://github.com/tale/headplane/pull/362)). +- Fixed an issue where the website favicon would not load correctly (closes [#323](https://github.com/tale/headplane/issues/323)). --- # 0.6.1 (October 12, 2025) diff --git a/app/server/index.ts b/app/server/index.ts index ce239c1..20142cc 100644 --- a/app/server/index.ts +++ b/app/server/index.ts @@ -1,5 +1,5 @@ import { join } from 'node:path'; -import { versions } from 'node:process'; +import { exit, versions } from 'node:process'; import { createHonoServer } from 'react-router-hono-server/node'; import log from '~/utils/log'; import { loadIntegration } from './config/integration'; @@ -19,7 +19,17 @@ declare global { // This module contains a side-effect because everything running here // exists for the lifetime of the process, making it appropriate. log.info('server', 'Running Node.js %s', versions.node); -const config = await loadConfig(); +let config: HeadplaneConfig; + +try { + config = await loadConfig(); +} catch (error) { + if (error instanceof ConfigError) { + log.error('server', 'Unable to load configuration: %s', error.message); + } + + exit(1); +} const db = await createDbClient(join(config.server.data_path, 'hp_persist.db')); const agents = await createHeadplaneAgent( @@ -39,6 +49,8 @@ const hsApi = await createHeadscaleInterface( export type LoadContext = typeof appLoadContext; import 'react-router'; +import { HeadplaneConfig } from './config/config-schema'; +import { ConfigError } from './config/error'; import { createOidcConnector } from './web/oidc-connector'; declare module 'react-router' { @@ -92,6 +104,11 @@ export default createHonoServer({ }); }, serveStaticOptions: { + publicAssets: { + // This is part of our monkey-patch for react-router-hono-server + // To see the first part, go to the patches/ directory. + rewriteRequestPath: (path) => path.replace(`${__PREFIX__}`, ''), + }, clientAssets: { // This is part of our monkey-patch for react-router-hono-server // To see the first part, go to the patches/ directory. diff --git a/patches/react-router-hono-server.patch b/patches/react-router-hono-server.patch index 328e9e4..7559432 100644 --- a/patches/react-router-hono-server.patch +++ b/patches/react-router-hono-server.patch @@ -1,8 +1,8 @@ diff --git a/dist/adapters/node.js b/dist/adapters/node.js -index ec81622898d583ddd8c2f4d9eaf5c0ed23776475..047ef1d45ad82e4b476a882b4ab5c8962faa0df1 100644 +index e081ab36a04ea100cf5da3fb5eb54c5174186f4d..35433810d05a829f2c824d63714e71bf5ed069a0 100644 --- a/dist/adapters/node.js +++ b/dist/adapters/node.js -@@ -49,7 +49,7 @@ async function createHonoServer(options) { +@@ -49,13 +49,13 @@ async function createHonoServer(options) { } await mergedOptions.beforeAll?.(app); app.use( @@ -11,3 +11,10 @@ index ec81622898d583ddd8c2f4d9eaf5c0ed23776475..047ef1d45ad82e4b476a882b4ab5c896 cache(60 * 60 * 24 * 365), // 1 year serveStatic({ root: clientBuildPath, ...mergedOptions.serveStaticOptions?.clientAssets }) + ); + app.use( +- "*", ++ `${import.meta.env.REACT_ROUTER_HONO_SERVER_BASENAME}*`, + cache(60 * 60), + // 1 hour + serveStatic({ root: PRODUCTION ? clientBuildPath : "./public", ...mergedOptions.serveStaticOptions?.publicAssets }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b9020d..066ecf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: patchedDependencies: react-router-hono-server: - hash: b68723a36649e2c3bd9e9edcfff3a8bc0fdb48e1cf6d64eba37c04f7bfbb1417 + hash: e94667f181837f2501959f5cf01fa0a9e6ea2883dcb1137be8b1c6178979bc77 path: patches/react-router-hono-server.patch importers: @@ -166,7 +166,7 @@ importers: version: 7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-router-hono-server: specifier: 2.22.0 - version: 2.22.0(patch_hash=b68723a36649e2c3bd9e9edcfff3a8bc0fdb48e1cf6d64eba37c04f7bfbb1417)(@hono/node-server@1.19.6(hono@4.10.4))(@react-router/dev@7.9.6(@types/node@24.10.1)(@vitejs/plugin-rsc@0.4.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)))(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(terser@5.39.0)(tsx@4.20.6)(typescript@5.9.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1))(@types/react@19.2.5)(bufferutil@4.0.9)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(utf-8-validate@5.0.10)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 2.22.0(patch_hash=e94667f181837f2501959f5cf01fa0a9e6ea2883dcb1137be8b1c6178979bc77)(@hono/node-server@1.19.6(hono@4.10.4))(@react-router/dev@7.9.6(@types/node@24.10.1)(@vitejs/plugin-rsc@0.4.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)))(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(terser@5.39.0)(tsx@4.20.6)(typescript@5.9.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1))(@types/react@19.2.5)(bufferutil@4.0.9)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(utf-8-validate@5.0.10)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)) react-stately: specifier: 3.42.0 version: 3.42.0(react@19.2.0) @@ -8232,7 +8232,7 @@ snapshots: react-dom: 19.2.0(react@19.2.0) react-router: 7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router-hono-server@2.22.0(patch_hash=b68723a36649e2c3bd9e9edcfff3a8bc0fdb48e1cf6d64eba37c04f7bfbb1417)(@hono/node-server@1.19.6(hono@4.10.4))(@react-router/dev@7.9.6(@types/node@24.10.1)(@vitejs/plugin-rsc@0.4.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)))(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(terser@5.39.0)(tsx@4.20.6)(typescript@5.9.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1))(@types/react@19.2.5)(bufferutil@4.0.9)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(utf-8-validate@5.0.10)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)): + react-router-hono-server@2.22.0(patch_hash=e94667f181837f2501959f5cf01fa0a9e6ea2883dcb1137be8b1c6178979bc77)(@hono/node-server@1.19.6(hono@4.10.4))(@react-router/dev@7.9.6(@types/node@24.10.1)(@vitejs/plugin-rsc@0.4.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)))(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(terser@5.39.0)(tsx@4.20.6)(typescript@5.9.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1))(@types/react@19.2.5)(bufferutil@4.0.9)(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(utf-8-validate@5.0.10)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@drizzle-team/brocli': 0.11.0 '@hono/node-server': 1.19.6(hono@4.10.4)