Skip to content

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Jan 23, 2026

Problem

We used to extract all route params with regular expressions. This would intrinsically enforce a very strict format for the parameter names: [a-zA-Z$][a-zA-Z0-9$]*, i.e. a valid javascript variable name.

When we rewrote the matcher (#5722), regular params were not matched by a regex anymore ($param) but more complex param syntaxes were still (e.g. prefix{-$optional}suffix). So we were only half enforcing the parameter name, which is not ideal.

Now we would like to move completely off of regexes (#6470) and we should probably enforce some limitations on parameter names, or we risk preventing future evolutions of the syntax if parameter names are too lax, and users start using characters we would eventually like to assign special meaning to.

Solution

This PR proposes we add an ESLint rule so that such invalid parameter names can be detected in IDE and in CI.

Summary by CodeRabbit

  • New Features

    • Added an ESLint rule that enforces valid route parameter names and included it in recommended configs.
  • Tests

    • Added extensive unit tests and utility tests covering valid/invalid param formats, braces/optional/wildcard cases, multi-param paths, various call shapes, and path-to-route conversions.

✏️ Tip: You can customize this high-level summary in your review settings.

@nx-cloud
Copy link

nx-cloud bot commented Jan 23, 2026

View your CI Pipeline Execution ↗ for commit ed276e6

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 55s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 6s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-23 22:02:18 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

Adds a new ESLint rule "route-param-names" that validates route parameter identifiers in TanStack Router path strings, along with constants, utilities for extracting/validating params, and comprehensive tests covering valid/invalid cases and multiple invocation shapes.

Changes

Cohort / File(s) Summary
Core Rule + Utils
packages/eslint-plugin-router/src/rules/route-param-names/route-param-names.rule.ts, packages/eslint-plugin-router/src/rules/route-param-names/route-param-names.utils.ts, packages/eslint-plugin-router/src/rules/route-param-names/constants.ts
New rule implementation, utility functions and constants: locate route path strings (various call shapes), extract params, validate names with VALID_PARAM_NAME_REGEX, and report invalidParamName diagnostics. Exports name and rule.
Plugin Registration
packages/eslint-plugin-router/src/index.ts, packages/eslint-plugin-router/src/rules.ts
Registers the new rule in plugin exports and marks @tanstack/router/route-param-names as 'error' in recommended and flat/recommended configs.
Tests
packages/eslint-plugin-router/src/__tests__/route-param-names.rule.test.ts, packages/eslint-plugin-router/src/__tests__/route-param-names.utils.test.ts
Adds comprehensive unit tests for rule behavior and utilities: valid/invalid param names (including braces, optional syntax, prefixes/suffixes, wildcards), multiple params, file-route variants, and utility function coverage (extraction, validation, invalid detection).

Sequence Diagram(s)

sequenceDiagram
  participant Source as "Source File / AST"
  participant ESLint as "ESLint Rule\nroute-param-names"
  participant Utils as "Param Utils"
  participant Reporter as "ESLint Reporter"

  Note over Source,ESLint: Linter visits project files
  Source->>ESLint: Detect router import/use and calls
  ESLint->>ESLint: Determine call shape (path prop, first-arg, file-based, curried)
  ESLint->>Utils: Extract path string(s) from literal/template/filepath
  Utils->>Utils: extractParamsFromPath / isValidParamName / getInvalidParams
  Utils-->>ESLint: Return invalid params list
  ESLint->>Reporter: Report `invalidParamName` for each invalid param (with paramName)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • beaussan
  • nlynzaad

Poem

🐰 I hopped through code with whiskers bright,
I chased each $param into the light,
I checked their names with careful cheer,
I nudged the bad ones — now paths are clear! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a new ESLint rule for validating route parameter names in the eslint-plugin-router package.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 23, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6473

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6473

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6473

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6473

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6473

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6473

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6473

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6473

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6473

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6473

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6473

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6473

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6473

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6473

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6473

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6473

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6473

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6473

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6473

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6473

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6473

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6473

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6473

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6473

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6473

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6473

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6473

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6473

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6473

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6473

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6473

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6473

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6473

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6473

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6473

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6473

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6473

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6473

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6473

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6473

commit: ed276e6

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@packages/eslint-plugin-router/src/rules/route-param-names/route-param-names.rule.ts`:
- Around line 46-60: The getStringLiteralValue function treats empty template
literals inconsistently because it checks node.quasis[0]?.value.cooked by
truthiness; change that check to explicitly test for null/undefined (e.g.,
cooked != null) so an empty string ("") is returned rather than null. Update the
TemplateLiteral branch (AST_NODE_TYPES.TemplateLiteral and
node.quasis[0].value.cooked) to capture the cooked value into a variable and
return it when it's not null/undefined, preserving existing behavior for
non-string Literal nodes.
- Around line 74-89: The rule currently only recognizes Identifier keys named
'path' in object arguments; update the property-key check in the createRoute
branch (where pathAsPropertySet is used and
reportInvalidParams/getStringLiteralValue are called) to also accept
string-literal keys. Replace the single check "prop.key.type ===
AST_NODE_TYPES.Identifier && prop.key.name === 'path'" with a condition that
allows either an Identifier named 'path' or a Literal whose value === 'path'
(i.e., check prop.key.type === AST_NODE_TYPES.Literal && prop.key.value ===
'path') before calling getStringLiteralValue and reportInvalidParams.

@Sheraff Sheraff merged commit e5f59f4 into main Jan 23, 2026
6 checks passed
@Sheraff Sheraff deleted the feat-eslint-plugin-router-param-name-rule branch January 23, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants