Frontend

Server-rendered BXM views, small Alpine.js components, and a Vite-compiled SCSS/JS pipeline.

On this page

Frontend

How it fits together

The frontend is a hybrid server-rendered + Alpine.js application - no SPA, no client-side router:

1
ColdBox layouts provide the shell

Admin.bxm, AuthSplit.bxm, and friends in app/layouts/ render the HTML frame.

2
BXM templates render server-side

Views in app/views/ render with rc/prc data already resolved by the handler.

3
Alpine.js adds interactivity

Small x-data components handle forms, modals, drawers, and toggles - no build step needed per-component.

4
Vite compiles the assets

SCSS + JS from resources/assets/ compile into public/includes/, served at the ASSET_URL prefix.

Alpine.js architecture

App.js (entry)
  ├── Registers all Alpine stores + components
  ├── Imports Bootstrap JS + Phosphor icons + Tippy.js
  │
  ├── Stores ($store.*)
  │   ├── theme.js     → dark/light mode, syncs data-bs-theme + localStorage
  │   └── sidebar.js   → collapse/open, mobile overlay, localStorage persistence
  │
  └── Components (x-data)
      ├── auth/        → AuthForm, RegisterForm, ForgotPasswordForm, PasswordResetForm
    ├── security/     → AuditLogForm, PermissionsForm, RolesForm, UserDetailForm, UsersForm
    ├── profile/      → PasskeyOnboarding, PreferencesForm, ProfileForm
    ├── settings/     → SettingsForm, SettingsRegistryForm
    └── ui/           → Drawer, GlobalProgress, GlobalToast, Logo, MessageBox, PasswordMeter, PasswordStrength, Switch

Each component is a standalone module returning an Alpine x-data object:

export default () => ( {
    visible: true,
    init() {
        setTimeout( () => this.visible = false, 5000 );
    }
} );
<div x-data="messageBox" x-show="visible" x-transition>
    <!-- alert content -->
</div>

SCSS structure

app.scss
  ├── _variables.scss   Bootstrap variable overrides
  ├── bootstrap          Full Bootstrap 5.3 import
  ├── _base.scss         CSS custom properties (light/dark theme)
  ├── components/        9 component partials
  ├── layouts/            Admin + Auth layout partials
  └── views/              Page-specific styles

Vite configuration

vite.config.mjs uses coldbox-vite-plugin's coldbox() plugin:

  • Entry points: resources/assets/scss/app.scss and resources/assets/js/App.js
  • refresh: appRefreshPaths — auto full-reload on handler/view changes
  • publicDirectory: "public/includes" — where built assets land
  • SCSS preprocessor with silenceDeprecations flags for newer Dart Sass (import, global-builtin, color-functions, if-function)
npm run dev        # Vite dev server with HMR
npm run build      # Production build → public/includes/
npm run lint       # ESLint check on resources/assets/js
npm run lint:fix   # ESLint auto-fix
npm run lint:scss  # Stylelint on resources/assets/scss
ASSET_URL

In production, compiled asset URLs are prefixed with the ASSET_URL environment variable (.env.example defaults it to /includes) - see Configuration.

Server-rendered view components

These BXM partials live under app/views/_components/ and are rendered with ColdBox's view() helper. They are intentionally presentation-focused: pass values through the args struct and keep business logic in handlers or services.

Application shell

PartialPurpose and inputs
_components/app/includesDocument metadata, theme/sidebar FOUC prevention, passkey script, and Vite CSS/JS. Optional title. Include once in <head>.
_components/app/sidebarAdmin navigation, permission-aware Users/Roles/Permissions/Audit Log links, settings submenu, and sidebar footer. Reads prc.authUser; include from Admin.bxm.
_components/app/sidebar-brandApplication logo/name link used by the sidebar.
_components/app/sidebar-footerAuthenticated user summary and profile/sign-out actions used by the sidebar.
_components/app/topbarSidebar toggle, theme toggle, breadcrumbs, user menu, and sign-out action. Reads prc.authUser and prc.title.
_components/app/topbar-breadcrumbsDashboard breadcrumb rendered inside the topbar. Extend when adding deeper navigation.
_components/app/topbar-notificationsTopbar notification slot/component for application notifications.
_components/app/footerCopyright and footer links. Optional classes. Reads prc.settings.cbCopyrightNotice.

Authentication partials

PartialPurpose and inputs
_components/auth/footerFooter used by authentication layouts.
_components/auth/passwordInputReusable password field with visibility toggle and password-strength affordances.

UI partials

