
Advanced Patterns and Techniques in v0
Take your v0 development to the next level with advanced patterns and architectural techniques.
Master advanced techniques and architectural patterns to build sophisticated, scalable applications with v0.
Advanced Component Patterns
Compound Components
Create flexible, composable component APIs:
```tsx
// components/dropdown.tsx
'use client'
import { createContext, useContext, useState } from 'react'
const DropdownContext = createContext<any>(null)
export function Dropdown({ children }) {
const [isOpen, setIsOpen] = useState(false)
return (
<DropdownContext.Provider value={{ isOpen, setIsOpen }}>
<div className="relative">{children}</div>
</DropdownContext.Provider>
)
}
export function DropdownTrigger({ children }) {
const { setIsOpen } = useContext(DropdownContext)
return (
<button onClick={() => setIsOpen((prev) => !prev)}>
{children}
</button>
)
}
export function DropdownMenu({ children }) {
const { isOpen } = useContext(DropdownContext)
if (!isOpen) return null
return (
<div className="absolute top-full mt-2 bg-white shadow-lg rounded-lg">
{children}
</div>
)
}
export function DropdownItem({ children, onClick }) {
const { setIsOpen } = useContext(DropdownContext)
return (
<button
onClick={() => {
onClick?.()
setIsOpen(false)
}}
className="block w-full text-left px-4 py-2 hover:bg-gray-100"
>
{children}
</button>
)
}
// Usage
<Dropdown>
<DropdownTrigger>Options</DropdownTrigger>
<DropdownMenu>
<DropdownItem onClick={handleEdit}>Edit</DropdownItem>
<DropdownItem onClick={handleDelete}>Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
```
Render Props Pattern
Share logic between components:
```tsx
function DataFetcher({ url, children }) {
const [data, setData] = useState(null)
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then(setData)
.catch(setError)
.finally(() => setIsLoading(false))
}, [url])
return children({ data, isLoading, error })
}
// Usage
<DataFetcher url="/api/users">
{({ data, isLoading, error }) => {
if (isLoading) return <Spinner />
if (error) return <Error message={error.message} />
return <UserList users={data} />
}}
</DataFetcher>
```
Custom Hooks for Logic Reuse
```tsx
// hooks/use-pagination.ts
export function usePagination(items, itemsPerPage = 10) {
const [currentPage, setCurrentPage] = useState(1)
const totalPages = Math.ceil(items.length / itemsPerPage)
const startIndex = (currentPage - 1) * itemsPerPage
const endIndex = startIndex + itemsPerPage
const currentItems = items.slice(startIndex, endIndex)
const goToPage = (page: number) => {
setCurrentPage(Math.max(1, Math.min(page, totalPages)))
}
return {
currentItems,
currentPage,
totalPages,
goToPage,
nextPage: () => goToPage(currentPage + 1),
prevPage: () => goToPage(currentPage - 1),
hasNext: currentPage < totalPages,
hasPrev: currentPage > 1,
}
}
```
Advanced Code Organization
Feature-Based Architecture
```
app/
├── (marketing)/
│ ├── page.tsx
│ ├── about/
│ └── pricing/
├── (dashboard)/
│ ├── layout.tsx
│ ├── dashboard/
│ ├── settings/
│ └── analytics/
├── api/
│ ├── auth/
│ ├── users/
│ └── products/
features/
├── auth/
│ ├── components/
│ ├── hooks/
│ ├── lib/
│ └── types.ts
├── products/
│ ├── components/
│ ├── hooks/
│ ├── lib/
│ └── types.ts
lib/
├── api-client.ts
├── utils.ts
├── constants.ts
└── validators.ts
```
Shared Type Definitions
```tsx
// types/database.ts
export interface User {
id: string
email: string
name: string
role: 'admin' | 'user'
createdAt: string
}
export interface Product {
id: string
name: string
price: number
category: string
}
// types/api.ts
export type ApiResponse<T> = {
data: T
error?: never
} | {
data?: never
error: string
}
```
Performance Optimization Patterns
Optimistic Updates
```tsx
'use client'
import { useOptimistic } from 'react'
export default function TodoList({ todos }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo) => [...state, { ...newTodo, sending: true }]
)
async function createTodo(formData: FormData) {
const newTodo = { id: Date.now(), text: formData.get('text') }
addOptimisticTodo(newTodo)
await saveTodoToDatabase(newTodo)
}
return (
<form action={createTodo}>
<input name="text" />
<button type="submit">Add</button>
<ul>
{optimisticTodos.map((todo) => (
<li key={todo.id} className={todo.sending ? 'opacity-50' : ''}>
{todo.text}
</li>
))}
</ul>
</form>
)
}
```
Memoization Strategies
```tsx
import { useMemo, useCallback } from 'react'
function ExpensiveComponent({ data, filters }) {
// Memoize expensive calculations
const filteredData = useMemo(() => {
return data.filter((item) =>
filters.every((filter) => filter(item))
)
}, [data, filters])
// Memoize callbacks passed to children
const handleItemClick = useCallback((id: string) => {
console.log('Clicked:', id)
}, [])
return (
<div>
{filteredData.map((item) => (
<Item key={item.id} data={item} onClick={handleItemClick} />
))}
</div>
)
}
// Memoize the component itself
export default React.memo(ExpensiveComponent)
```
Error Handling Patterns
Global Error Boundary
```tsx
// app/error.tsx
'use client'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// Log error to monitoring service
console.error('[v0] Error:', error)
}, [error])
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}
```
Async Error Handling
```tsx
async function handleSubmit(formData: FormData) {
try {
const result = await submitData(formData)
if (!result.success) {
throw new Error(result.error)
}
revalidatePath('/dashboard')
redirect('/dashboard')
} catch (error) {
if (error instanceof ValidationError) {
return { errors: error.errors }
}
if (error instanceof AuthError) {
redirect('/login')
}
// Log unexpected errors
console.error('[v0] Unexpected error:', error)
throw error
}
}
```
Advanced Routing Patterns
Parallel Routes
```tsx
// app/dashboard/@analytics/page.tsx
export default function Analytics() {
return <AnalyticsDashboard />
}
// app/dashboard/@team/page.tsx
export default function Team() {
return <TeamOverview />
}
// app/dashboard/layout.tsx
export default function DashboardLayout({ children, analytics, team }) {
return (
<div className="grid grid-cols-2 gap-4">
<div>{analytics}</div>
<div>{team}</div>
<div className="col-span-2">{children}</div>
</div>
)
}
```
Intercepting Routes
```tsx
// app/@modal/(.)photo/[id]/page.tsx
export default function PhotoModal({ params }) {
const router = useRouter()
return (
<dialog open onClose={() => router.back()}>
<Photo id={params.id} />
</dialog>
)
}
```
Middleware Patterns
```tsx
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Authentication check
const token = request.cookies.get('token')
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url))
}
// Add custom headers
const response = NextResponse.next()
response.headers.set('x-custom-header', 'value')
// Rate limiting (simple example)
const ip = request.ip ?? 'unknown'
// Implement rate limiting logic here
return response
}
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*'],
}
```
Monorepo with Turborepo
```json
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/", "dist/"]
},
"test": {
"dependsOn": ["build"],
"outputs": []
},
"lint": {
"outputs": []
},
"dev": {
"cache": false
}
}
}
```
These advanced patterns enable you to build enterprise-grade, scalable applications with v0 that are maintainable and performant.
Need Help with Your v0 Project?
Our team of v0 experts is ready to help you build amazing applications with cutting-edge AI technology.
Get in Touch