diff --git a/packages/server/src/routes/index.tsx b/packages/server/src/routes/index.tsx index 94601935..4795372c 100644 --- a/packages/server/src/routes/index.tsx +++ b/packages/server/src/routes/index.tsx @@ -14,13 +14,13 @@ import { LoadErrorCard } from '../components/actionUi' * expose in the URL) renders the dashboard right here, unchanged. */ export const Route = createFileRoute('/')({ - ssr: false, // `?template=` deep-links from the public market (`/templates`): it rides through // the gated redirect and preselects the compose modal (see DashboardView.openTemplate). validateSearch: (s: Record): { template?: string } => ({ template: typeof s.template === 'string' && s.template ? s.template : undefined, }), loaderDeps: ({ search }) => ({ template: search.template }), + ssr: false, loader: async ({ deps }): Promise<{ mode: 'signin' | 'dashboard'; auth: { enabled: boolean }; initial?: DashboardData }> => { const auth = await getAuthState() if (auth.enabled) { diff --git a/packages/server/src/routes/onboarding.tsx b/packages/server/src/routes/onboarding.tsx index aad73504..1048c32e 100644 --- a/packages/server/src/routes/onboarding.tsx +++ b/packages/server/src/routes/onboarding.tsx @@ -21,12 +21,12 @@ import { LoadErrorCard } from '../components/actionUi' * from the URL), falling back to the default. Open mode renders with no team segment. */ export const Route = createFileRoute('/onboarding')({ - ssr: false, validateSearch: (search: Record): { team?: string } => { const team = typeof search.team === 'string' ? search.team.trim() : '' return team ? { team } : {} }, loaderDeps: ({ search }) => ({ team: search.team }), + ssr: false, loader: async ({ deps, }): Promise<{ diff --git a/packages/server/src/routes/t.$teamId.tsx b/packages/server/src/routes/t.$teamId.tsx index d6a21a01..e3dd5220 100644 --- a/packages/server/src/routes/t.$teamId.tsx +++ b/packages/server/src/routes/t.$teamId.tsx @@ -18,12 +18,12 @@ import { LoadErrorCard } from '../components/actionUi' * single shared workspace. */ export const Route = createFileRoute('/t/$teamId')({ - ssr: false, // `?template=` is forwarded from `/` (the public-market deep link) and preselects // the compose modal on this team's dashboard. validateSearch: (s: Record): { template?: string } => ({ template: typeof s.template === 'string' && s.template ? s.template : undefined, }), + ssr: false, loader: async ({ params, }): Promise<{ mode: 'signin' | 'dashboard'; auth: { enabled: boolean }; teamId: string; initial?: DashboardData }> => { diff --git a/packages/server/src/routes/templates.tsx b/packages/server/src/routes/templates.tsx index 0f42dc04..2b29d1d8 100644 --- a/packages/server/src/routes/templates.tsx +++ b/packages/server/src/routes/templates.tsx @@ -21,6 +21,7 @@ import type { BundleView } from '../types' * the SEO meta. The interactive bits (category filter, copy buttons) hydrate as usual. */ export const Route = createFileRoute('/templates')({ + loader: async (): Promise<{ bundles: BundleView[] }> => ({ bundles: await listPublicBundles() }), head: () => ({ meta: [ { title: 'Loopany templates — agent loops that actually work' }, @@ -31,7 +32,6 @@ export const Route = createFileRoute('/templates')({ }, ], }), - loader: async (): Promise<{ bundles: BundleView[] }> => ({ bundles: await listPublicBundles() }), component: TemplatesRoute, })