Routing
The Ellemment Stack implements file-based routing using remix-flat-routes, which extends Remix's routing convention with hybrid routing capabilities. This configuration is set up in your application's vite.config.js
file.
Route Structure Discovery
Discover your application's route structure using:
npx remix routes
This command outputs a JSX-like representation of your routes based on the current file structure.
Example Route Structure
app/routes
├── _auth+
│ ├── forgot-password.tsx
│ ├── login.tsx
│ ├── logout.tsx
│ ├── onboarding.tsx
│ └── signup.tsx
├── _marketing+
│ ├── about.tsx
│ ├── index.tsx
│ ├── privacy.tsx
│ └── tos.tsx
├── admin+
│ ├── cache.tsx
│ └── cache_.sqlite.tsx
├── resources+
│ ├── delete-image.tsx
│ ├── healthcheck.tsx
│ └── theme.tsx
└── users+
└── $username_+
├── profile.tsx
└── settings.tsx
Route Configuration
The above file structure generates the following routes:
<Routes>
<Route file="root.tsx">
{/* Authentication Routes */}
<Route path="login" file="routes/_auth+/login.tsx" />
<Route path="logout" file="routes/_auth+/logout.tsx" />
<Route path="signup" file="routes/_auth+/signup.tsx" />
{/* Marketing Pages */}
<Route path="about" file="routes/_marketing+/about.tsx" />
<Route index file="routes/_marketing+/index.tsx" />
{/* Admin Section */}
<Route path="admin/cache" file="routes/admin+/cache.tsx">
<Route path="sqlite" file="routes/admin+/cache_.sqlite.tsx" />
</Route>
{/* Resource Routes */}
<Route
path="resources/theme"
file="routes/resources+/theme.tsx"
/>
{/* User Routes */}
<Route path="users/:username" file="routes/users+/$username_+/profile.tsx" />
<Route
path="users/:username/settings"
file="routes/users+/$username_+/settings.tsx"
/>
</Route>
</Routes>
Hybrid Routing Benefits
-
Code Organization:
- Colocate related route files
- Group by feature or section
- Maintain clean directory structure
-
File Naming:
- Use
.
for nested routes - Use
+
for grouped routes - Use
$
for dynamic parameters
- Use
-
Route Grouping:
_feature+/ # Feature group ├── index.tsx # Landing page ├── about.tsx # About page └── settings.tsx # Settings page
Route Types
Static Routes
// routes/about.tsx -> /about
export default function About() {
return <div>About Page</div>
}
Dynamic Routes
// routes/users/$userId.tsx -> /users/:userId
export default function UserProfile() {
const { userId } = useParams()
return <div>User {userId}</div>
}
Nested Routes
// routes/users.$userId.settings.tsx -> /users/:userId/settings
export default function UserSettings() {
const { userId } = useParams()
return <div>Settings for {userId}</div>
}
Best Practices
-
Route Organization
- Group related routes
- Use descriptive names
- Maintain flat structure
- Follow naming conventions
-
File Structure
- Keep routes organized
- Use feature folders
- Separate resource routes
- Group by functionality
-
Route Naming
- Use kebab-case for files
- Clear, descriptive names
- Consistent patterns
- Semantic grouping
-
Code Organization
- Colocate related code
- Keep components close
- Share utilities properly
- Maintain clear boundaries
For detailed implementation examples, see the examples documentation.