feat: App - Support setting base URL during build

This is needed to host OpenCode app under under some URL prefix.
This minimal change makes it possible to build OpenCode Web App with VITE_BASE_URL="/subdir/" and have it run under `http://<host>:<port>/subdir/` instead of root (`http://<host>:<port>/`).

Set `VITE_BASE_URL` env var during build. This automatically sets the `base` in Vite config. Vite generates correct URLs in `index.html`.
`import.meta.env.BASE_URL` is also used in routers. See https://vite.dev/config/shared-options#base
You can also set `VITE_OPENCODE_SERVER_BASE_URL` to specify the base URL prefix for the server.

Usage:
```
% VITE_BASE_URL="/XXX" VITE_OPENCODE_SERVER_BASE_URL="/" bun dev
$ vite
(!) "base" option should start with a slash.

  VITE v7.1.4  ready in 320 ms

  ➜  Local:   http://localhost:3000/XXX
```
pull/18209/head
Alexey Volkov 2026-03-19 01:34:28 -07:00
parent 0bbf26a1ce
commit ad930e0ba2
No known key found for this signature in database
GPG Key ID: AD5B02DD0971751E
4 changed files with 7 additions and 2 deletions

View File

@ -284,6 +284,7 @@ export function AppInterface(props: {
<Dynamic
component={props.router ?? Router}
root={(routerProps) => <RouterRoot appChildren={props.children}>{routerProps.children}</RouterRoot>}
base={import.meta.env.BASE_URL.replace(/\/$/, "") || undefined}
>
<Route path="/" component={HomeRoute} />
<Route path="/:dir" component={DirectoryLayout}>

View File

@ -99,9 +99,11 @@ if (!(root instanceof HTMLElement) && import.meta.env.DEV) {
const getCurrentUrl = () => {
if (location.hostname.includes("opencode.ai")) return "http://localhost:4096"
const serverBaseUrl =
"/" + (import.meta.env.VITE_OPENCODE_SERVER_BASE_URL ?? "/").replace(/^\//, "").replace(/\/$/, "")
if (import.meta.env.DEV)
return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}`
return location.origin
return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}{serverBaseUrl}`
return location.origin + serverBaseUrl
}
const getDefaultUrl = () => {

View File

@ -1,6 +1,7 @@
import "solid-js"
interface ImportMetaEnv {
readonly BASE_URL: string
readonly VITE_OPENCODE_SERVER_HOST: string
readonly VITE_OPENCODE_SERVER_PORT: string
}

View File

@ -2,6 +2,7 @@ import { defineConfig } from "vite"
import desktopPlugin from "./vite"
export default defineConfig({
base: process.env.VITE_BASE_URL || "/",
plugins: [desktopPlugin] as any,
server: {
host: "0.0.0.0",