11import { v4 as uuid } from '@lukeed/uuid' ;
2- import { Routes , Route , BrowserRouter , Outlet , useNavigate } from 'react-router' ;
2+ import { createBrowserRouter , RouterProvider , Outlet , useNavigate , redirect } from 'react-router' ;
33
44import { Layout } from '@/components/layout' ;
55
@@ -37,15 +37,13 @@ import MCPServerToolExecutor from './pages/mcps/tool';
3737import { McpServerPage } from './pages/mcps/[serverId]' ;
3838
3939import {
40- useMastraPlatform ,
4140 LinkComponentProvider ,
4241 LinkComponentProviderProps ,
4342 PlaygroundConfigGuard ,
4443 PlaygroundQueryClient ,
4544 StudioConfigProvider ,
4645 useStudioConfig ,
4746} from '@mastra/playground-ui' ;
48- import { NavigateTo } from './lib/react-router' ;
4947import { Link } from './lib/framework' ;
5048import Scorers from './pages/scorers' ;
5149import Scorer from './pages/scorers/scorer' ;
@@ -76,23 +74,95 @@ const paths: LinkComponentProviderProps['paths'] = {
7674 workflowRunLink : ( workflowId : string , runId : string ) => `/workflows/${ workflowId } /graph/${ runId } ` ,
7775} ;
7876
79- const LinkComponentWrapper = ( { children } : { children : React . ReactNode } ) => {
77+ const RootLayout = ( ) => {
8078 const navigate = useNavigate ( ) ;
81- const frameworkNavigate = ( path : string ) => {
82- navigate ( path ) ;
83- } ;
79+ const frameworkNavigate = ( path : string ) => navigate ( path ) ;
8480
8581 return (
8682 < LinkComponentProvider Link = { Link } navigate = { frameworkNavigate } paths = { paths } >
87- { children }
83+ < Layout >
84+ < Outlet />
85+ </ Layout >
8886 </ LinkComponentProvider >
8987 ) ;
9088} ;
9189
90+ // Determine platform status at module level for route configuration
91+ const isMastraPlatform = Boolean ( window . MASTRA_CLOUD_API_ENDPOINT ) ;
92+
93+ const routes = [
94+ {
95+ element : < RootLayout /> ,
96+ children : [
97+ // Conditional routes (non-platform only)
98+ ...( isMastraPlatform
99+ ? [ ]
100+ : [
101+ { path : '/settings' , element : < StudioSettingsPage /> } ,
102+ { path : '/templates' , element : < Templates /> } ,
103+ { path : '/templates/:templateSlug' , element : < Template /> } ,
104+ ] ) ,
105+
106+ { path : '/scorers' , element : < Scorers /> } ,
107+ { path : '/scorers/:scorerId' , element : < Scorer /> } ,
108+ { path : '/observability' , element : < Observability /> } ,
109+ { path : '/agents' , element : < Agents /> } ,
110+ { path : '/agents/:agentId/tools/:toolId' , element : < AgentTool /> } ,
111+ {
112+ path : '/agents/:agentId' ,
113+ element : (
114+ < AgentLayout >
115+ < Outlet />
116+ </ AgentLayout >
117+ ) ,
118+ children : [
119+ {
120+ index : true ,
121+ loader : ( { params } : { params : { agentId : string } } ) => redirect ( `/agents/${ params . agentId } /chat` ) ,
122+ } ,
123+ { path : 'chat' , element : < Agent /> } ,
124+ { path : 'chat/:threadId' , element : < Agent /> } ,
125+ ] ,
126+ } ,
127+
128+ { path : '/tools' , element : < Tools /> } ,
129+ { path : '/tools/:toolId' , element : < Tool /> } ,
130+
131+ { path : '/processors' , element : < Processors /> } ,
132+ { path : '/processors/:processorId' , element : < Processor /> } ,
133+
134+ { path : '/mcps' , element : < MCPs /> } ,
135+ { path : '/mcps/:serverId' , element : < McpServerPage /> } ,
136+ { path : '/mcps/:serverId/tools/:toolId' , element : < MCPServerToolExecutor /> } ,
137+
138+ { path : '/workflows' , element : < Workflows /> } ,
139+ {
140+ path : '/workflows/:workflowId' ,
141+ element : (
142+ < WorkflowLayout >
143+ < Outlet />
144+ </ WorkflowLayout >
145+ ) ,
146+ children : [
147+ {
148+ index : true ,
149+ loader : ( { params } : { params : { workflowId : string } } ) =>
150+ redirect ( `/workflows/${ params . workflowId } /graph` ) ,
151+ } ,
152+ { path : 'graph' , element : < Workflow /> } ,
153+ { path : 'graph/:runId' , element : < Workflow /> } ,
154+ ] ,
155+ } ,
156+
157+ { index : true , loader : ( ) => redirect ( '/agents' ) } ,
158+ { path : '/request-context' , element : < RequestContext /> } ,
159+ ] ,
160+ } ,
161+ ] ;
162+
92163function App ( ) {
93164 const studioBasePath = window . MASTRA_STUDIO_BASE_PATH || '' ;
94165 const { baseUrl, headers, isLoading } = useStudioConfig ( ) ;
95- const { isMastraPlatform } = useMastraPlatform ( ) ;
96166
97167 if ( isLoading ) {
98168 // Config is loaded from localStorage. However, there might be a race condition
@@ -104,76 +174,12 @@ function App() {
104174 return < PlaygroundConfigGuard /> ;
105175 }
106176
177+ const router = createBrowserRouter ( routes , { basename : studioBasePath } ) ;
178+
107179 return (
108180 < MastraReactProvider baseUrl = { baseUrl } headers = { headers } >
109181 < PostHogProvider >
110- < BrowserRouter basename = { studioBasePath } >
111- < LinkComponentWrapper >
112- < Routes >
113- < Route
114- element = {
115- < Layout >
116- < Outlet />
117- </ Layout >
118- }
119- >
120- { isMastraPlatform ? null : (
121- < >
122- < Route path = "/settings" element = { < StudioSettingsPage /> } />
123- < Route path = "/templates" element = { < Templates /> } />
124- < Route path = "/templates/:templateSlug" element = { < Template /> } />
125- </ >
126- ) }
127-
128- < Route path = "/scorers" element = { < Scorers /> } />
129- < Route path = "/scorers/:scorerId" element = { < Scorer /> } />
130- < Route path = "/observability" element = { < Observability /> } />
131- < Route path = "/agents" element = { < Agents /> } />
132- < Route path = "/agents/:agentId" element = { < NavigateTo to = "/agents/:agentId/chat" /> } />
133- < Route path = "/agents/:agentId/tools/:toolId" element = { < AgentTool /> } />
134- < Route
135- path = "/agents/:agentId"
136- element = {
137- < AgentLayout >
138- < Outlet />
139- </ AgentLayout >
140- }
141- >
142- < Route path = "chat" element = { < Agent /> } />
143- < Route path = "chat/:threadId" element = { < Agent /> } />
144- </ Route >
145-
146- < Route path = "/tools" element = { < Tools /> } />
147- < Route path = "/tools/:toolId" element = { < Tool /> } />
148-
149- < Route path = "/processors" element = { < Processors /> } />
150- < Route path = "/processors/:processorId" element = { < Processor /> } />
151- < Route path = "/mcps" element = { < MCPs /> } />
152-
153- < Route path = "/mcps/:serverId" element = { < McpServerPage /> } />
154- < Route path = "/mcps/:serverId/tools/:toolId" element = { < MCPServerToolExecutor /> } />
155-
156- < Route path = "/workflows" element = { < Workflows /> } />
157- < Route path = "/workflows/:workflowId" element = { < NavigateTo to = "/workflows/:workflowId/graph" /> } />
158-
159- < Route
160- path = "/workflows/:workflowId"
161- element = {
162- < WorkflowLayout >
163- < Outlet />
164- </ WorkflowLayout >
165- }
166- >
167- < Route path = "/workflows/:workflowId/graph" element = { < Workflow /> } />
168- < Route path = "/workflows/:workflowId/graph/:runId" element = { < Workflow /> } />
169- </ Route >
170-
171- < Route path = "/" element = { < NavigateTo to = "/agents" /> } />
172- < Route path = "/request-context" element = { < RequestContext /> } />
173- </ Route >
174- </ Routes >
175- </ LinkComponentWrapper >
176- </ BrowserRouter >
182+ < RouterProvider router = { router } />
177183 </ PostHogProvider >
178184 </ MastraReactProvider >
179185 ) ;
0 commit comments