# Layout & Structure

> Page layouts, cards, tabs, and structural components.

*Canonical: https://makerkit.dev/docs/nextjs-prisma/ui-components/layout-and-structure*

---

Structure your pages with `Card` for content grouping, `Page` for application layouts with sidebar navigation, `Tabs` for tabbed interfaces, and `Accordion`/`Collapsible` for expandable sections. All layout components handle responsive behavior and dark mode.

This guide is part of the [UI Components](./overview) documentation.

Layout components organize content structure and visual hierarchy, providing consistent spacing, borders, and responsive behavior across the application.

## Card

Container component for grouping related content.

```typescript
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction } from '@kit/ui/card';
```

```tsx
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card description text</CardDescription>
  </CardHeader>
  <CardContent>
    Card content goes here
  </CardContent>
  <CardFooter>
    <Button>Action</Button>
  </CardFooter>
</Card>
```

### With Action Button

```tsx
<Card>
  <CardHeader>
    <CardTitle>Settings</CardTitle>
    <CardDescription>Manage your preferences</CardDescription>
    <CardAction>
      <Button variant="ghost" size="icon">
        <Settings className="h-4 w-4" />
      </Button>
    </CardAction>
  </CardHeader>
  <CardContent>
    Content here
  </CardContent>
</Card>
```

### Small Size

```tsx
<Card size="sm">
  <CardContent>Compact card</CardContent>
</Card>
```

## Page

Application page layout with header, navigation, and body sections.

```typescript
import { Page, PageHeader, PageTitle, PageDescription, PageBody, PageNavigation, PageMobileNavigation, PageHeaderActions } from '@kit/ui/page';
```

```tsx
<Page>
  <PageNavigation>
    <Sidebar />
  </PageNavigation>

  <PageMobileNavigation>
    <MobileNav />
  </PageMobileNavigation>

  <PageBody>
    <PageHeader>
      <div>
        <PageTitle>Dashboard</PageTitle>
        <PageDescription>Overview of your account</PageDescription>
      </div>
      <PageHeaderActions>
        <Button>New Item</Button>
      </PageHeaderActions>
    </PageHeader>

    {/* Page content */}
  </PageBody>
</Page>
```

## Sidebar

Collapsible sidebar navigation.

```typescript
import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarTrigger } from '@kit/ui/sidebar';
```

```tsx
<Sidebar>
  <SidebarContent>
    <SidebarGroup>
      <SidebarGroupLabel>Navigation</SidebarGroupLabel>
      <SidebarMenu>
        <SidebarMenuItem>
          <SidebarMenuButton render={<Link href="/dashboard" />}>
            <Home className="h-4 w-4" />
            Dashboard
          </SidebarMenuButton>
        </SidebarMenuItem>
      </SidebarMenu>
    </SidebarGroup>
  </SidebarContent>
</Sidebar>
```

## Tabs

Tabbed content interface.

```typescript
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@kit/ui/tabs';
```

```tsx
<Tabs defaultValue="tab1">
  <TabsList>
    <TabsTrigger value="tab1">Tab 1</TabsTrigger>
    <TabsTrigger value="tab2">Tab 2</TabsTrigger>
    <TabsTrigger value="tab3">Tab 3</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">Content for tab 1</TabsContent>
  <TabsContent value="tab2">Content for tab 2</TabsContent>
  <TabsContent value="tab3">Content for tab 3</TabsContent>
</Tabs>
```

### Line Variant

```tsx
<Tabs defaultValue="tab1">
  <TabsList variant="line">
    <TabsTrigger value="tab1">Overview</TabsTrigger>
    <TabsTrigger value="tab2">Settings</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">Overview content</TabsContent>
  <TabsContent value="tab2">Settings content</TabsContent>
</Tabs>
```

### Vertical Orientation

```tsx
<Tabs defaultValue="tab1" orientation="vertical">
  <TabsList>
    <TabsTrigger value="tab1">Profile</TabsTrigger>
    <TabsTrigger value="tab2">Account</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">Profile settings</TabsContent>
  <TabsContent value="tab2">Account settings</TabsContent>
</Tabs>
```

## Accordion

Collapsible content sections.

```typescript
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@kit/ui/accordion';
```

```tsx
<Accordion type="single" collapsible>
  <AccordionItem value="item-1">
    <AccordionTrigger>Section 1</AccordionTrigger>
    <AccordionContent>
      Content for section 1
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
    <AccordionTrigger>Section 2</AccordionTrigger>
    <AccordionContent>
      Content for section 2
    </AccordionContent>
  </AccordionItem>
</Accordion>
```

### Multiple Open

```tsx
<Accordion type="multiple">
  {/* Multiple items can be open simultaneously */}
</Accordion>
```

## Collapsible

Toggle visibility of content.

```typescript
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@kit/ui/collapsible';
```

```tsx
<Collapsible>
  <CollapsibleTrigger>
    <Button variant="ghost">
      Toggle Content
      <ChevronDown className="h-4 w-4" />
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent>
    Hidden content revealed on toggle
  </CollapsibleContent>
</Collapsible>
```

## Scroll Area

Custom scrollbar container.

```typescript
import { ScrollArea } from '@kit/ui/scroll-area';
```

```tsx
<ScrollArea className="h-72 w-48">
  <div className="p-4">
    {/* Long content that needs scrolling */}
  </div>
</ScrollArea>
```

## Aspect Ratio

Maintain aspect ratio for content.

```typescript
import { AspectRatio } from '@kit/ui/aspect-ratio';
```

```tsx
<AspectRatio ratio={16 / 9}>
  <img
    src="/image.jpg"
    alt="Image"
    className="h-full w-full object-cover"
  />
</AspectRatio>
```

## Common Pitfalls

- **Tabs without default value**: Always set `defaultValue` on Tabs, or use controlled `value` prop. Missing defaults cause hydration mismatches.
- **Accordion value type mismatch**: Single mode uses `string`, multiple mode uses `string[]`. Match your state type accordingly.
- **Page layout without sidebar width**: Sidebar needs explicit width via className or the layout shifts unexpectedly.
- **Card nested incorrectly**: CardHeader, CardContent, CardFooter must be direct children of Card for proper spacing.
- **ScrollArea height**: ScrollArea needs a fixed height to enable scrolling. Without `className="h-72"` or similar, it expands to fit content.

{% faq
   title="Frequently Asked Questions"
   items=[
     {"question": "How do I make tabs work with URL routing?", "answer": "Use controlled value prop synced with URL params. Read the param on mount, update URL in onValueChange handler."},
     {"question": "Can I nest Cards inside Cards?", "answer": "Yes, but consider using Card with size='sm' for nested cards to maintain visual hierarchy without too much padding."},
     {"question": "How do I make Accordion items open by default?", "answer": "Pass the item's value to defaultValue prop: defaultValue='item-1'. For multiple, use defaultValue={['item-1', 'item-2']}."},
     {"question": "What's the difference between Accordion and Collapsible?", "answer": "Accordion manages multiple items with mutual exclusivity (single mode). Collapsible is for a single expandable section."},
     {"question": "How do I add actions to Card header?", "answer": "Use CardAction component inside CardHeader: <CardHeader><CardTitle>...</CardTitle><CardAction><Button /></CardAction></CardHeader>"}
   ]
/%}

---

**Next:** [Navigation →](./navigation)
