feat(eslint): Add pageExtensions support to no-html-link-for-pages rule
What?
This PR adds support for custom pageExtensions configuration to the @next/next/no-html-link-for-pages ESLint rule.
Why?
Currently, the ESLint rule only recognizes default Next.js page extensions (.js, .jsx, .ts, .tsx) and ignores custom extensions configured via pageExtensions in next.config.js. This causes the linting rule to fail when projects use custom file extensions.
Fixes #53473
How?
Changes Made:
-
packages/eslint-plugin-next/src/utils/url.ts:- Added
buildPageExtensionRegex()helper to generate dynamic regex from extensions array - Updated
parseUrlForPages()to acceptpageExtensionsparameter with default fallback - Updated
parseUrlForAppDir()to acceptpageExtensionsparameter with default fallback - Modified
getUrlFromPagesDirectories()andgetUrlFromAppDirectory()signatures to support custom extensions - Removed hardcoded regex patterns and TODO comments
- Added
-
packages/eslint-plugin-next/src/rules/no-html-link-for-pages.ts:- Added
getPageExtensions()function to readpageExtensionsfromnext.config.js - Integrated pageExtensions reading with support for
.js,.mjs, and.tsconfig files - Passed custom extensions to URL parsing functions
- Maintained backward compatibility with default extensions
- Added
Features:
- ✅ Reads
pageExtensionsfromnext.config.js,next.config.mjs, ornext.config.ts - ✅ Falls back to default extensions if config not found or parsing fails
- ✅ Works with both Pages Router and App Router
- ✅ Maintains backward compatibility
- ✅ Uses caching to avoid performance impact
Testing
The implementation:
- Maintains existing functionality for default extensions
- Adds support for custom extensions like
.page.tsx,.mdx, etc. - Gracefully handles missing or malformed config files
- Uses memoization to prevent performance degradation
Note: This is my first contribution to Next.js. I'd appreciate any feedback on the implementation approach!
Allow CI Workflow Run
- [ ] approve CI run for commit: 705060439641925fe46272aae3d656e4899416ac
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer