Routes Configuration
Routes let you define a sequence of turnout operations that execute together as a single action. Instead of throwing each turnout individually, you define a route once and activate it with one tap. Routes are stored in Firebase Firestore at layouts/{layoutId}/routes and can be triggered from the Throttle app, the Cloud app, or programmatically through the server.

Route List
The main routes view (/routes) displays your defined routes as a list of cards. Each card shows the route name and provides a clickable interface to navigate to the edit form. An "Add" tile at the beginning of the list lets you create new routes.
Creating a Route
Navigate to /routes/new or click the Add tile. The route form has three main areas: metadata, turnout sequence, and display options.
Route Metadata
| Field | Description | Required |
|---|---|---|
| Name | A display name for the route (e.g., "Main Line to Yard") | Yes |
| Point 1 | The starting location or track identifier | No |
| Point 2 | The ending location or track identifier | No |
The Point 1 and Point 2 fields are free-text identifiers that describe the route's endpoints on your layout. They are also used to auto-generate the route ID when creating a new route (formatted as route-{point1}-{point2} using the slugify utility).
Turnout Sequence
The core of a route is its turnout sequence. The Turnouts card displays the currently assigned turnouts as a row of interactive chips. Each chip shows:
- A directional icon (fork icon for turnouts) color-coded green (straight) or red (thrown)
- The turnout name
- A delete button to remove the turnout from the sequence
- A state toggle indicator showing the turnout's current live state
Adding Turnouts to a Route
Click the + button on the Turnouts card to open the turnout selector dialog. This shows all turnouts defined in your layout. Select the turnouts you want to include in the route and confirm. Duplicate entries are automatically deduplicated.
Setting Turnout State
Each turnout in the route has a configurable target state (straight or thrown). Click the state icon on a chip to toggle whether the turnout should be set to straight or thrown when the route executes. The green/red color indicates the target state:
- Green -- The turnout will be set to thrown (divergent) when the route runs.
- Red -- The turnout will be set to straight (closed) when the route runs.
Removing Turnouts
Click the delete icon on any turnout chip to remove it from the route sequence.

Testing a Route
While editing, you can click the Run Route button to immediately execute the route without saving. This sends the turnout commands through the runRoute function from useRoutes(), which throws each turnout in the sequence through Firestore. The server picks up the state changes and forwards them to the CommandStation.
This is useful for verifying that a route works correctly before saving it.
Display Options
- Color -- Click the color picker button to choose a display color for the route card in the UI. A color picker dialog lets you select from a full palette.
- Tags -- Assign tags to the route for filtering and organization. Tags are shared across the layout.
Editing a Route
Click any route card in the list to navigate to /routes/:routeId. The edit form is identical to the create form, pre-populated with the route's existing data. The header displays "Edit Route" instead of "Add Route". Modify any fields and click Submit to save, or Close to discard changes.
Deleting a Route
Route deletion is handled through the route edit form. Remove the route from the Firestore collection to delete it.
Data Structure
Each route document in Firestore has the following shape:
| Field | Type | Description |
|---|---|---|
id | string | Auto-generated or custom route identifier |
name | string | Display name |
description | string | Route description (defaults to name) |
point1 | string | Starting location identifier |
point2 | string | Ending location identifier |
turnouts | RouteTurnoutConfig[] | Ordered array of turnout configurations |
color | string | Display color name |
tags | string[] | Tag identifiers for filtering |
order | number | Sort order in the list |
Each entry in the turnouts array has:
| Field | Type | Description |
|---|---|---|
id | string | Reference to a turnout document ID |
name | string | Turnout display name |
device | string | Device ID controlling the turnout |
type | string | Always "turnout" |
state | boolean | Target state when route executes |
How Route Execution Works
When a route is activated:
- The
runRoutefunction iterates through the route's turnout array. - For each turnout, it calls
setTurnoutto update the turnout's state in Firestore. - The server's Firestore listener detects each state change.
- The server sends the corresponding DCC command (
<T idx state>) to the CommandStation for each turnout. - Turnouts throw in sequence on the layout.
Since each turnout state change goes through Firestore independently, there is a small delay between successive throws as each command round-trips through the Firebase pipeline.
Related Pages
- Turnouts Configuration -- Define the turnouts that routes reference.
- Cloud App Overview -- Return to the main Cloud app guide.
- Effects Management -- Create effects that can be triggered alongside routes.