Routing
This service provides helpers for routing and handling document.title.
buildRoute
buildRoute provides type-safe path building for pages in the app. It includes auto-complete for path names and will require path parameters to be included if they are present in the URL.
import { buildRoute } from '@rhapsody/routing'
buildRoute('/analytics')
buildRoute('/coaching/:id/calls', { id: '12345' })
history
history is a global singleton created using createBrowserHistory from v4 of the history library.
DocumentTitle
We can use DocumentTitle to update the current page's document title in the browser. The text provided as children to DocumentTitle will be prepended to the string | Salesloft, e.g. <DocumentTitle>Home</DocumentTitle> results in the document title Home | Salesloft. If no text is provided, the fallback title Salesloft will be used, e.g. <DocumentTitle /> results in the document title Salesloft.
import React from 'react'
import { DocumentTitle } from '@rhapsody/routing'
function PageComponent() {
return (
<>
<DocumentTitle>Page XYZ</DocumentTitle>
<div>{/* Additional page content here */}</div>
</>
)
}
How Routing Works in Rhapsody
Local Development Environment
The routing system in Rhapsody works in multiple layers:
1. Nginx Layer (First Contact)
The first routing happens through the infrastructure/server/src/nginx/default.conf file. At this level:
- All server requests are initially directed to
https://$host/app - Several security headers are added to protect the application
- Specific legacy routes are handled (like
/live_callsand/leaving)
2. Express Server Layer
The next layer is an Express server (infrastructure/server/src/serverDev.ts) which:
- Redirects all requests from
https://$hostto/app - Handles static file serving
- Sets up development middleware
- Configures CORS and other security measures
- Proxies requests to the Melody service when needed
3. Frontend Application Layer
Finally, routing reaches the frontend application (platform/internal/navigation/src/Content/Content.tsx). Here, routes are constructed based on registrations made through the @rhapsody/app-registry package. Routes are processed in this order:
- Standard redirects (from
getAllRegisteredRedirects) - Settings section redirects
- Main application routes
- Settings routes
- Root path (
/) handling - 404 handling for unmatched routes
The root path (/) has special handling through LicenseRedirectTracker which:
- Checks if the collaboration license platform is enabled
- Redirects users without 'cadence' feature to
/conversation-intelligence - Otherwise redirects to
/dashboard
If no route matches the user's request, the Handle404Redirect component:
- Logs the error with additional context
- Redirects the user to
/dashboard
Development Container Environment
When running in a development container:
- The system works similarly to the local environment
- A Docker image is created using
.devcontainer/Dockerfile - The container connects to networks created by the local environment setup
- Development dependencies and tools are included in the container
QA and Production Environment
For QA and production:
- A production Docker image is built using the root
Dockerfile - The build process happens in two stages:
- Build Stage: Compiles and bundles the application
- Deploy Stage: Creates a lightweight Nginx-based image
- The image is exported to SalesLoft's registry for use with Kubernetes
Route Registration System
Routes can be registered in two main ways:
- Through
registerRoutesfor general application routes - Through
registerSettingsSectionfor settings-related routes
The system validates all routes to ensure:
- They start with a forward slash
- They contain only valid characters
- There are no duplicate routes
- Settings sections have all required properties
After creating new routes, you must run pnpm generate-routes to ensure type definitions are properly generated. Failing to do this will cause TypeScript errors and prevent proper type checking for route paths.