Categories
Category components support any depth of nesting. Use CategoryList for category grids and CategorySubcategories for recursive trees.
Category Grid
Fetch and display categories with link-wrapped cards:
<CategoryList>
<CollectionContent>
<Grid cols={3} gap={4}>
<CollectionView>
<Category href="/categories" class="group">
<div class="relative overflow-hidden rounded-xl aspect-square bg-muted">
<CategoryImage class="w-full h-full object-cover transition-transform group-hover:scale-105" />
<div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
<div class="absolute bottom-3 left-3 right-3">
<CategoryName class="text-white text-sm font-semibold" />
</div>
</div>
</Category>
</CollectionView>
</Grid>
</CollectionContent>
</CategoryList>
Category with href wraps the entire card in a link pointing to {href}/{slug}.
Recursive Tree (Categories → Subcategories)
CategorySubcategories auto-fetches children of the current category. Nest them to any depth:
<CategoryList>
<CollectionView>
<Category class="border rounded-lg p-4">
<CategoryName class="font-bold text-lg" />
<CategorySubcategories>
<div class="ml-8 mt-4 space-y-2 border-l-2 border-muted pl-4">
<CollectionView>
<Category class="py-2">
<CategoryName class="font-medium" />
<CategorySubcategories>
<div class="ml-6 mt-2">
<CollectionView>
<Category class="py-1 text-sm text-muted-foreground">
<CategoryName />
</Category>
</CollectionView>
</div>
</CategorySubcategories>
</Category>
</CollectionView>
</div>
</CategorySubcategories>
</Category>
</CollectionView>
</CategoryList>
Each CategorySubcategories adds one level of depth. Stop nesting when you reach the desired depth — there's no technical limit.
Data Modes
CategoryList accepts a mode prop:
| Mode | Behavior |
|---|---|
"tree" (default) |
Single API call — fetches entire nested tree. CategorySubcategories reads from .children. |
"root" |
Fetches root categories only. Each CategorySubcategories makes its own API call. |
Tree mode is faster for static hierarchies. Root mode lets you paginate per-level and lazy-load.
Single Category Page
When placed on a route like /categories/:slug, Category auto-detects the slug:
<Category class="p-6">
<CategoryImage class="w-24 h-24 rounded-lg object-cover" />
<CategoryName class="text-3xl font-bold" />
<CategoryDescription class="text-muted-foreground" />
</Category>
No categorySlug prop needed — it's read from the router. For an explicit slug, pass categorySlug="electronics".