Sidebar
Configure the admin sidebar — sections, collection items, global items, and external links.
The sidebar controls admin navigation. Configure it in config/admin.ts — define sections and items under the sidebar key.
Basic Setup
import { adminConfig } from "#questpie/factories";
export default adminConfig({
sidebar: {
sections: [
{ id: "overview", title: { en: "Overview" } },
{ id: "content", title: { en: "Content" } },
],
items: [
{
sectionId: "overview",
type: "link",
label: { en: "Dashboard" },
href: "/admin",
icon: { type: "icon", props: { name: "ph:house" } },
},
{
sectionId: "content",
type: "collection",
collection: "posts",
},
],
},
});Sections
Sections group sidebar items:
sections: [
{ id: "overview", title: { en: "Overview", sk: "Prehľad" } },
{ id: "operations", title: { en: "Operations", sk: "Prevádzka" } },
{ id: "content", title: { en: "Content", sk: "Obsah" } },
{ id: "team", title: { en: "Team", sk: "Tím" } },
];Item Types
Collection
Links to a collection list view. Label and icon are read from the collection's .admin() config:
{ sectionId: "content", type: "collection", collection: "posts" }Global
Links to a global edit form:
{ sectionId: "overview", type: "global", global: "siteSettings" }Link
Custom link with icon:
{
sectionId: "external",
type: "link",
label: { en: "Open Website" },
href: "/",
external: true,
icon: { type: "icon", props: { name: "ph:arrow-square-out" } },
}Real-World Example
From the barbershop:
import { adminConfig } from "#questpie/factories";
export default adminConfig({
sidebar: {
sections: [
{ id: "overview", title: { en: "Overview" } },
{ id: "operations", title: { en: "Operations" } },
{ id: "content", title: { en: "Content" } },
{ id: "team", title: { en: "Team" } },
{ id: "external", title: { en: "External" } },
{ id: "administration", title: { en: "Administration" } },
],
items: [
{
sectionId: "overview",
type: "link",
label: { en: "Dashboard" },
href: "/admin",
icon: { type: "icon", props: { name: "ph:house" } },
},
{ sectionId: "overview", type: "global", global: "siteSettings" },
{
sectionId: "operations",
type: "collection",
collection: "appointments",
},
{ sectionId: "operations", type: "collection", collection: "reviews" },
{ sectionId: "content", type: "collection", collection: "pages" },
{ sectionId: "content", type: "collection", collection: "services" },
{ sectionId: "team", type: "collection", collection: "barbers" },
{
sectionId: "external",
type: "link",
label: { en: "Open Website" },
href: "/",
external: true,
icon: { type: "icon", props: { name: "ph:arrow-square-out" } },
},
],
},
});Chrome Overrides
To customize sidebar chrome without modifying your app shell, use file-first component overrides.
Brand area
Replace the logo + name area:
import type { AdminSidebarBrandProps } from "@questpie/admin/client";
export default function SidebarBrand({
name,
collapsed,
}: AdminSidebarBrandProps) {
return (
<div className="flex items-center gap-2">
<img src="/logo.svg" alt={name} className="size-6 shrink-0" />
{!collapsed && <span className="font-bold">{name}</span>}
</div>
);
}Nav item rendering
Replace every navigation item row:
import type { AdminSidebarNavItemProps } from "@questpie/admin/client";
export default function NavItem({
item,
isActive,
collapsed,
}: AdminSidebarNavItemProps) {
return (
<a
href={item.href}
className={`flex items-center gap-2 px-3 py-2 text-sm ${isActive ? "font-bold" : ""}`}
>
{!collapsed && (
<span>
{typeof item.label === "string" ? item.label : item.label.en}
</span>
)}
</a>
);
}Both overrides follow the same three-tier priority: runtime prop > file-first > built-in.
Use a normal React component as the default export for these files. React.lazy(...) is fine too. Do not default-export a raw () => import("...") loader function for reserved sidebar overrides.
Module Contributions
Modules can contribute sidebar items. The adminModule adds an "Administration" section with user management. The auditModule adds an audit log item to that section. Your project-level sidebar merges with these contributions.