# Component Development Guidelines This document covers component development patterns including Server vs Client components, semantic HTML, and UI best practices. ## Server vs Client Components ### Default to Server Components Next.js App Router defaults to Server Components. Use them for: - Data fetching - Accessing backend resources directly - Keeping sensitive data on the server - Reducing client-side JavaScript ```typescript // app/(app)/dashboard/page.tsx (Server Component) import { DashboardStats } from '@/modules/dashboard/components'; export default async function DashboardPage() { // Can fetch data directly const stats = await fetchDashboardStats(); return (

Dashboard

); } ``` ### When to Use Client Components Add `'use client'` directive only when you need: - Event handlers (onClick, onChange, etc.) - useState, useEffect, or other React hooks - Browser-only APIs (localStorage, window) - Class components with lifecycle methods ```typescript 'use client'; import { useState } from 'react'; export function Counter() { const [count, setCount] = useState(0); return ( ); } ``` ### Composition Pattern Keep Server Components at the top, push Client Components down: ```typescript // Server Component (page.tsx) import { ProductList } from './ProductList'; import { FilterSidebar } from './FilterSidebar'; // Client export default async function ProductsPage() { const products = await fetchProducts(); return (
{/* Client component for interactivity */} {/* Can be server or client */}
); } ``` ### Passing Server Data to Client Components ```typescript // Server Component export default async function Page() { const initialData = await fetchData(); return ; } // Client Component 'use client'; export function InteractiveWidget({ initialData }: { initialData: Data }) { const [data, setData] = useState(initialData); // Interactive logic... } ``` ## Semantic HTML ### Use Proper Elements ```typescript // Bad: div for everything
Click me
Item 1
Item 2
// Good: semantic elements ``` ### Button vs Div Always use ` ``` ### Form Elements ```typescript // Bad: Missing labels, wrong elements
Email
// Good: Proper form structure
{error && }
``` ### Navigation ```typescript // Bad
router.push('/about')}>About
// Good About // For programmatic navigation with button appearance About ``` ## Next.js Image Component ### Always Use next/image ```typescript // Bad: Raw img tag Hero // Good: Optimized Image component import Image from 'next/image'; Hero image ``` ### Responsive Images ```typescript // Fill container
Banner
``` ### Remote Images Configure domains in `next.config.js`: ```javascript // next.config.js module.exports = { images: { remotePatterns: [ { protocol: 'https', hostname: 'images.example.com', }, ], }, }; ``` ## Command Palette (cmdk) ### Basic Implementation ```typescript 'use client'; import { Command } from 'cmdk'; import { useState, useEffect } from 'react'; export function CommandPalette() { const [open, setOpen] = useState(false); // Toggle with keyboard shortcut useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { e.preventDefault(); setOpen((open) => !open); } }; document.addEventListener('keydown', down); return () => document.removeEventListener('keydown', down); }, []); return ( No results found. router.push('/dashboard')}> Go to Dashboard router.push('/settings')}> Go to Settings Create New Order ); } ``` ### With Search Results ```typescript export function SearchCommandPalette() { const [search, setSearch] = useState(''); const { data: results, isLoading } = useSearch(search); return ( {isLoading && Searching...} No results found. {results?.map((item) => ( handleSelect(item)} > {item.title} ))} ); } ``` ## Styling with Tailwind ### Component Styling Pattern ```typescript // Use className for styling export function Card({ children, className, }: { children: ReactNode; className?: string; }) { return (
{children}
); } ``` ### Conditional Styles ```typescript import { cn } from '@/lib/utils'; export function Button({ variant = 'primary', size = 'md', className, ...props }: ButtonProps) { return ( ); } ``` ### ARIA Labels ```typescript ``` ## Best Practices 1. **Server First**: Default to Server Components 2. **Semantic HTML**: Use the right element for the job 3. **Optimize Images**: Always use next/image 4. **Accessibility**: Include ARIA labels and keyboard support 5. **Type Props**: Define TypeScript interfaces for all props 6. **Composition**: Break large components into smaller pieces ## Anti-Patterns - Using `div` for buttons and links - Using `img` instead of `next/image` - Adding `'use client'` at the top of every file - Inline styles instead of Tailwind classes - Missing accessibility attributes - Components with too many responsibilities