Skip to content

Main (ue-main) ​

ue-main is the root application shell. It wraps v-app and composes the top bar, sidebar, page content area, optional bottom navigation, and a set of singleton modals that are available everywhere in the app.

Usage ​

Pass the navigation object from your Inertia/backend page props:

html
<ue-main
  :navigation="navigation"
  header-title="My App"
  :impersonation="impersonation"
  :authorization="authorization"
>
  <!-- page content -->
</ue-main>

The navigation prop is typically shared via Inertia's HandleInertiaRequests middleware and has this shape:

php
'navigation' => [
    'sidebar'      => $this->buildSidebarItems(),
    'sidebarBottom' => [],
    'profileMenu'  => $this->buildProfileMenu(),
    'breadcrumbs'  => [],
]

Props ​

PropTypeDefaultDescription
navigationObject{ sidebar: [], breadcrumbs: [], profileMenu: [], sidebarBottom: [] }Navigation data. Keys: sidebar, sidebarBottom, profileMenu, breadcrumbs.
headerTitleString''Text shown in the centre of the top app bar.
hideDefaultSidebarBooleanfalseOmit the sidebar entirely (e.g. for login/auth pages).
fixedAppBarBooleanfalseForce the top bar to render regardless of ui_settings.
appBarOrderNumber0Vuetify order for the v-app-bar when fixedAppBar is true.
sidebarAttributesObject{}Extra props forwarded to ue-sidebar.
impersonationObject{}Config for the impersonation toolbar. See Impersonation.
authorizationObject{}Auth flags used to gate the media library. See Authorization.

Slots ​

SlotDescription
defaultMain page content. Rendered inside v-main.
topContent rendered above the default slot inside v-main.
bottomContent rendered below the default slot inside v-main.
app-barReplaces the entire default v-app-bar inner content. Receives no bindings.
bottom-navReplaces the default items inside v-bottom-navigation (mobile).
KeyTypeDescription
sidebarArrayItems passed to ue-sidebar / ue-navigation-group.
sidebarBottomArrayItems pinned to the bottom of the sidebar via ue-navigation-group.
profileMenuArrayItems for the collapsible profile menu in the sidebar footer.
breadcrumbsArrayReserved; not currently consumed by Main.vue directly.

Top bar ​

The top bar is a v-app-bar that renders when showTopbar is true. The value is derived from useNavigationLayout() (which reads ui_settings.topbar) unless fixedAppBar is true, which forces it on.

Default top-bar content:

  • Hamburger icon — shown on screens below lg; toggles the sidebar via $toggleSidebar().
  • Title — centred, driven by headerTitle prop.
  • Avatar — shows the current user's avatar; clicking opens the profile dialog.

Override the entire bar using #app-bar.

Bottom navigation ​

A v-bottom-navigation is rendered when showBottomNav is true (resolved from useNavigationLayout()). Default items are a Home button and a Profile button. Override with #bottom-nav.

Singleton modals ​

ue-main mounts the following modals once for the entire application:

ModalTriggerDescription
ue-modal-mediastore.state.mediaLibrary.showModalFull media library browser
Profile dialogstore.state.user.profileDialog / $openProfileDialogAvatar upload form
Alert dialogstore.state.alert.dialogLarge-format dialog alert
Login modalstore.state.user.showLoginModalSession-expired re-login form
ue-alertstore.state.alertSnackbar/toast notifications
ue-dynamic-modalprogrammatic APIDynamically triggered modals

Impersonation ​

Pass an impersonation object to show the impersonation toolbar at the bottom of the sidebar:

php
'impersonation' => [
    'active'        => auth()->user()->isImpersonating(),
    'fetchEndpoint' => route('impersonate.users'),
    'route'         => route('impersonate.start', ':id'),
    'stopRoute'     => route('impersonate.stop'),
]
KeyTypeDescription
activeBooleanShows the toolbar when true
fetchEndpointStringAPI endpoint to search users
routeStringURL template for starting impersonation (:id is replaced)
stopRouteStringURL to stop impersonation

Authorization ​

The authorization object controls whether the media library modal is mounted:

php
'authorization' => [
    'isClient' => $user->isClient(),
]

The media library is accessible when authorization is a non-empty object and isClient is false.

CSS classes on v-app ​

Main.vue applies these classes to the root v-app element based on sidebar state:

ClassCondition
ue-sidebar-expandedDesktop, sidebar open and not rail-only
ue-sidebar-rail-onlyDesktop, rail mode active and sidebar open
ue-sidebar-fully-hiddenexpandHover === 'hidden' and sidebar not pinned

CSS custom properties set on v-app:

PropertySet when
--ue-sidebar-widthSidebar is expanded; value is the configured drawer width in px
--ue-sidebar-rail-widthSidebar is in rail-only mode; value is the rail width in px

Development mode banner ​

When store.getters.isHot is true (HMR active), a green "Development Mode" chip is shown in the top-right corner of the screen. Clicking it dismisses it.