Home screen and navigation
Your team opens /admin every morning. Make it land somewhere useful, and keep the sidebar in the order they work.
The home screen
Section titled “The home screen”By default, /admin is a welcome page. Set home to show a screen there instead, with the URL unchanged. The demo shows its Overview:
/** * What /admin shows: the Overview screen from app/admin/screens (FR-22) */home: 'overview',Or send people to a resource’s list:
home: { resource: 'orders' },- The home screen replaces “Dashboard” at the top of the navigation.
- A user who fails the screen’s ability gets the welcome page, not a 403.
- With
{ resource }, only users who may list that resource are redirected. Everyone else gets the welcome page. - A
homethat names no screen or resource stops the app from booting.
The sidebar
Section titled “The sidebar”The sidebar holds your brand, the dashboard, and your resources. At the bottom is the signed-in user’s account button.
On screens narrower than 768px, a menu button in a top bar opens the sidebar as a drawer. It has the same choices, as full-width rows.
Order and groups
Section titled “Order and groups”The navigation lists your resources, your screens, and any links you add.
- Items without a
groupcome first. - Groups follow the order you list in
navigation.groups, then any others alphabetically. - Within a group, resources, screens, and links sort together.
ordercomes first, lower first. Then items without one, alphabetically.
/** * Navigation group order. Groups not listed follow, by label. */navigation: { groups: ['Sales', 'Catalog', 'Reports', 'Settings', 'Help'], // Links to any URL (FR-21). An ability would only hide one; its page checks access itself links: [ { label: 'Awaiting shipping', url: '/admin/resources/orders?status=paid', group: 'Sales', icon: 'truck', order: 2, ability: viewOrders, }, { label: 'Azu documentation', url: 'https://github.com/mezielabs/azu#readme', group: 'Help', icon: 'book-open', }, ],},Links point anywhere: a filtered list, a page of your app, another site.
- A link to an absolute
http(s)URL opens in a new tab, with an external-link icon. - A link is highlighted when the page’s path and query match it.
A link’s ability is a Bouncer ability, like a screen’s. It only hides the link from users who fail it.
The demo’s “Awaiting shipping” link asks the order policy, rather than repeating its rule:
export const viewOrders = Bouncer.ability((user: User) => { return new Bouncer(user, {}, policies).with('OrderPolicy').allows('viewList')})icon is a Lucide icon name in kebab case, like 'package' or 'shopping-cart'.
Install lucide-react to show icons. Without it, the navigation shows none.
npm i lucide-reactThe azu() Vite plugin bundles only the icons you name. It reads them from app/admin/resources, app/admin/screens, and config/azu.ts.
If you set icon in a way the plugin can’t read, from a variable say, list the name yourself:
azu({ icons: ['shopping-cart'] })An unknown name gives a warning at build time and shows no icon.
The account menu
Section titled “The account menu”The account button’s menu holds:
- the theme: Light, Dark, or System. See Theming.
- “View site”, which opens your
siteUrl(/by default). SetsiteUrl: falseto hide it. - Sign out.
Sign out posts to /admin/logout. That signs the user out of Azu’s auth guard (guard in config/azu.ts) and sends them to your loginUrl.
Note: sign out doesn’t run your app’s own logout code, such as an audit entry or extra cookies.