From 5d32081494a7b48213946b09d18724e959af6857 Mon Sep 17 00:00:00 2001 From: Pecacheu <3608878+Pecacheu@users.noreply.github.com> Date: Thu, 25 Jun 2026 22:17:12 -0400 Subject: [PATCH 1/3] feat: Client config route Signed-off-by: Pecacheu <3608878+Pecacheu@users.noreply.github.com> --- package.json | 3 +++ packages/client/app-config.plugin.ts | 25 ++++++++++++++++++++ packages/client/components/common/lib/env.ts | 15 +++++++++++- packages/client/vite.config.ts | 2 ++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 packages/client/app-config.plugin.ts diff --git a/package.json b/package.json index 6f38c48d02..e1f13fd6dc 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "stoat-for-web", "version": "0.9.1", "description": "Stoat for Web: frontend software for Stoat", + "dependencies": { + "dotenv": "^17.4.2" + }, "devDependencies": { "@eslint/js": "^9.39.1", "eslint": "^9.26.0", diff --git a/packages/client/app-config.plugin.ts b/packages/client/app-config.plugin.ts new file mode 100644 index 0000000000..0dfe18b173 --- /dev/null +++ b/packages/client/app-config.plugin.ts @@ -0,0 +1,25 @@ +import { ViteDevServer } from "vite"; + +//Load .env file +import dotenv from "dotenv"; +dotenv.config({ quiet: true }); + +import CONFIGURATION, { AppConfig } from "./components/common/lib/env"; + +//Data for public config endpoint +const appCfg: AppConfig = { + api: CONFIGURATION.DEFAULT_API_URL, + gifbox: CONFIGURATION.DEFAULT_GIFBOX_URL, +}; + +export default function appConfigPlugin() { + return { + name: "app-config", + configureServer(server: ViteDevServer) { + server.middlewares.use("/.stoat-config", (_, res) => { + res.writeHead(200, { "Content-Type": "application/json" }); + res.end(JSON.stringify(appCfg)); + }); + }, + }; +} diff --git a/packages/client/components/common/lib/env.ts b/packages/client/components/common/lib/env.ts index 73d85d54ca..73c51c0d99 100644 --- a/packages/client/components/common/lib/env.ts +++ b/packages/client/components/common/lib/env.ts @@ -1,7 +1,19 @@ +export const STOAT_API = "https://api.stoat.chat"; + +//Run in NodeJS mode +if (!("env" in import.meta)) + (import.meta as { env: NodeJS.ProcessEnv }).env = process.env; + +/** App `/.stoat-config` endpoint response */ +export interface AppConfig { + api: string; + gifbox: string; +} + const DEFAULT_API_URL = (import.meta.env.DEV ? import.meta.env.VITE_DEV_API_URL : undefined) ?? (import.meta.env.VITE_API_URL as string) ?? - "https://stoat.chat/api"; + STOAT_API; export default { /** @@ -22,6 +34,7 @@ export default { "https://revolt.chat/api", // ... and now: "https://stoat.chat/api", + STOAT_API, ].includes(DEFAULT_API_URL), /** * What WS server to connect to by default. diff --git a/packages/client/vite.config.ts b/packages/client/vite.config.ts index d868fd8b69..79343efdac 100644 --- a/packages/client/vite.config.ts +++ b/packages/client/vite.config.ts @@ -9,6 +9,7 @@ import { VitePWA } from "vite-plugin-pwa"; import solidPlugin from "vite-plugin-solid"; import solidSvg from "vite-plugin-solid-svg"; +import appConfigPlugin from "./app-config.plugin"; import codegenPlugin from "./codegen.plugin"; const base = process.env.BASE_PATH ?? "/"; @@ -19,6 +20,7 @@ export default defineConfig({ Inspect(), devtools(), codegenPlugin(), + appConfigPlugin(), babelMacrosPlugin(), linguiSolidPlugin(), solidPlugin(), From 710c4cb9cc1c4727d978b752de2686469c55955a Mon Sep 17 00:00:00 2001 From: Pecacheu <3608878+Pecacheu@users.noreply.github.com> Date: Thu, 25 Jun 2026 22:17:52 -0400 Subject: [PATCH 2/3] chore: pnpm lockfile Signed-off-by: Pecacheu <3608878+Pecacheu@users.noreply.github.com> --- pnpm-lock.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5386a76df4..a1c17ba6d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,10 @@ overrides: importers: .: + dependencies: + dotenv: + specifier: ^17.4.2 + version: 17.4.2 devDependencies: '@eslint/js': specifier: ^9.39.1 @@ -4416,6 +4420,10 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -11773,6 +11781,8 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + dotenv@17.4.2: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 From 66fe8a1642d4e61374e9a45261f22cf5d3801e43 Mon Sep 17 00:00:00 2001 From: Pecacheu <3608878+Pecacheu@users.noreply.github.com> Date: Thu, 25 Jun 2026 23:54:15 -0400 Subject: [PATCH 3/3] fix: Build static file for Docker mode - Add CORS header Signed-off-by: Pecacheu <3608878+Pecacheu@users.noreply.github.com> --- packages/client/app-config.plugin.ts | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/client/app-config.plugin.ts b/packages/client/app-config.plugin.ts index 0dfe18b173..b389b6cd4b 100644 --- a/packages/client/app-config.plugin.ts +++ b/packages/client/app-config.plugin.ts @@ -1,4 +1,4 @@ -import { ViteDevServer } from "vite"; +import { PluginOption } from "vite"; //Load .env file import dotenv from "dotenv"; @@ -7,18 +7,32 @@ dotenv.config({ quiet: true }); import CONFIGURATION, { AppConfig } from "./components/common/lib/env"; //Data for public config endpoint -const appCfg: AppConfig = { +const appCfg = JSON.stringify({ api: CONFIGURATION.DEFAULT_API_URL, gifbox: CONFIGURATION.DEFAULT_GIFBOX_URL, -}; +} as AppConfig); -export default function appConfigPlugin() { +export default function appConfigPlugin(): PluginOption { return { name: "app-config", - configureServer(server: ViteDevServer) { - server.middlewares.use("/.stoat-config", (_, res) => { - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(JSON.stringify(appCfg)); + //For dev / serve mode + configureServer(server) { + server.middlewares.use("/stoat-config.json", (_, res) => { + res.writeHead(200, { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + }); + res.end(appCfg); + }); + }, + //For static build + buildStart() { + //TODO: This throws warning "context method emitFile() is not supported in serve mode. This plugin is likely not vite-compatible." + //Need to add a conditional and detect serve mode somehow + this.emitFile({ + fileName: "stoat-config.json", + source: appCfg, + type: "asset", }); }, };