G
GTM Vault
Browse
  • Dashboard
    • Automations
    • Skills
    • Prompts
    • Makers
  • Sign in
All Skills

shadcn-sidebar

Set up a complete shadcn sidebar with correct collapsible pattern, all dependencies, and visible trigger

skillFrontend DevelopmentClaude Code SkillsInternal Ops
Original
by Roheel Jain
Skill Content

Shadcn Sidebar Setup

Set up a fully working shadcn sidebar from scratch. Follow every step.

Step 1: Pre-flight

  1. Read components.json — confirm "style": "new-york". If not, run /shadcn-init first.
  2. Check if 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
}

Step 2: Fetch ALL dependencies at once

Use mcp__Shadcn_UI__get_component to fetch all 8 components in parallel:

  • tooltip
  • collapsible
  • sheet
  • separator
  • avatar
  • button
  • input
  • skeleton

Then fetch sidebar itself.

Do NOT write any files until all 9 sources are fetched.

Step 3: Fix imports and write

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.

Step 4: Scaffold app-sidebar.tsx

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>

Step 5: Set up layout

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>

Step 6: Verify

  1. npm run build — zero errors
  2. Start dev server and screenshot
  3. Check console for errors
  4. Verify: expand/collapse groups work, sidebar toggle works, text sizes are consistent
Tech Stack
JavaScript
JavaScript