2:I[7012,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],"MarkdownRenderer"] 4:I[9856,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],""] 5:I[4126,[],""] 7:I[9630,[],""] 8:I[4278,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"HeadingProvider"] 9:I[1476,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Header"] a:I[3167,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Sidebar"] b:I[7409,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"PageFrame"] 3:T1a1b, # 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: ```bash # In apps/web-app/ cat .env.local # Should have VITE_API_URL, etc. ``` **Common Fixes:** ```bash # 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: ```javascript // In browser console console.log(import.meta.env.VITE_API_URL); ``` 3. Test API directly: ```bash curl -X GET http://localhost:8000/health ``` 4. 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: ```typescript useEffect(() => { console.log("Effect triggered, deps:", someDependency); }, [someDependency]); ``` 4. Check for mutations: ```typescript // BAD - mutates state directly state.items.push(newItem); // GOOD - creates new array setState((prev) => ({ ...prev, items: [...prev.items, newItem] })); ``` **Common Patterns:** ```typescript // 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: ```typescript // Wrap pure components export const ExpensiveComponent = React.memo(({ data }) => { // ... }); ``` 4. Use useMemo for expensive computations: ```typescript const processedData = useMemo(() => { return expensiveComputation(rawData); }, [rawData]); ``` 5. Virtualize long lists: ```typescript import { FixedSizeList } from 'react-window'; {Row} ``` **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:** ```bash # Check for type errors pnpm tsc --noEmit # Common fixes: # - Add missing types # - Fix import paths # - Update @types/* packages ``` **Vite Build Errors:** ```bash # 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:** ```bash # 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 | Tool | Usage | | -------- | ----------------------------- | | Console | JavaScript errors, logs | | Network | API calls, assets loading | | Elements | DOM inspection, CSS debugging | | Sources | Breakpoints, step debugging | | Profiler | Performance analysis | | Memory | Memory leaks, heap snapshots | ### React DevTools - Component tree inspection - Props and state viewing - Profiler for render performance - Hook inspection ### VS Code ```json // .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 | Error | Cause | Fix | | -------------------------------------- | ---------------------------------------- | -------------------------------------------------- | | `Cannot read properties of undefined` | Accessing nested prop without null check | Optional chaining: `obj?.nested?.prop` | | `Objects are not valid as React child` | Rendering object directly | Use `JSON.stringify()` or access specific property | | `Each child should have unique key` | Missing key prop in list | Add `key={item.id}` to list items | | `Maximum update depth exceeded` | Infinite re-render loop | Check useEffect dependencies | | `Failed to fetch` | Network/CORS error | Check API URL and CORS config | --- ## Related Documentation - [Debugging Overview](./DEBUGGING_OVERVIEW.md) - [Frontend Architecture](../FRONTEND_ARCHITECTURE.md) - [Design Tokens](../../packages/design-tokens/) 6:["slug","debugging/DEBUGGING_FRONTEND","c"] 0:["X7oMT3VrOffzp0qvbeOas",[[["",{"children":["docs",{"children":[["slug","debugging/DEBUGGING_FRONTEND","c"],{"children":["__PAGE__?{\"slug\":[\"debugging\",\"DEBUGGING_FRONTEND\"]}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["docs",{"children":[["slug","debugging/DEBUGGING_FRONTEND","c"],{"children":["__PAGE__",{},[["$L1",["$","div",null,{"children":[["$","div",null,{"className":"mb-6 flex items-center justify-between gap-4","children":[["$","div",null,{"children":[["$","p",null,{"className":"text-sm text-gray-500 dark:text-gray-400","children":"Docs / Raw"}],["$","h1",null,{"className":"text-3xl font-bold text-gray-900 dark:text-white","children":"Frontend Debugging Guide"}],["$","p",null,{"className":"text-sm text-gray-600 dark:text-gray-400","children":["Sourced from"," ",["$","code",null,{"className":"font-mono text-xs","children":["docs/","debugging/DEBUGGING_FRONTEND.md"]}]]}]]}],["$","a",null,{"href":"https://github.com/mohammednazmy/VoiceAssist/edit/main/docs/debugging/DEBUGGING_FRONTEND.md","target":"_blank","rel":"noreferrer","className":"inline-flex items-center gap-2 rounded-md border border-gray-200 dark:border-gray-700 px-3 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:border-primary-500 dark:hover:border-primary-400 hover:text-primary-700 dark:hover:text-primary-300","children":"Edit on GitHub"}]]}],["$","div",null,{"className":"rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-6","children":["$","$L2",null,{"content":"$3"}]}],["$","div",null,{"className":"mt-6 flex flex-wrap gap-2 text-sm","children":[["$","$L4",null,{"href":"/reference/all-docs","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"← All documentation"}],["$","$L4",null,{"href":"/","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"Home"}]]}]]}],null],null],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children","$6","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/7f586cdbbaa33ff7.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","className":"h-full","children":["$","body",null,{"className":"__className_f367f3 h-full bg-white dark:bg-gray-900","children":[["$","a",null,{"href":"#main-content","className":"skip-to-content","children":"Skip to main content"}],["$","$L8",null,{"children":[["$","$L9",null,{}],["$","$La",null,{}],["$","main",null,{"id":"main-content","className":"lg:pl-64","role":"main","aria-label":"Documentation content","children":["$","$Lb",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]]}]]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Frontend Debugging Guide | Docs | VoiceAssist Docs"}],["$","meta","3",{"name":"description","content":"Debug React web app, admin panel, and frontend issues in VoiceAssist."}],["$","meta","4",{"name":"keywords","content":"VoiceAssist,documentation,medical AI,voice assistant,healthcare,HIPAA,API"}],["$","meta","5",{"name":"robots","content":"index, follow"}],["$","meta","6",{"name":"googlebot","content":"index, follow"}],["$","link","7",{"rel":"canonical","href":"https://assistdocs.asimo.io"}],["$","meta","8",{"property":"og:title","content":"VoiceAssist Documentation"}],["$","meta","9",{"property":"og:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","10",{"property":"og:url","content":"https://assistdocs.asimo.io"}],["$","meta","11",{"property":"og:site_name","content":"VoiceAssist Docs"}],["$","meta","12",{"property":"og:type","content":"website"}],["$","meta","13",{"name":"twitter:card","content":"summary"}],["$","meta","14",{"name":"twitter:title","content":"VoiceAssist Documentation"}],["$","meta","15",{"name":"twitter:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","16",{"name":"next-size-adjust"}]] 1:null