🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

NextJS Frontend Development + Integration

by @wing8169

Generate production-ready Next.js projects with TypeScript, Tailwind CSS, shadcn/ui, and API integration. Use when the user asks to build, create, develop, or scaffold a Next.js application, web app, full-stack project, or frontend with backend integration. Prioritizes modern stack (Next.js 14+, TypeScript, shadcn/ui, axios, react-query) and best practices. Also triggers on requests to add features, integrate APIs, or extend existing Next.js projects.

Versionv0.1.1
Downloads3,129
Installs33
TERMINAL
clawhub install frontend-dev

πŸ“– About This Skill


name: ui-development description: Generate production-ready Next.js projects with TypeScript, Tailwind CSS, shadcn/ui, and API integration. Use when the user asks to build, create, develop, or scaffold a Next.js application, web app, full-stack project, or frontend with backend integration. Prioritizes modern stack (Next.js 14+, TypeScript, shadcn/ui, axios, react-query) and best practices. Also triggers on requests to add features, integrate APIs, or extend existing Next.js projects.

UI Development

Generate production-ready Next.js projects from natural language, with shadcn/ui components, API integration, type safety, and modern tooling.

Quick Start (TL;DR)

Fast path for simple projects: 1. Create Next.js app β†’ 2. Install shadcn/ui β†’ 3. Build UI β†’ 4. Start with PM2 β†’ 5. Screenshot review β†’ 6. Done

Live preview: Projects run on PM2 (port 3002), accessible at http://localhost:3002 or via nginx proxy if configured.

Default workflow: All projects use PM2 for dev server management (prevents port conflicts, ensures single instance).

Requirements & Optional Features

