From 3170aa6b77985b31630695caab309764904146c9 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 7 Jun 2026 00:03:01 -0400 Subject: [PATCH] feat(setup): collect server base URL during first-run wizard Add a Server URL field to the admin-account step of the setup wizard so the public base URL (used for device sync, OPDS feed, and API endpoints) is configured up front instead of requiring a later visit to admin settings. - setup.templ: base URL input on the admin step plus a summary entry - setup.ts: default baseUrl to window.location.origin and persist it via PUT /system/config ({ base_url }) right after the admin account is created, with a non-fatal warning if the save fails --- templates/setup.templ | 17 +++++++++++++++++ templates/setup_templ.go | 2 +- web/src/setup.ts | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/templates/setup.templ b/templates/setup.templ index ee8279b..ee81ba7 100644 --- a/templates/setup.templ +++ b/templates/setup.templ @@ -49,6 +49,19 @@ templ Setup() {

This first account will have full admin privileges.

+
+ + +

The public URL of your Bookhoard instance. Used for device sync, OPDS feed, and API endpoints.

+
+
+
+

Server URL

+

+

Administrator

diff --git a/templates/setup_templ.go b/templates/setup_templ.go index fd6daec..d19dcb1 100644 --- a/templates/setup_templ.go +++ b/templates/setup_templ.go @@ -29,7 +29,7 @@ func Setup() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Setup - Bookhoard

Welcome to Bookhoard

Let's get your library set up.

Create Administrator Account

This first account will have full admin privileges.

Password Requirements:

  • At least 8 characters
  • One uppercase letter
  • One lowercase letter
  • One number
  • One special character
  • Passwords match

Create Libraries

Add one or more media libraries. You can always add more later.

0\" class=\"mb-6 space-y-2\">

Configure Library Folders

Add the filesystem folders where your media files are stored.

No libraries created. You can add folders later from the admin panel.

Scan & Finish

Review your configuration and start the initial scan.

Administrator

Libraries ()

Scan Progress

Initial scan complete! Your libraries are ready to use.

Browse Folders

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Setup - Bookhoard

Welcome to Bookhoard

Let's get your library set up.

Create Administrator Account

This first account will have full admin privileges.

The public URL of your Bookhoard instance. Used for device sync, OPDS feed, and API endpoints.

Password Requirements:

  • At least 8 characters
  • One uppercase letter
  • One lowercase letter
  • One number
  • One special character
  • Passwords match

Create Libraries

Add one or more media libraries. You can always add more later.

0\" class=\"mb-6 space-y-2\">

Configure Library Folders

Add the filesystem folders where your media files are stored.

No libraries created. You can add folders later from the admin panel.

Scan & Finish

Review your configuration and start the initial scan.

Server URL

Administrator

Libraries ()

Scan Progress

Initial scan complete! Your libraries are ready to use.

Browse Folders

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/web/src/setup.ts b/web/src/setup.ts index 18aeef2..94209e0 100644 --- a/web/src/setup.ts +++ b/web/src/setup.ts @@ -36,14 +36,13 @@ function initSetup(): void { if (savedTheme && savedTheme !== "tokyo-night") { applyTheme(savedTheme); } -} - -Alpine.data("setupWizard", () => ({ +}Alpine.data("setupWizard", () => ({ currentStep: 1 as number, loading: false as boolean, errorMsg: "" as string, admin: { + baseUrl: "", email: "", username: "", password: "", @@ -71,6 +70,7 @@ Alpine.data("setupWizard", () => ({ init() { initSetup(); + this.admin.baseUrl = window.location.origin; setTimeout(() => { initPasswordValidation(); }, 100); @@ -128,6 +128,8 @@ Alpine.data("setupWizard", () => ({ setToken(data.token || data.access_token); setRefreshToken(data.refresh_token); + await this.saveBaseUrl(); + showToast("Admin account created successfully!", "success"); this.currentStep = 2; } catch (err) { @@ -137,6 +139,17 @@ Alpine.data("setupWizard", () => ({ } }, + async saveBaseUrl() { + if (!this.admin.baseUrl) return; + try { + await handleVoidResponse( + await apiPut("/system/config", { base_url: this.admin.baseUrl }) + ); + } catch { + showToast("Warning: could not save server URL. You can set it later in Admin Settings.", "warning"); + } + }, + async addLibrary() { this.clearError(); this.loading = true;