feat(web): render the app name from config (BUNYIP-499) #500

Merged
nrupard merged 1 commit from feat/BUNYIP-499-branding-config into main 2026-08-07 19:39:37 +02:00
Owner

B1 of the BUNYIP-459 theme-agnostic-web-kit epic.

What

Make bunyip-web's app/brand name config-driven instead of a hardcoded "Bunyip" literal, so a skin can rebrand the web UI without editing the framework.

Changes

  • Config.app_name from APP_NAME (default "Bunyip"), installed once at startup via a views::layout OnceLock (install_app_name / app_name()), mirroring the existing SSE_API_ORIGIN / COMMUNITY_ENABLED installs.
  • brand() renders app_name() instead of the literal.
  • The browser-title " · Bunyip" suffix, previously baked into ~96 title literals across the handlers, is now appended once in document() as " · {app_name()}", and every call site passes a bare page title. The now-redundant topbar_title() strip helper (which hardcoded " · Bunyip") is removed - the top bar already renders the bare title.
  • main installs the name from Config; bunyip-web/.env.example documents APP_NAME.

Byte-identical by default

document() is the single <title> sink (every response path funnels through it), so with APP_NAME unset every rendered <title> and the brand mark are byte-identical to before. bunyip-web's compose service does not receive APP_NAME today (only bunyip-api does, for email branding), so no deploy changes the web brand until APP_NAME is wired into the bunyip-web service per skin - a deliberate deploy/skin decision, out of scope here.

Scope

B1 only (brand name + browser-title suffix). Theme colors (B2 / BUNYIP-500), skin-content de-brand (B3 / BUNYIP-501), the shared web-kit crate (B4 / BUNYIP-502), and CSP config (B5 / BUNYIP-503) are the sibling children of the epic. The framework's meta description still names Bunyip/Mokosh; that is marketing copy handled in B3.

Validation

cargo fmt --all --check and cargo clippy --workspace --all-targets -- -D warnings green; cargo test -p bunyip-web green (bunyip-web is a standalone binary with no async-stripe dependency, so its tests run locally).

B1 of the BUNYIP-459 theme-agnostic-web-kit epic. ## What Make bunyip-web's app/brand name config-driven instead of a hardcoded `"Bunyip"` literal, so a skin can rebrand the web UI without editing the framework. ## Changes - `Config.app_name` from `APP_NAME` (default `"Bunyip"`), installed once at startup via a `views::layout` `OnceLock` (`install_app_name` / `app_name()`), mirroring the existing `SSE_API_ORIGIN` / `COMMUNITY_ENABLED` installs. - `brand()` renders `app_name()` instead of the literal. - The browser-title `" · Bunyip"` suffix, previously baked into ~96 title literals across the handlers, is now appended once in `document()` as `" · {app_name()}"`, and every call site passes a bare page title. The now-redundant `topbar_title()` strip helper (which hardcoded `" · Bunyip"`) is removed - the top bar already renders the bare title. - `main` installs the name from `Config`; `bunyip-web/.env.example` documents `APP_NAME`. ## Byte-identical by default `document()` is the single `<title>` sink (every response path funnels through it), so with `APP_NAME` unset every rendered `<title>` and the brand mark are byte-identical to before. bunyip-web's compose service does not receive `APP_NAME` today (only bunyip-api does, for email branding), so no deploy changes the web brand until `APP_NAME` is wired into the bunyip-web service per skin - a deliberate deploy/skin decision, out of scope here. ## Scope B1 only (brand name + browser-title suffix). Theme colors (B2 / BUNYIP-500), skin-content de-brand (B3 / BUNYIP-501), the shared web-kit crate (B4 / BUNYIP-502), and CSP config (B5 / BUNYIP-503) are the sibling children of the epic. The framework's `meta description` still names Bunyip/Mokosh; that is marketing copy handled in B3. ## Validation `cargo fmt --all --check` and `cargo clippy --workspace --all-targets -- -D warnings` green; `cargo test -p bunyip-web` green (bunyip-web is a standalone binary with no async-stripe dependency, so its tests run locally).
feat(web): render the app name from config
All checks were successful
E2E / PR gate (pull_request) Successful in 13s
Check / fmt + clippy + build + tests (pull_request) Successful in 12m13s
Create release / Create release from merged PR (pull_request) Has been skipped
31b1d2c975
B1 of the theme-agnostic web-kit epic. bunyip-web's brand name is now config-driven instead of a hardcoded "Bunyip" literal, so a skin can rebrand the web UI without editing the framework.

Config.app_name comes from APP_NAME (default "Bunyip") and is installed once at startup via a views::layout OnceLock (install_app_name / app_name()), the same pattern as SSE_API_ORIGIN and COMMUNITY_ENABLED. brand() renders app_name(). The browser-title " · Bunyip" suffix, previously baked into ~96 title literals across the handlers, is appended once in document() as " · {app_name()}", and every call site now passes a bare page title; the redundant topbar_title() strip helper (which hardcoded " · Bunyip") is removed, since the top bar already renders the bare title.

document() is the single <title> sink, so with APP_NAME unset every rendered <title> and the brand mark are byte-identical to before; the 211 bunyip-web tests pass unchanged. bunyip-web's compose service does not receive APP_NAME today (only bunyip-api does, for email), so no deploy changes the web brand until APP_NAME is wired into the bunyip-web service per skin.

#BUNYIP-499

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard scheduled this pull request to auto merge when all checks succeed 2026-08-07 19:29:34 +02:00
nrupard deleted branch feat/BUNYIP-499-branding-config 2026-08-07 19:39:37 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!500
No description provided.