Required Dependencies

  • Node.js 18+ and npm/yarn/pnpm
  • Git (for project initialization)
  • Optional Features (user can decline)

    #### 1. Auto-Revision with Visual Review (requires Chromium)

  • What it does: Takes screenshots during development to visually review designs and auto-fix issues
  • Installation: sudo apt-get install chromium-browser (Debian/Ubuntu)
  • Privileges: Read/write access to project files, execute chromium in headless mode
  • If declined: Manual review only (you describe, user verifies)
  • #### 2. Live Preview Server (requires Nginx)

  • What it does: Serves project on external port for live preview during development (useful for mobile testing or remote access)
  • Installation: sudo apt-get install nginx
  • How it works: PM2 runs dev server on port 3002, nginx proxies it to chosen external port
  • Nginx config template:
  •   # /etc/nginx/sites-available/
      server {
        listen ;  # e.g., 3001, 8081, etc.
        server_name _;
        
        location / {
          proxy_pass http://localhost:3002;  # PM2 dev server
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
        }
      }
      
  • Enable: sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ && sudo systemctl reload nginx
  • If declined: Access directly via http://localhost:3002 (PM2 port)
  • Before starting, ask user if they want to enable optional features.

    Common Project Types

    Quick reference for typical requests:

  • Dashboard/Admin Panel β†’ Use (dashboard) route group, shadcn data tables, charts
  • Landing Page β†’ Single app/page.tsx, hero section, features grid, testimonials
  • Todo/Task App β†’ shadcn checkbox, input, button; local state or API
  • Blog/CMS β†’ Dynamic routes app/blog/[slug]/page.tsx, markdown support
  • E-commerce β†’ Product catalog, cart state (Zustand), checkout flow
  • SaaS App β†’ Auth ((auth) group), protected routes, subscription logic
  • Portfolio β†’ Projects grid, contact form, image gallery
  • Form-heavy App β†’ React Hook Form + Zod validation, shadcn form components
  • Ask user: What type of project are you building? (helps determine structure and components)

    Tech Stack

    Core:

  • Next.js 14+ (App Router)
  • TypeScript
  • Tailwind CSS v3
  • shadcn/ui (recommended UI component library)
  • ESLint + Prettier
  • API Integration (default):

  • axios (HTTP client)
  • @tanstack/react-query (data fetching, caching, state management)
  • Optional (based on needs):

  • Zustand (client-side state management)
  • Zod (runtime validation)
  • next-auth (authentication)
  • Prisma (database ORM)
  • Project Structure

    Industry-standard Next.js 14+ App Router structure with feature-based organization:

    /
    β”œβ”€β”€ app/                                # Next.js 14 App Router
    β”‚   β”œβ”€β”€ (auth)/                         # Route group (auth pages)
    β”‚   β”‚   β”œβ”€β”€ login/
    β”‚   β”‚   β”‚   └── page.tsx
    β”‚   β”‚   β”œβ”€β”€ register/
    β”‚   β”‚   β”‚   └── page.tsx
    β”‚   β”‚   └── layout.tsx                  # Auth-specific layout
    β”‚   β”œβ”€β”€ (dashboard)/                    # Route group (protected pages)
    β”‚   β”‚   β”œβ”€β”€ dashboard/
    β”‚   β”‚   β”‚   β”œβ”€β”€ page.tsx
    β”‚   β”‚   β”‚   └── loading.tsx
    β”‚   β”‚   β”œβ”€β”€ profile/
    β”‚   β”‚   β”‚   └── page.tsx
    β”‚   β”‚   β”œβ”€β”€ settings/
    β”‚   β”‚   β”‚   └── page.tsx
    β”‚   β”‚   └── layout.tsx                  # Dashboard layout with sidebar
    β”‚   β”œβ”€β”€ api/                            # API routes
    β”‚   β”‚   β”œβ”€β”€ auth/
    β”‚   β”‚   β”‚   └── [...nextauth]/route.ts
    β”‚   β”‚   └── users/
    β”‚   β”‚       └── route.ts
    β”‚   β”œβ”€β”€ layout.tsx                      # Root layout
    β”‚   β”œβ”€β”€ page.tsx                        # Home page
    β”‚   β”œβ”€β”€ loading.tsx                     # Root loading UI
    β”‚   β”œβ”€β”€ error.tsx                       # Root error boundary
    β”‚   β”œβ”€β”€ not-found.tsx                   # 404 page
    β”‚   └── providers.tsx                   # Client providers (React Query, etc.)
    β”‚
    β”œβ”€β”€ components/
    β”‚   β”œβ”€β”€ ui/                             # shadcn/ui components (auto-generated)
    β”‚   β”‚   β”œβ”€β”€ button.tsx
    β”‚   β”‚   β”œβ”€β”€ card.tsx
    β”‚   β”‚   β”œβ”€β”€ input.tsx
    β”‚   β”‚   β”œβ”€β”€ form.tsx
    β”‚   β”‚   └── ...
    β”‚   β”œβ”€β”€ layout/                         # Layout components
    β”‚   β”‚   β”œβ”€β”€ header.tsx
    β”‚   β”‚   β”œβ”€β”€ footer.tsx
    β”‚   β”‚   β”œβ”€β”€ sidebar.tsx
    β”‚   β”‚   └── mobile-nav.tsx
    β”‚   β”œβ”€β”€ features/                       # Feature-specific components
    β”‚   β”‚   β”œβ”€β”€ auth/
    β”‚   β”‚   β”‚   β”œβ”€β”€ login-form.tsx
    β”‚   β”‚   β”‚   └── register-form.tsx
    β”‚   β”‚   β”œβ”€β”€ dashboard/
    β”‚   β”‚   β”‚   β”œβ”€β”€ stats-card.tsx
    β”‚   β”‚   β”‚   └── recent-activity.tsx
    β”‚   β”‚   └── profile/
    β”‚   β”‚       β”œβ”€β”€ profile-header.tsx
    β”‚   β”‚       └── edit-profile-form.tsx
    β”‚   └── shared/                         # Shared/common components
    β”‚       β”œβ”€β”€ data-table.tsx
    β”‚       β”œβ”€β”€ search-bar.tsx
    β”‚       └── pagination.tsx
    β”‚
    β”œβ”€β”€ lib/                                # Utility functions & configurations
    β”‚   β”œβ”€β”€ api.ts                          # Axios instance + interceptors
    β”‚   β”œβ”€β”€ react-query.ts                  # React Query client config
    β”‚   β”œβ”€β”€ utils.ts                        # Utility functions (cn, formatters)
    β”‚   β”œβ”€β”€ validations.ts                  # Zod schemas
    β”‚   β”œβ”€β”€ constants.ts                    # App constants
    β”‚   └── auth.ts                         # Auth utilities (if using next-auth)
    β”‚
    β”œβ”€β”€ hooks/                              # Custom React hooks
    β”‚   β”œβ”€β”€ use-auth.ts                     # Authentication hook
    β”‚   β”œβ”€β”€ use-user.ts                     # User data hook (React Query)
    β”‚   β”œβ”€β”€ use-posts.ts                    # Posts data hook (React Query)
    β”‚   β”œβ”€β”€ use-media-query.ts              # Responsive design hook
    β”‚   └── use-toast.ts                    # Toast notifications (shadcn)
    β”‚
    β”œβ”€β”€ types/                              # TypeScript type definitions
    β”‚   β”œβ”€β”€ index.ts                        # Common types
    β”‚   β”œβ”€β”€ api.ts                          # API response types
    β”‚   β”œβ”€β”€ user.ts                         # User-related types
    β”‚   └── database.ts                     # Database types (Prisma generated)
    β”‚
    β”œβ”€β”€ actions/                            # Server Actions (Next.js 14+)
    β”‚   β”œβ”€β”€ auth.ts                         # Auth actions
    β”‚   β”œβ”€β”€ user.ts                         # User actions
    β”‚   └── posts.ts                        # Posts actions
    β”‚
    β”œβ”€β”€ config/                             # Configuration files
    β”‚   β”œβ”€β”€ site.ts                         # Site metadata (name, description, etc.)
    β”‚   └── navigation.ts                   # Navigation menu config
    β”‚
    β”œβ”€β”€ prisma/                             # Prisma ORM (if using database)
    β”‚   β”œβ”€β”€ schema.prisma                   # Database schema
    β”‚   └── migrations/                     # Database migrations
    β”‚
    β”œβ”€β”€ public/                             # Static assets
    β”‚   β”œβ”€β”€ images/
    β”‚   β”œβ”€β”€ icons/
    β”‚   └── fonts/
    β”‚
    β”œβ”€β”€ styles/                             # Global styles
    β”‚   └── globals.css                     # Tailwind imports + custom styles
    β”‚
    β”œβ”€β”€ .env.local                          # Environment variables (gitignored)
    β”œβ”€β”€ .env.example                        # Environment variables template
    β”œβ”€β”€ .eslintrc.json                      # ESLint config
    β”œβ”€β”€ .prettierrc                         # Prettier config
    β”œβ”€β”€ components.json                     # shadcn/ui config
    β”œβ”€β”€ next.config.js                      # Next.js config
    β”œβ”€β”€ tailwind.config.ts                  # Tailwind config
    β”œβ”€β”€ tsconfig.json                       # TypeScript config
    β”œβ”€β”€ package.json                        # Dependencies
    └── README.md                           # Project documentation
    

    Directory Purpose

    app/ - Next.js 14 App Router pages and layouts. Use route groups (name) for logical grouping without affecting URLs.

    components/ - All React components, organized by type:

  • ui/ - shadcn/ui components (copy-paste, customizable)
  • layout/ - Shared layout components (header, footer, sidebar)
  • features/ - Feature-specific components (scoped to one feature)
  • shared/ - Reusable components used across features
  • lib/ - Utility functions, configurations, and third-party library setups.

    hooks/ - Custom React hooks, especially React Query hooks for API calls.

    types/ - TypeScript type definitions and interfaces.

    actions/ - Server Actions for form handling and server-side operations (Next.js 14+).

    config/ - App configuration (site metadata, navigation menus, constants).

    prisma/ - Database schema and migrations (if using Prisma).

    public/ - Static files served at root URL.

    styles/ - Global CSS (Tailwind imports + custom styles).

    Workflow

    Keep user informed at every step β€” this is a live build log.

    ⚠️ Important: All projects use PM2 for dev server management (port 3002 by default). This ensures:

  • Only one instance runs at a time (no port conflicts)
  • Easy process management (list/logs/restart/stop)
  • Persistent dev server across terminal sessions
  • Better error logging and debugging
  • Step 1: Project Setup

    Ask:
  • Project name
  • Description/purpose
  • Optional features (chromium review, nginx preview)
  • Create Next.js project:

    npx create-next-app@latest  \
      --typescript \
      --tailwind \
      --app \
      --no-src-dir \
      --import-alias "@/*"
    

    β†’ Message user: "Next.js project initialized βœ“"

    Step 2: Create Directory Structure

    Create all necessary directories following industry best practices:

    cd 

    Create app route groups

    mkdir -p app/\(auth\)/login app/\(auth\)/register mkdir -p app/\(dashboard\)/dashboard app/\(dashboard\)/profile app/\(dashboard\)/settings mkdir -p app/api/auth app/api/users

    Create component directories

    mkdir -p components/ui components/layout components/features components/shared mkdir -p components/features/auth components/features/dashboard components/features/profile

    Create utility directories

    mkdir -p lib hooks types actions config

    Create static asset directories

    mkdir -p public/images public/icons public/fonts

    Create styles directory

    mkdir styles

    Create Prisma directory (if using database)

    mkdir -p prisma

    Create essential config files:

    config/site.ts - Site metadata

    export const siteConfig = {
      name: '',
      description: '',
      url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
      links: {
        github: 'https://github.com/...',
      },
    };
    

    config/navigation.ts - Navigation menu

    export const mainNav = [
      { title: 'Home', href: '/' },
      { title: 'Dashboard', href: '/dashboard' },
      { title: 'Profile', href: '/profile' },
    ];

    export const dashboardNav = [ { title: 'Overview', href: '/dashboard' }, { title: 'Profile', href: '/profile' }, { title: 'Settings', href: '/settings' }, ];

    .env.example - Environment variables template

    NEXT_PUBLIC_APP_URL=http://localhost:3000
    NEXT_PUBLIC_API_BASE_URL=http://localhost:3000/api
    DATABASE_URL=postgresql://...
    NEXTAUTH_SECRET=...
    NEXTAUTH_URL=http://localhost:3000
    

    β†’ Message user: "Directory structure created βœ“"

    Step 3: Install Dependencies

    Core dependencies:

    cd 
    npm install axios @tanstack/react-query
    npm install -D @types/node
    

    shadcn/ui setup (recommended):

    npx shadcn-ui@latest init
    

    This will prompt for configuration. Recommended answers:

  • Style: Default
  • Base color: Slate
  • CSS variables: Yes
  • Install essential shadcn components:

    npx shadcn-ui@latest add button card input label select textarea
    npx shadcn-ui@latest add dropdown-menu dialog sheet tabs
    npx shadcn-ui@latest add table form avatar badge separator toast
    

    Install form dependencies (for shadcn/ui forms):

    npm install react-hook-form @hookform/resolvers zod
    

    Optional (ask user based on needs):

    npm install zustand  # State management
    npm install next-auth  # Authentication
    npm install prisma @prisma/client  # Database ORM
    

    β†’ Message user: "Dependencies + shadcn/ui installed βœ“"

    Step 4: Configure Base Files

    #### lib/api.ts (axios instance)

    import axios from 'axios';

    export const api = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3000/api', timeout: 10000, headers: { 'Content-Type': 'application/json' } });

    // Request interceptor (add auth tokens, etc.) api.interceptors.request.use( (config) => { const token = localStorage.getItem('token'); if (token) config.headers.Authorization = Bearer ${token}; return config; }, (error) => Promise.reject(error) );

    // Response interceptor (handle errors globally) api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // Handle unauthorized } return Promise.reject(error); } );

    #### lib/react-query.ts (query client)

    import { QueryClient } from '@tanstack/react-query';

    export const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, // 1 minute refetchOnWindowFocus: false, retry: 1, }, }, });

    #### app/providers.tsx (wrap app with providers)

    'use client';

    import { QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { queryClient } from '@/lib/react-query';

    export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); }

    Update app/layout.tsx to use Providers.

    β†’ Message user: "Base configuration complete βœ“"

    Step 5: Generate Features

    Ask what features/pages to build. For each feature:

    1. Create route (app//page.tsx) 2. Create components (components/features//) 3. Create API hooks (hooks/use.ts) using react-query 4. Create types (types/.ts) 5. Optionally create API routes (app/api//route.ts)

    Example: User Profile Feature

    // types/user.ts
    export interface User {
      id: string;
      name: string;
      email: string;
    }

    // hooks/useUser.ts import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { api } from '@/lib/api'; import type { User } from '@/types/user';

    export const useUser = (id: string) => { return useQuery({ queryKey: ['user', id], queryFn: async () => { const { data } = await api.get(/users/${id}); return data; }, }); };

    export const useUpdateUser = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (user: Partial) => { const { data } = await api.patch(/users/${user.id}, user); return data; }, onSuccess: (data) => { queryClient.invalidateQueries({ queryKey: ['user', data.id] }); }, }); };

    // app/profile/[id]/page.tsx 'use client';

    import { useUser, useUpdateUser } from '@/hooks/useUser';

    export default function ProfilePage({ params }: { params: { id: string } }) { const { data: user, isLoading, error } = useUser(params.id); const updateUser = useUpdateUser();

    if (isLoading) return

    Loading...
    ; if (error) return
    Error: {error.message}
    ;

    return (

    {user?.name}

    {user?.email}

    ); }

    β†’ Message user after each feature: "Profile page complete βœ“"

    Step 6: Build UI with shadcn/ui Components

    Use shadcn/ui components (already installed) for consistent, accessible UI. Apply Design Principles (see below).

    Example: Profile page with shadcn/ui

    import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
    import { Button } from '@/components/ui/button';
    import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';

    export default function ProfilePage({ params }: { params: { id: string } }) { const { data: user, isLoading } = useUser(params.id);

    if (isLoading) return Loading...;

    return (

    {user?.name[0]}
    {user?.name}

    {user?.email}

    ); }

    When to add more components:

  • Forms β†’ npx shadcn-ui@latest add form input label
  • Data tables β†’ npx shadcn-ui@latest add table
  • Navigation β†’ npx shadcn-ui@latest add navigation-menu
  • Feedback β†’ npx shadcn-ui@latest add toast alert
  • β†’ Message user: "UI built with shadcn/ui βœ“"

    Step 7: Visual Review (if chromium enabled)

    Important: Use PM2 to manage the dev server (ensures only 1 instance runs, prevents port conflicts).

    Start dev server with PM2:

    # Stop any existing instance of this project
    pm2 delete  2>/dev/null || true

    Start with PM2 (port 3002 for nginx proxy)

    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev

    Give PM2 a moment to start

    sleep 2

    Wait for server to be fully ready (critical - avoid white screen screenshots):

    # Wait for "Ready in" message in PM2 logs (usually 5-15 seconds)
    timeout=30
    elapsed=0
    while [ $elapsed -lt $timeout ]; do
      if pm2 logs  --nostream --lines 50 2>/dev/null | grep -q "Ready in"; then
        echo "Server ready!"
        sleep 3  # Extra buffer for module loading
        break
      fi
      sleep 1
      elapsed=$((elapsed + 1))
    done

    Verify server is responding

    if ! curl -s http://localhost:3002 > /dev/null; then echo "Warning: Server not responding on port 3002" pm2 logs --nostream --lines 20 fi

    Take screenshots (requires chromium):

    bash scripts/screenshot.sh "http://localhost:3002" /tmp/review-desktop.png 1400 900
    bash scripts/screenshot.sh "http://localhost:3002" /tmp/review-mobile.png 390 844
    

    Review Checklist (analyze with image tool):

  • βœ… Desktop (1400px): Content centered, proper spacing
  • βœ… Mobile (390px):
  • - No horizontal overflow (content fits within screen) - Text readable (not too small) - Padding appropriate (p-4 not p-24) - Touch targets large enough (min 44x44px) - No content cutting off edges

    If issues found: Fix responsive classes, re-run screenshots.

    Common fixes:

  • Large padding β†’ p-4 md:p-8 lg:p-12
  • Large text β†’ text-2xl md:text-4xl
  • Wide content β†’ Add max-w-full or px-4
  • β†’ Message user: "Review complete, sending preview..."

    Step 8: Environment Setup

    Create .env.local:

    NEXT_PUBLIC_API_BASE_URL=https://api.example.com
    DATABASE_URL=postgresql://...
    NEXTAUTH_SECRET=...
    

    Create .env.example (template for user).

    β†’ Message user: "Environment template created βœ“"

    Step 9: Scripts & Documentation

    Update package.json scripts:

    {
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint",
        "type-check": "tsc --noEmit"
      }
    }
    

    Create README.md with:

  • Setup instructions
  • Environment variables needed
  • Development commands
  • API integration guide
  • β†’ Message user: "Documentation complete βœ“"

    Step 10: Export & Deploy Guidance

    Stop PM2 dev server (if running):

    pm2 delete  2>/dev/null || true
    pm2 save  # Persist PM2 process list
    

    Zip the project:

    cd .. && zip -r /tmp/.zip /
    

    Send via message tool with filePath.

    Provide deployment options:

  • Vercel (recommended): npx vercel
  • Netlify: npm run build && netlify deploy
  • Docker: Provide Dockerfile
  • Self-hosted: Provide systemd service + nginx config
  • β†’ Message user: "Project ready! πŸš€"

    Testing & Live Preview

    Quick Test (during development)

    1. PM2 dev server (always running after Step 7):

    # Check status
    pm2 list

    View logs

    pm2 logs

    Access locally

    curl http://localhost:3002

    2. Live preview URLs:

  • Local access: http://localhost:3002
  • Nginx proxy (if configured): http://:
  • Mobile testing: Use nginx proxy or ngrok/tunneling service
  • 3. Screenshot review (if chromium enabled):

    # Desktop (1400x900)
    bash scripts/screenshot.sh "http://localhost:3002" /tmp/desktop.png 1400 900

    Mobile (390x844)

    bash scripts/screenshot.sh "http://localhost:3002" /tmp/mobile.png 390 844

    End-to-End Testing Workflow

    Full test sequence:

    # 1. Check PM2 status
    pm2 list | grep 

    2. Verify dev server responding

    curl -I http://localhost:3002

    3. Take screenshots for visual verification

    bash scripts/screenshot.sh "http://localhost:3002" /tmp/test-desktop.png 1400 900 bash scripts/screenshot.sh "http://localhost:3002" /tmp/test-mobile.png 390 844

    4. Check logs for errors

    pm2 logs --lines 50 | grep -i error

    5. Test API endpoints (if using API routes)

    curl http://localhost:3002/api/health # Example health check

    6. Production build test

    npm run build && npm run start # Test production build

    7. Type check

    npm run type-check

    Common Testing Scenarios

    Scenario 1: Test responsive design

    # Mobile, tablet, desktop
    for width in 390 768 1400; do
      bash scripts/screenshot.sh "http://localhost:3002" /tmp/screen-${width}.png $width 900
    done
    

    Scenario 2: Test specific page/route

    # Take screenshot of specific route
    bash scripts/screenshot.sh "http://localhost:3002/dashboard" /tmp/dashboard.png 1400 900
    

    Scenario 3: Test after making changes

    # PM2 auto-reloads on file changes, verify in logs
    pm2 logs  --lines 20

    Wait for "compiled successfully" then take new screenshot

    bash scripts/screenshot.sh "http://localhost:3002" /tmp/updated.png 1400 900

    Sharing Preview with User

    Option 1: Screenshots

  • Send desktop + mobile screenshots via message tool
  • User provides feedback, you iterate
  • Option 2: Nginx proxy + external access

  • Set up nginx config (see Optional Features)
  • Share URL: http://:
  • User can test live in browser
  • Option 3: Export & deploy

  • Zip project and send to user
  • User deploys to Vercel/Netlify
  • Test on production URL
  • API Integration Patterns

    Pattern 1: REST API (default)

    Use axios + react-query:

    // hooks/usePosts.ts
    import { useQuery, useMutation } from '@tanstack/react-query';
    import { api } from '@/lib/api';

    export const usePosts = () => { return useQuery({ queryKey: ['posts'], queryFn: async () => { const { data } = await api.get('/posts'); return data; }, }); };

    export const useCreatePost = () => { return useMutation({ mutationFn: async (post: { title: string; body: string }) => { const { data } = await api.post('/posts', post); return data; }, }); };

    Pattern 2: GraphQL (optional)

    Install:

    npm install @apollo/client graphql
    

    Setup Apollo Client, use useQuery and useMutation from Apollo.

    Pattern 3: tRPC (optional)

    For Next.js API routes with type safety:

    npm install @trpc/server @trpc/client @trpc/react-query @trpc/next
    

    Pattern 4: Server Actions (Next.js 14+)

    For form handling without API routes:

    // app/actions.ts
    'use server';

    export async function createPost(formData: FormData) { const title = formData.get('title'); // ... }

    Always ask user which pattern they prefer for their use case.

    Design Principles

    Apply these consistently. These are quality standards.

    Layout & Spacing

  • Consistent Tailwind spacing scale (4, 6, 8, 12, 16, 20, 24)
  • Max content width: max-w-5xl or max-w-6xl
  • Vertical rhythm: py-16 for sections, py-8 for subsections
  • Mobile: minimum px-4 padding
  • Typography

  • Clear hierarchy (h1 β†’ h2 β†’ h3, max 3-4 sizes)
  • Line length: max 65-75 characters (max-w-prose)
  • Font weight contrast (bold headings, regular body)
  • Text color hierarchy (slate-900 β†’ slate-700 β†’ slate-500)
  • Color & Contrast

  • WCAG AA minimum (4.5:1 contrast)
  • Limit palette (1 primary + 1 accent + neutrals)
  • Consistent accent usage (CTAs, links, active states)
  • Responsive Design (Critical)

  • Mobile-first (390px β†’ 768px β†’ 1024px) - Always design for 390px first
  • Responsive padding - Use Tailwind responsive classes:
  • - Mobile: p-4 or px-4 py-6 (never p-24 on mobile!) - Tablet: md:p-8 or md:px-6 md:py-8 - Desktop: lg:p-12 xl:p-24 - Example:
  • Responsive text sizes - Scale down headings on mobile:
  • - Mobile: text-2xl β†’ Desktop: md:text-4xl - Mobile: text-lg β†’ Desktop: md:text-2xl
  • No horizontal overflow - Content must fit within 390px width
  • - Test: Check mobile screenshot for any content cutting off edges - Use max-w-full on containers - Break long words: break-words
  • Touch targets - min 44x44px for buttons/links on mobile
  • Stack on mobile - Grids collapse to single column: grid-cols-1 md:grid-cols-2 lg:grid-cols-3
  • Hamburger menu - Required on mobile for navigation
  • Components (Use shadcn/ui)

  • Icons: Use Lucide React (comes with shadcn/ui), never emoji
  • Buttons: Use
  • Forms: Use shadcn
    with react-hook-form integration
  • Cards: Use component for content sections
  • Dialogs/Modals: Use or components
  • Loading states: Use shadcn component for loading UI
  • Error handling: Use component for error messages
  • Data display: Use component for tabular data

    shadcn/ui benefits: Accessible, customizable, copy-paste friendly, works with Tailwind

    TypeScript Best Practices

  • Strict mode enabled
  • Explicit return types for functions
  • Interface over type for objects
  • Avoid any (use unknown if needed)
  • Use discriminated unions for variants
  • Performance

  • Use Next.js Image component (next/image)
  • Lazy load below-the-fold content
  • Code splitting (dynamic imports)
  • Memoize expensive computations (useMemo, useCallback)
  • Common Patterns

    Form Handling (with shadcn/ui)

    'use client';

    import { zodResolver } from '@hookform/resolvers/zod'; import { useForm } from 'react-hook-form'; import * as z from 'zod'; import { useMutation } from '@tanstack/react-query'; import { Button } from '@/components/ui/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { useToast } from '@/components/ui/use-toast';

    const formSchema = z.object({ name: z.string().min(2, 'Name must be at least 2 characters'), email: z.string().email('Invalid email address'), });

    export default function ContactForm() { const { toast } = useToast(); const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { name: '', email: '' }, });

    const mutation = useMutation({ mutationFn: async (data: z.infer) => { const res = await api.post('/contact', data); return res.data; }, onSuccess: () => { toast({ title: 'Success', description: 'Message sent!' }); form.reset(); }, onError: (error) => { toast({ title: 'Error', description: error.message, variant: 'destructive' }); }, });

    return ( mutation.mutate(data))} className="space-y-4"> ( Name )} /> ( Email )} /> ); }

    Note: Run npx shadcn-ui@latest add form toast and install npm install react-hook-form @hookform/resolvers zod for this pattern.

    Pagination

    const usePaginatedPosts = (page: number) => {
      return useQuery({
        queryKey: ['posts', page],
        queryFn: async () => {
          const { data } = await api.get(/posts?page=${page});
          return data;
        },
        keepPreviousData: true, // Smooth transitions
      });
    };
    

    Infinite Scroll

    import { useInfiniteQuery } from '@tanstack/react-query';

    const useInfinitePosts = () => { return useInfiniteQuery({ queryKey: ['posts'], queryFn: async ({ pageParam = 1 }) => { const { data } = await api.get(/posts?page=${pageParam}); return data; }, getNextPageParam: (lastPage, pages) => lastPage.nextPage, }); };

    Common Mistakes to Avoid

  • ❌ Not wrapping app with QueryClientProvider
  • ❌ Using axios without interceptors (no error handling)
  • ❌ Forgetting loading/error states in components
  • ❌ Not invalidating queries after mutations
  • ❌ Using any instead of proper TypeScript types
  • ❌ Client components when server components would work
  • ❌ Not using Next.js Image component (performance loss)
  • ❌ Missing error boundaries
  • ❌ Hardcoding API URLs (use env vars)
  • ❌ No mobile testing (always check responsive at 390px width)
  • ❌ Large padding on mobile (p-24 = 96px causes overflow on 390px screens)
  • ❌ Not using responsive Tailwind classes (use p-4 md:p-8 lg:p-12)
  • ❌ Horizontal overflow on mobile (content wider than 390px)
  • ❌ Building custom components when shadcn/ui has them (Button, Card, Dialog, etc.)
  • ❌ Using emoji for icons (use Lucide React icons from shadcn/ui)
  • ❌ Not installing @hookform/resolvers and zod before using shadcn forms
  • ❌ Forgetting to add component when using toast notifications
  • ❌ Taking screenshots before dev server is fully ready (causes white screens)
  • ❌ Not waiting for module loading (causes "Module not found" errors in screenshots)
  • Troubleshooting

    White Screen Screenshots

    Problem: Screenshots show blank white page Cause: Dev server not fully initialized before screenshot Solution:
  • Wait for "Ready in" message in dev server logs
  • Add 3-5 second buffer after "Ready" message
  • Verify localhost:3000 loads in browser before taking screenshot
  • Module Not Found Errors

    Problem: React error "Module not found: Can't resolve @tanstack/react-query" Cause: Dev server started before all packages loaded Solution:
  • Restart dev server: pkill -f "next dev" && npm run dev
  • Verify packages in node_modules: ls node_modules/@tanstack/
  • Wait 10-15 seconds after npm install before starting dev server
  • Dev Server Won't Start

    Problem: Port already in use (EADDRINUSE error) Solution (PM2 method):
    # Check what's running
    pm2 list

    Stop the conflicting process

    pm2 delete

    Or check port directly

    lsof -ti:3002

    Kill process on port (if not PM2-managed)

    kill -9 $(lsof -ti:3002)

    Restart with PM2

    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev

    PM2 Process Management

    List all PM2 processes:
    pm2 list
    

    Check logs:

    pm2 logs  --lines 50
    

    Restart a process:

    pm2 restart 
    

    Stop a process:

    pm2 stop 
    

    Delete a process:

    pm2 delete 
    

    Ensure only one instance runs:

    # Always delete before starting
    pm2 delete  2>/dev/null || true
    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev
    

    Common PM2 scenarios:

    1. Project won't start β†’ Check logs: pm2 logs 2. Process keeps restarting β†’ Module missing or port conflict, check logs 3. Changes not reflecting β†’ PM2 auto-reloads, verify in logs: pm2 logs | grep compiled 4. Multiple instances running β†’ Delete all: pm2 delete all && pm2 list 5. Check resource usage β†’ pm2 monit (real-time monitoring) 6. Save PM2 process list β†’ pm2 save (persists across reboots)

    Iteration & Updates

    When user requests changes: 1. Identify affected files 2. Make changes 3. PM2 auto-reloads (no manual restart needed for file changes) 4. Run type check: npm run type-check 5. Verify in logs: pm2 logs --lines 20 6. If chromium enabled: take new screenshot 7. Report changes to user

    Always explain what changed and why.


    Quick Reference Cheat Sheet

    Essential Commands

    # Start dev server
    pm2 delete  2>/dev/null || true
    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev

    Check status

    pm2 list pm2 logs

    Take screenshots

    bash scripts/screenshot.sh "http://localhost:3002" /tmp/desktop.png 1400 900 bash scripts/screenshot.sh "http://localhost:3002" /tmp/mobile.png 390 844

    Test production build

    npm run build && npm run start

    Type check

    npm run type-check

    File Locations

  • Components: components/ui/ (shadcn), components/features/ (custom)
  • Pages: app/*/page.tsx
  • API routes: app/api/*/route.ts
  • Styles: app/globals.css, tailwind.config.ts
  • Config: next.config.ts, .env.local
  • Common shadcn Components

    npx shadcn-ui@latest add button input form card table dialog toast
    

    Live Preview URLs

  • Local: http://localhost:3002
  • Nginx proxy: http://:
  • Mobile testing: Use nginx proxy or ngrok
  • Troubleshooting

    1. Port conflict β†’ pm2 delete then restart 2. White screen β†’ Wait for "Ready in" message (check logs) 3. Module errors β†’ npm install then restart PM2 4. Type errors β†’ npm run type-check 5. Layout breaks β†’ Check responsive classes (p-4 md:p-8 lg:p-12)

    πŸ“‹ Tips & Best Practices

    White Screen Screenshots

    Problem: Screenshots show blank white page Cause: Dev server not fully initialized before screenshot Solution:
  • Wait for "Ready in" message in dev server logs
  • Add 3-5 second buffer after "Ready" message
  • Verify localhost:3000 loads in browser before taking screenshot
  • Module Not Found Errors

    Problem: React error "Module not found: Can't resolve @tanstack/react-query" Cause: Dev server started before all packages loaded Solution:
  • Restart dev server: pkill -f "next dev" && npm run dev
  • Verify packages in node_modules: ls node_modules/@tanstack/
  • Wait 10-15 seconds after npm install before starting dev server
  • Dev Server Won't Start

    Problem: Port already in use (EADDRINUSE error) Solution (PM2 method):
    # Check what's running
    pm2 list

    Stop the conflicting process

    pm2 delete

    Or check port directly

    lsof -ti:3002

    Kill process on port (if not PM2-managed)

    kill -9 $(lsof -ti:3002)

    Restart with PM2

    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev

    PM2 Process Management

    List all PM2 processes:
    pm2 list
    

    Check logs:

    pm2 logs  --lines 50
    

    Restart a process:

    pm2 restart 
    

    Stop a process:

    pm2 stop 
    

    Delete a process:

    pm2 delete 
    

    Ensure only one instance runs:

    # Always delete before starting
    pm2 delete  2>/dev/null || true
    PORT=3002 pm2 start npm --name "" --cwd "$(pwd)" -- run dev
    

    Common PM2 scenarios:

    1. Project won't start β†’ Check logs: pm2 logs 2. Process keeps restarting β†’ Module missing or port conflict, check logs 3. Changes not reflecting β†’ PM2 auto-reloads, verify in logs: pm2 logs | grep compiled 4. Multiple instances running β†’ Delete all: pm2 delete all && pm2 list 5. Check resource usage β†’ pm2 monit (real-time monitoring) 6. Save PM2 process list β†’ pm2 save (persists across reboots)

    BytesAgain
    Discover the best AI agent skills for your workflow.
    Β© 2026 BytesAgain. All rights reserved.
    BytesAgain is an independent skill directory. We index and link to third-party content (ClawHub, GitHub, LobeHub, Dify, etc.) for informational purposes only. All trademarks, skill names, and content are the property of their respective owners. BytesAgain does not claim ownership of any indexed content.