VoiceAssist Docs

Frontend Debugging

Troubleshooting guide for web app, React components, and browser issues

stablefrontend2025-11-27human, agent, frontend
debuggingrunbookfrontendreactweb-app

Frontend Debugging Guide

Last Updated: 2025-11-27 Components: apps/web-app/, apps/admin-panel/


Symptoms

Blank Page / App Won't Load

Likely Causes:

  • JavaScript syntax error
  • Missing environment variables
  • Failed API call blocking render
  • CORS issues

Steps to Investigate:

  1. Open Browser DevTools (F12) → Console tab
  2. Look for red error messages
  3. Check Network tab for failed requests
  4. Verify environment variables:
# In apps/web-app/ cat .env.local # Should have VITE_API_URL, etc.

Common Fixes:

# Clear cache and rebuild rm -rf node_modules/.vite pnpm dev # Check for TypeScript errors pnpm tsc --noEmit # Verify dependencies pnpm install

Relevant Code Paths:

  • apps/web-app/src/main.tsx - Entry point
  • apps/web-app/src/App.tsx - Root component
  • apps/web-app/vite.config.ts - Build config

API Calls Failing

Likely Causes:

  • Wrong API base URL
  • CORS not configured
  • Auth token expired/missing
  • Network connectivity

Steps to Investigate:

  1. Check Network tab in DevTools:

    • Filter by XHR/Fetch
    • Look at request headers (Authorization present?)
    • Check response status and body
  2. Verify API URL:

// In browser console console.log(import.meta.env.VITE_API_URL);
  1. Test API directly:
curl -X GET http://localhost:8000/health
  1. Check CORS headers in response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type

Relevant Code Paths:

  • apps/web-app/src/lib/api/ - API client
  • apps/web-app/src/stores/authStore.ts - Auth state
  • packages/api-client/ - Shared HTTP client

State Not Updating

Likely Causes:

  • Direct state mutation instead of setter
  • Missing useEffect dependency
  • Stale closure in callback
  • Zustand/context not wired correctly

Steps to Investigate:

  1. Install React DevTools browser extension
  2. Inspect component state
  3. Add console.log in useEffect:
useEffect(() => { console.log("Effect triggered, deps:", someDependency); }, [someDependency]);
  1. Check for mutations:
// BAD - mutates state directly state.items.push(newItem); // GOOD - creates new array setState((prev) => ({ ...prev, items: [...prev.items, newItem] }));

Common Patterns:

// Correct useEffect dependencies useEffect(() => { fetchData(); }, [fetchData]); // Include the function if it's a dependency // Use useCallback for stable function references const fetchData = useCallback(async () => { // ... }, [dependency]);

Relevant Code Paths:

  • apps/web-app/src/stores/ - Zustand stores
  • apps/web-app/src/hooks/ - Custom hooks

Slow Rendering / Performance Issues

Likely Causes:

  • Unnecessary re-renders
  • Large lists without virtualization
  • Expensive computations in render
  • Memory leaks

Steps to Investigate:

  1. React DevTools → Profiler tab → Record
  2. Look for components re-rendering frequently
  3. Check for missing React.memo:
// Wrap pure components export const ExpensiveComponent = React.memo(({ data }) => { // ... });
  1. Use useMemo for expensive computations:
const processedData = useMemo(() => { return expensiveComputation(rawData); }, [rawData]);
  1. Virtualize long lists:
import { FixedSizeList } from 'react-window'; <FixedSizeList height={400} itemCount={items.length} itemSize={50} > {Row} </FixedSizeList>

Performance Checklist:

  • Components using React.memo where appropriate
  • useMemo/useCallback for expensive operations
  • Lists virtualized if > 100 items
  • No inline object/array creation in props
  • Images lazy-loaded

Build Errors

TypeScript Errors:

# Check for type errors pnpm tsc --noEmit # Common fixes: # - Add missing types # - Fix import paths # - Update @types/* packages

Vite Build Errors:

# Clear cache rm -rf node_modules/.vite dist # Check for circular imports # Look for "Circular dependency detected" warnings # Verify vite.config.ts aliases match tsconfig.json paths

ESLint Errors:

# Run linter pnpm lint # Auto-fix what's possible pnpm lint --fix

Browser-Specific Issues

Safari

  • WebSocket connections may need explicit protocol
  • AudioContext requires user interaction to start
  • Date parsing differs from Chrome

Firefox

  • Stricter CORS enforcement
  • Different CSS rendering in some cases

Mobile Browsers

  • Touch events vs click events
  • Viewport height issues (100vh)
  • Keyboard pushing content

Debugging Tools

Browser DevTools

ToolUsage
ConsoleJavaScript errors, logs
NetworkAPI calls, assets loading
ElementsDOM inspection, CSS debugging
SourcesBreakpoints, step debugging
ProfilerPerformance analysis
MemoryMemory leaks, heap snapshots

React DevTools

  • Component tree inspection
  • Props and state viewing
  • Profiler for render performance
  • Hook inspection

VS Code

// .vscode/launch.json for debugging { "type": "chrome", "request": "launch", "name": "Debug Web App", "url": "http://localhost:5173", "webRoot": "${workspaceFolder}/apps/web-app/src" }

Common Error Messages

ErrorCauseFix
Cannot read properties of undefinedAccessing nested prop without null checkOptional chaining: obj?.nested?.prop
Objects are not valid as React childRendering object directlyUse JSON.stringify() or access specific property
Each child should have unique keyMissing key prop in listAdd key={item.id} to list items
Maximum update depth exceededInfinite re-render loopCheck useEffect dependencies
Failed to fetchNetwork/CORS errorCheck API URL and CORS config