PartialPurpose and inputs
_components/ui/modalGeneric Alpine dialog that renders an optional nested view. Required id should be unique; supports title, openExpression, closeExpression, contentView, and contentArgs.
_components/ui/drawerRight-side focus-trapped dialog with backdrop/Escape closing and optional contentView/contentArgs; also initializes drawer().
_components/ui/confirmConfirmation dialog with static or Alpine-bound message, confirm/cancel expressions, labels, icon, button class, and disabled expression.
_components/ui/messageboxDismissible info/success/warning/error alert. Supports static message/title or dynamic messageExpression/typeExpression/dismissAction, plus autoDismiss and classes.
_components/ui/globalProgressGlobal accessible progress bar. Include once per layout; controlled by $progress.start()`, `$progress.set(), and $progress.stop().
_components/ui/globalToastGlobal toast stack. Include once per layout; accepts duration, position, and maxVisible, and receives notifications from $toast().
_components/ui/logoReusable application logo/branding partial.
_components/ui/passwordMeterPassword policy meter used beside password fields.
_components/ui/progressbarInline progress bar partial for a local numeric value.
_components/ui/switchAccessible switch control partial for boolean settings.

Alpine components and stores

resources/assets/js/App.js registers the following names globally with Alpine. Use them as x-data="name" or x-data="name(...)" in BXM views. Form components make remote requests to the matching handler routes and expect the CSRF token supplied by their view.

Application shell and authentication

Alpine nameSourceResponsibility
adminBodycomponents/app/AdminBody.jsAdmin page shell behavior and global layout events.
sidebarBrandcomponents/app/SidebarBrand.jsSidebar brand interactions.
footercomponents/app/Footer.jsFooter state and current-year behavior.
authFormcomponents/auth/AuthForm.jsLogin submission, validation, remember-me, and errors.
registerFormcomponents/auth/RegisterForm.jsRegistration validation, email availability, and submission.
forgotPasswordFormcomponents/auth/ForgotPasswordForm.jsForgot-password request state and feedback.
passwordResetFormcomponents/auth/PasswordResetForm.jsPassword reset token submission and validation.

Admin and profile forms

Alpine nameSourceResponsibility
usersFormcomponents/security/UsersForm.jsUser listing, search, pagination, invitation, status, and admin actions.
userDetailFormcomponents/security/UserDetailForm.jsUser profile, role, permission, preference, token, and verification actions.
rolesFormcomponents/security/RolesForm.jsRole CRUD and assigning/removing users and permissions.
permissionsFormcomponents/security/PermissionsForm.jsPermission listing and CRUD operations.
auditLogFormcomponents/security/AuditLogForm.jsAudit filtering, pagination, detail drawer, CSV export, purge, and clear actions.
settingsFormcomponents/settings/SettingsForm.jsCore application settings editing and cache-related feedback.
settingsRegistryFormcomponents/settings/SettingsRegistryForm.jsRegistry search, pagination, create/update, enable/disable, and delete actions.
profileFormcomponents/profile/ProfileForm.jsProfile fields, password policy, and API token management.
preferencesFormcomponents/profile/PreferencesForm.jsPersisting user preferences.
passkeyOnboardingcomponents/profile/PasskeyOnboarding.jsPasskey registration and required-passkey onboarding.

UI components and global APIs

Alpine nameSourceResponsibility
messageBoxcomponents/ui/MessageBox.jsAlert visibility and optional timed dismissal.
passwordMetercomponents/ui/PasswordMeter.jsPassword requirement and strength display.
passwordStrengthcomponents/ui/PasswordStrength.jsPassword strength calculation and labels.
switchComponentcomponents/ui/Switch.jsToggle state and change handling.
drawercomponents/ui/Drawer.jsDrawer lifecycle and focus behavior.
globalProgresscomponents/ui/GlobalProgress.jsProgress events and current progress value.
globalToastcomponents/ui/GlobalToast.jsToast queue, dismissal, type mapping, and stack limits.

The source also contains Header.js, Sidebar.js, TopBarNotifications.js, and Logo.js. Their exports are available for local imports, but they are not currently registered by App.js; register them with Alpine.data() before using them as global x-data components.

Stores, utilities, and magic properties

APISourceUsage
$store.themestores/theme.jsLight/dark mode, data-bs-theme, and localStorage persistence.
$store.sidebarstores/sidebar.jsDesktop collapse, mobile open/close, and localStorage persistence.
$formatDate`, `$formatDateTime, $relativeDateutils/dateFormat.jsConsistent date display with fallbacks.
$countLabelutils/countLabel.jsSingular/plural count labels.
$sortClass`, `$sortIconutils/sort.jsSortable table headers and indicators.
$passwordMeetsPolicyutils/passwordPolicy.jsChecks the configured password requirements.
$isEmailApp.jsLightweight email-format check.
$toast` / `$progresscomponents/ui/GlobalToast.js, GlobalProgress.jsGlobal notification and progress APIs.
$focus` / `$copyApp.jsFocus a descendant after Alpine updates; copy text through the browser clipboard API.
createRemoteListing()utils/listing.jsShared remote listing state, loading, pagination, and error handling.

AlpinePlugins.js installs Collapse, Focus, Mask, and Persist. passkeys.js provides the browser-side WebAuthn integration. Keep new reusable browser APIs documented here and add their registration/import to App.js when they are global.

Edit this page Download Markdown Last updated Sep 1, 2026, 7:55:53 PM