Set up a complete shadcn sidebar with correct collapsible pattern, all dependencies, and visible trigger
Set up a fully working shadcn sidebar from scratch. Follow every step.
components.json — confirm "style": "new-york". If not, run /shadcn-init first.src/hooks/use-mobile.tsx exists. If not, create it:"use client"
import * as React from "react"
const MOBILE_BREAKPOINT = 768
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
return !!isMobile
}
Use mcp__Shadcn_UI__get_component to fetch all 8 components in parallel:
tooltipcollapsiblesheetseparatoravatarbuttoninputskeletonThen fetch sidebar itself.
Do NOT write any files until all 9 sources are fetched.
For the sidebar source, fix all registry paths:
@/registry/new-york-v4/ui/... → @/components/ui/...@/registry/new-york-v4/hooks/... → @/hooks/...@/registry/new-york-v4/lib/... → @/lib/...Critical fix: Add gap-2 to the SidebarGroupLabel className (after items-center). The canonical source omits it, causing icons to jam against text.
Write all 9 component files + the hook in parallel.
Create src/components/app-sidebar.tsx using the CORRECT collapsible pattern:
// CORRECT pattern for collapsible nav groups:
<SidebarGroup>
<SidebarGroupLabel>Section Name</SidebarGroupLabel>
<SidebarMenu>
{/* Regular items */}
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href="/path"><Icon /><span>Label</span></Link>
</SidebarMenuButton>
</SidebarMenuItem>
{/* Collapsible items */}
<Collapsible asChild defaultOpen className="group/collapsible">
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton tooltip="Group Name">
<Icon />
<span>Group Name</span>
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
<SidebarMenuSubItem>
<SidebarMenuSubButton asChild>
<Link href="/sub-path"><span>Sub Item</span></Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
</SidebarMenu>
</SidebarGroup>
WRONG pattern (never do this):
// WRONG: SidebarGroupLabel as CollapsibleTrigger
<Collapsible>
<SidebarGroup>
<SidebarGroupLabel asChild>
<CollapsibleTrigger>...</CollapsibleTrigger>
</SidebarGroupLabel>
...
</SidebarGroup>
</Collapsible>
Include a visible SidebarTrigger in the sidebar header:
<SidebarHeader>
<div className="flex items-center justify-between">
<Link href="/" className="flex items-center gap-2">
{/* Logo */}
</Link>
<SidebarTrigger className="group-data-[collapsible=icon]:hidden" />
</div>
</SidebarHeader>
Create/update the app layout with SidebarProvider:
<SidebarProvider>
<AppSidebar />
<SidebarInset>
<header className="flex h-14 shrink-0 items-center gap-2 border-b px-4">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 !h-4" />
</header>
<main className="flex-1 overflow-auto p-6">{children}</main>
</SidebarInset>
</SidebarProvider>
npm run build — zero errors