or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

component-rules.mdcomputed-property-rules.mdember-utils.mdindex.mdlegacy-configuration.mdmigration-rules.mdmodern-configuration.mdplugin-configuration.mdroute-rules.mdservice-rules.mdtest-rules.md
tile.json

route-rules.mddocs/

Route Rules

Rules for Ember routes covering naming conventions, lifecycle management, and best practices. These rules help maintain consistency in route definitions and prevent common routing anti-patterns.

Capabilities

Route Naming Rules

Rules governing route naming conventions and URL structure.

/**
 * Disallow capital letters in route names
 * Enforces kebab-case route naming convention
 */
'ember/no-capital-letters-in-routes': ESLintRule;

/**
 * Enforce snake_case for route segments
 * Maintains URL consistency
 */
'ember/routes-segments-snake-case': ESLintRule;

/**
 * Enforce consistent route path style
 * Standardizes route path definitions
 */
'ember/route-path-style': ESLintRule;

Usage Examples:

// ❌ Bad - capital letters in route name (triggers no-capital-letters-in-routes)
this.route('userProfile');

// ✅ Good - kebab-case route name  
this.route('user-profile');

// ❌ Bad - inconsistent segment casing (triggers routes-segments-snake-case)
this.route('user-profile', { path: '/userProfile/:userId' });

// ✅ Good - snake_case segments
this.route('user-profile', { path: '/user_profile/:user_id' });

Route Access Rules

Rules preventing improper access patterns in routes.

/**
 * Disallow controller access in routes
 * Prevents tight coupling between routes and controllers
 */
'ember/no-controller-access-in-routes': ESLintRule;

/**
 * Disallow accessing private routing service
 * Prevents usage of internal routing APIs
 */
'ember/no-private-routing-service': ESLintRule;

Usage Examples:

// ❌ Bad - accessing controller in route (triggers no-controller-access-in-routes)
export default class UserRoute extends Route {
  setupController(controller, model) {
    super.setupController(...arguments);
    this.controllerFor('application').set('currentUser', model);
  }
}

// ✅ Good - using services instead
export default class UserRoute extends Route {
  @service currentUser;
  
  setupController(controller, model) {
    super.setupController(...arguments);
    this.currentUser.setUser(model);
  }
}

Route Lifecycle Rules

Rules for route lifecycle management and method usage.

/**
 * Disallow deprecated router transition methods
 * Encourages modern transition APIs
 */
'ember/no-deprecated-router-transition-methods': ESLintRule;

/**
 * Disallow unnecessary route path options
 * Removes redundant path specifications
 */
'ember/no-unnecessary-route-path-option': ESLintRule;

/**
 * Disallow unnecessary index routes
 * Removes redundant index route definitions
 */
'ember/no-unnecessary-index-route': ESLintRule;

Usage Examples:

// ❌ Bad - deprecated transition method (triggers no-deprecated-router-transition-methods)
this.transitionToRoute('user.profile');

// ✅ Good - modern transition method
this.transitionTo('user.profile');

// ❌ Bad - unnecessary path option (triggers no-unnecessary-route-path-option)
this.route('profile', { path: '/profile' });

// ✅ Good - default path matches route name
this.route('profile');

// ❌ Bad - unnecessary index route (triggers no-unnecessary-index-route)
this.route('users', function() {
  this.route('index', { path: '/' });
});

// ✅ Good - index route is implicit
this.route('users');

Route Organization Rules

Rules for organizing route properties and maintaining consistent structure.

/**
 * Enforce order of properties in routes
 * Maintains consistent route structure
 */
'ember/order-in-routes': ESLintRule;

/**
 * Disallow shadow route definitions
 * Prevents route definition conflicts
 */
'ember/no-shadow-route-definition': ESLintRule;

Usage Examples:

// ❌ Bad - incorrect property order (triggers order-in-routes)
export default Route.extend({
  actions: {
    save() {
      // action logic
    }
  },
  
  model() {
    return this.store.findAll('user');
  },
  
  queryParams: {
    sortBy: { refreshModel: true }
  }
});

// ✅ Good - correct property order
export default Route.extend({
  queryParams: {
    sortBy: { refreshModel: true }
  },
  
  model() {
    return this.store.findAll('user');
  },
  
  actions: {
    save() {
      // action logic
    }
  }
});

// ❌ Bad - shadow route definition (triggers no-shadow-route-definition)
// In router.js
this.route('users');
this.route('users', { path: '/people' }); // Shadows previous definition

// ✅ Good - unique route definitions
this.route('users');
this.route('people', { path: '/people' });

Route Property Rules

Rules for route-specific properties and default values.

/**
 * Check if property is a default route property
 * Identifies standard route properties
 */
function isRouteDefaultProp(property: ASTNode): boolean;

/**
 * Route-specific property validation
 * Standard route properties that should not be overridden unnecessarily
 */
interface RouteProperties {
  actions: ActionsHash;
  concatenatedProperties: string[];
  controller: string;
  controllerName: string;
  isDestroyed: boolean;
  isDestroying: boolean;
  mergedProperties: string[];
  queryParams: QueryParamsConfig;
  routeName: string;
  templateName: string;
}

Usage Examples:

// Default route properties - generally should not be overridden
export default Route.extend({
  // ✅ Good - standard route implementation
  model() {
    return this.store.findAll('user');
  },
  
  setupController(controller, model) {
    super.setupController(...arguments);
    controller.set('users', model);
  }
});

// Route with query params
export default Route.extend({
  queryParams: {
    page: { refreshModel: true },
    sortBy: { refreshModel: true }
  },
  
  model(params) {
    return this.store.query('user', {
      page: params.page,
      sort: params.sortBy
    });
  }
});