Capítulo 55 de 57

Chapter 55: create-route Property Order Rule

Core Idea

The @tanstack/router/create-route-property-order ESLint rule enforces a specific ordering of type-inference-sensitive properties passed to createRoute, createFileRoute, createRootRoute, and createRootRouteWithContext, because TypeScript resolves these properties' types in the order they appear in the object literal.

Key Concepts

  • Why order matters: Properties like beforeLoad and loader depend on inferred types from earlier properties (e.g. loader's context argument type depends on what beforeLoad returns); if loader is written before beforeLoad in the object literal, TypeScript can't yet infer the context shape.
  • Correct order: params, validateSearchloaderDeps, search.middlewares, ssrcontextbeforeLoadloaderonEnter, onStay, onLeave, head, scripts, headers, remountDeps.
  • Order-insensitive properties: All properties not listed above (e.g. component, notFoundComponent, staticData) don't depend on inference order and can be placed anywhere.
  • Applies to four functions: createRoute, createFileRoute, createRootRoute, createRootRouteWithContext, all of which build route config objects subject to this inference chain.
  • Autofixable: The rule is marked both Recommended and Fixable (🔧), meaning ESLint --fix can reorder properties automatically.

Code Examples

// Incorrect: loader before beforeLoad breaks context type inference
export const Route = createFileRoute('/path')({
  loader: async ({ context }) => {
    await context.queryClient.ensureQueryData(getQueryOptions(context.hello))
  },
  beforeLoad: () => ({ hello: 'world' }),
})
// Correct: beforeLoad before loader
export const Route = createFileRoute('/path')({
  beforeLoad: () => ({ hello: 'world' }),
  loader: async ({ context }) => {
    await context.queryClient.ensureQueryData(getQueryOptions(context.hello))
  },
})
  • What it demonstrates: How reordering beforeLoad before loader fixes type inference of context.hello inside the loader.

Key Takeaways

  1. Always declare beforeLoad before loader (and follow the full documented order) so downstream properties get correctly inferred context/dependency types.
  2. Enable this rule and let eslint --fix handle reordering automatically rather than manually tracking the sequence.
  3. This is purely a TypeScript-inference concern, not a runtime one, but getting it wrong silently degrades type safety without an obvious error unless the lint rule catches it.

Connects To

  • Ch 54: ESLint Plugin Router, the parent plugin and installation/config instructions for this rule.
  • Ch 49: Router Context, explains why beforeLoad's return value feeds into loader's context argument.