skills/frontend-qa/page-component-mapper/SKILL.md
Use when investigating any frontend issue before diagnosis or debugging — maps a Next.js route to its full component tree. Resolves "what components render on this page," "show me the component tree for /dashboard," or "trace imports for this route." Produces a ComponentMap artifact with server/client boundaries, props, hooks, data fetching, and styling metadata consumed by all downstream QA skills. Not for diagnosing bugs, fixing code, or generating tests — those are handled by specialist skills after mapping is complete.
npx skillsauth add dtsong/my-claude-setup page-component-mapperInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Given a route, produce a depth-limited component tree with file paths, server/client boundaries, props, hooks, state management, data fetching patterns, and styling metadata. Output a ComponentMap artifact consumed by all downstream skills.
tsconfig.json, package.json, next.config.*.claude/qa-cache/component-maps/ for ComponentMap persistence/dashboard/settings)--depth N--fresh to bypass cache and rebuildapp/{route}/page.tsx or pages/{route}.tsx. Validate that the route contains only alphanumeric characters, hyphens, underscores, forward slashes, and brackets (for dynamic segments like [id]). Reject routes containing .., shell metacharacters, or null bytes.Copy this checklist and update as you complete each step:
Progress:
- [ ] Step 0: Check Cache
- [ ] Step 1: Resolve tsconfig Path Aliases
- [ ] Step 2: Identify Route Entry Points
- [ ] Step 3: Trace Imports (Depth-Limited)
- [ ] Step 4: Classify Completeness
- [ ] Step 5: Persist and Present
Note: If you've lost context of previous steps (e.g., after context compaction), check the progress checklist above. Resume from the last unchecked item. Re-read relevant reference files if needed.
.claude/qa-cache/component-maps/{route-slug}.json.references/caching-protocol.md.Using cached map ({age} old, {N} components, completeness: {level}) | --fresh to rebuild--fresh flag provided, skip cache entirely.tsconfig.json at the project root. If it has an extends field, read the parent config too.compilerOptions.paths and compilerOptions.baseUrl.{ "@/*": "./src/*", "~/lib/*": "./lib/*" }.tsconfig.json is missing, warn the user and proceed with relative-path-only resolution.App Router (default -- app/ directory exists):
app/{route}/page.tsx (or .ts, .jsx, .js).layout.tsx, loading.tsx, error.tsx, not-found.tsx in the same directory and parent directories up to app/layout.tsx.Pages Router (fallback -- pages/ directory, no app/):
pages/{route}.tsx (or pages/{route}/index.tsx).pages/_app.tsx and pages/_document.tsx.getServerSideProps or getStaticProps exports.Default depth: 3 levels from route entry. Override with --depth N.
For each file, starting from the entry points found in Step 2:
'use client' or 'use server' directives../Button): try .tsx, .ts, .jsx, .js, /index.tsx, /index.ts@/components/Button): resolve using the Step 1 lookup table, then try extensionsreact, next/link, @radix-ui/*): record as external, stop tracingnext/dynamic(() => import(...)), React.lazy): trace literal paths, flag isDynamic: trueimport { X } from './components'): follow re-export through index files, cap at 5 levelsreferences/import-tracing-protocol.md.displayName: the component function/const nameboundary: "server" (has 'use server' or in app/ without directive), "client" (has 'use client'), "shared" (no directive, outside app/)props: from TypeScript type annotation on the component parameterhooks: all useXxx( callsstateManagement: imports from zustand, jotai, recoil, @tanstack/react-query, or React context usagedataFetching: fetch() calls, server actions, tRPC calls, React Query hooks, SWR hooksstyling_approach: based on import type (.module.css -> css-modules, tailwind classes in JSX -> tailwind)has_conditional_classes: clsx(, cn(, classNames(, or ternary in classNamedesign_system_component: true if imported from a known UI libraryaccepts_className_prop: true if props type includes classNamelayout_role: infer from file location and component nameunresolved: true, unresolvedReason: "depth-limit"."full": unresolvedImports array is empty"shallow": all unresolved entries have reason "depth-limit""partial": any unresolved entry has a non-depth reason ("dynamic-computed", "barrel-depth-exceeded", "not-found")cachedFiles array..claude/qa-cache/component-maps/{route-slug}.json.Component Map: /dashboard/settings (depth 3, shallow)
Entry: app/dashboard/settings/page.tsx [server]
Layout: app/dashboard/layout.tsx [server]
23 components mapped | 4 unresolved (depth-limit) | 2 external (shadcn)
Server (8): SettingsPage, SettingsLayout, AccountSection, ...
Client (12): ThemeToggle, NotificationForm, ProfileEditor, ...
Shared (3): Button, Card, Input
Data flow: 2 server actions, 1 React Query hook, 3 prop chains
Hooks: useState(5), useEffect(3), useForm(2), useQuery(1)
The ComponentMap JSON follows the schema in the design document. Key fields:
{
"version": "1.0",
"route": "/dashboard/settings",
"depth": 3,
"completeness": "shallow",
"framework": { "name": "next", "routerType": "app", "version": "14.1.0" },
"entryComponent": {
"filePath": "/abs/path/app/dashboard/settings/page.tsx",
"displayName": "SettingsPage",
"boundary": "server",
"imports": [{ "targetPath": "...", "importType": "component" }]
},
"unresolvedImports": [{ "sourcePath": "...", "importSpecifier": "./DeepChild", "reason": "depth-limit" }],
"cachedFiles": ["..."]
}
Pass the ComponentMap artifact path to qa-coordinator. The map contains the full component tree with boundary, hooks, dataFetching, and styling_approach fields consumed by ui-bug-investigator and css-layout-debugger.
| Path | Load Condition | Content Summary |
|------|---------------|-----------------|
| references/caching-protocol.md | Step 0, when cache file exists | Cache validity rules, TTL, invalidation triggers |
| references/import-tracing-protocol.md | Step 3, always | Path alias resolution, barrel handling, dynamic imports, boundary rules |
development
Use when planning implementation steps, deciding commit format, or structuring development approach. Provides brainstorm-plan-implement flow with conventional commits. Triggers on 'how should I approach this', 'commit format'.
development
Security audit checklist for web applications. Use when reviewing, auditing, or hardening a web app's security posture. Covers rate limiting, auth headers, IP blocking, CORS, security middleware, input validation, file upload limits, ORM usage, and password hashing. Triggers on requests like "review security", "harden this app", "security audit", "check for vulnerabilities", or when building/reviewing API endpoints.
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
development
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.