Skip to content

Next.js: extract page routes (app/page.tsx, pages/*.tsx)#6

Merged
jorgeraad merged 1 commit intocursor/add-kind-field-4943from
cursor/nextjs-page-routes-fc0b
Apr 29, 2026
Merged

Next.js: extract page routes (app/page.tsx, pages/*.tsx)#6
jorgeraad merged 1 commit intocursor/add-kind-field-4943from
cursor/nextjs-page-routes-fc0b

Conversation

@jorgeraad
Copy link
Copy Markdown
Collaborator

Summary

Extends the Next.js extractor to discover user-visible page routes that were previously missing from extraction output. The extractor now scans both App Router and Pages Router page files in addition to the existing API route scanning.

Changes

App Router pages (app/**/page.{tsx,jsx,ts,js})

  • Walks app/ and src/app/ directories for page.{tsx,jsx,ts,js} files
  • Emits each as { method: "GET", handler: "Page", kind: "page" }
  • URL paths derived from directory structure (e.g. app/blog/[slug]/page.tsx/blog/[slug])
  • Explicitly excludes layout files: layout, template, loading, error, not-found, default

Pages Router pages (pages/**/*.{tsx,jsx,ts,js})

  • Walks pages/ and src/pages/ directories
  • Excludes pages/api/ (already handled as API endpoints)
  • Excludes special Next.js files: _app, _document, _error, _middleware
  • Normalizes /index segments: pages/about/index.tsx/about, pages/index.tsx/
  • Emits each as { method: "GET", handler: "Page", kind: "page" }

Test coverage

  • Added nextjs-pages fixture with realistic App Router + Pages Router structure
  • 21 tests covering:
    • App Router page extraction (root, nested, dynamic [slug])
    • Exclusion of all 6 layout file types
    • Pages Router page extraction with /index normalization
    • Exclusion of _app, _document, and api/ directory
    • Coexistence with existing API route extraction
    • Kind and method validation on all page endpoints

Other

  • Added scripts/fixtures to tsconfig.json exclude list (fixture TSX files don't have React types)

Depends on

  • cursor/add-kind-field-4943 (the kind field on EndpointInfo)
Open in Web Open in Cursor 

Extend the Next.js extractor to discover user-visible page routes:

App Router:
- Scan app/**/page.{tsx,jsx,ts,js} files
- Emit as { method: 'GET', handler: 'Page', kind: 'page' }
- Exclude layout files (layout, template, loading, error, not-found, default)

Pages Router:
- Scan pages/**/*.{tsx,jsx,ts,js} files
- Exclude pages/api/ (already handled as API endpoints)
- Exclude special files (_app, _document, _error, _middleware)
- Normalize /index segments (pages/about/index.tsx -> /about)

Also adds test fixture and 21 tests covering all extraction scenarios.

Co-authored-by: Jorge Alejandro Raad <jorge@pensarai.com>
@jorgeraad jorgeraad marked this pull request as ready for review April 29, 2026 19:24
@jorgeraad jorgeraad requested a review from kylejryan April 29, 2026 19:24
Copy link
Copy Markdown
Collaborator

@kylejryan kylejryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jorgeraad jorgeraad merged commit 798100f into cursor/add-kind-field-4943 Apr 29, 2026
2 checks passed
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.

Reviewed by Cursor Bugbot for commit 062b4ec. Configure here.

Comment thread src/extractors/nextjs.ts
// Skip special Next.js files
if (PAGES_ROUTER_SPECIAL_FILES.has(stem)) continue;
// Skip layout-like files in pages router
if (APP_ROUTER_LAYOUT_FILES.has(stem)) continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App Router exclusions incorrectly applied to Pages Router

Low Severity

The APP_ROUTER_LAYOUT_FILES set (layout, template, loading, error, not-found, default) is applied to filter Pages Router files, but these are only reserved names in the App Router. In Pages Router, files like pages/error.tsx or pages/loading.tsx are perfectly valid pages (only _error.tsx with underscore is special). This causes legitimate Pages Router pages with these stems to be silently excluded from extraction results, including in nested paths like pages/dashboard/loading.tsx.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 062b4ec. Configure here.

jorgeraad added a commit that referenced this pull request Apr 29, 2026
* feat: add kind field (api | page | action | websocket) to EndpointInfo

- Add EndpointKind type to types.ts
- Add required kind field to EndpointInfo interface
- Add optional kind? parameter to endpoint() factory (defaults to 'api')
- Set kind: 'action' in server-actions extractor
- Set kind: 'websocket' for FastAPI websocket routes
- Include kind in JSON/NDJSON output for both map and impact formatters
- Export EndpointKind from public API (index.ts)

Co-authored-by: Jorge Alejandro Raad <jorge@pensarai.com>

* feat(nextjs): extract page routes from app/ and pages/ directories (#6)

Extend the Next.js extractor to discover user-visible page routes:

App Router:
- Scan app/**/page.{tsx,jsx,ts,js} files
- Emit as { method: 'GET', handler: 'Page', kind: 'page' }
- Exclude layout files (layout, template, loading, error, not-found, default)

Pages Router:
- Scan pages/**/*.{tsx,jsx,ts,js} files
- Exclude pages/api/ (already handled as API endpoints)
- Exclude special files (_app, _document, _error, _middleware)
- Normalize /index segments (pages/about/index.tsx -> /about)

Also adds test fixture and 21 tests covering all extraction scenarios.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants