Skip to content

React 19 - React Router v7 #3715

@odinr

Description

@odinr

Azure Bord:

As a Fusion Framework App Developer
I want my route configuration to include rich metadata (description, path/search param schema) and be statically analyzable at build time
So that the CLI can generate documentation, OpenAPI specs, prerender lists, navigation trees, and linkswithout loading the appchatbot agents can understand and use correct tooling to resolve params and search args — and so that every loader has access to the Fusion framework instance.


Acceptance Criteria

Core Functionality

  1. App team defines routes using a typed DSL (Domain-Specific Language) (route(), index(), prefix(), layout(), etc.) that compiles to React Router v7 RouteObject[]
  2. Each route supports optional metadata: description, params (path params), search (query params)
  3. params and search schemas include: description, optional type (string, number, boolean), and enum (array of allowed values)
  4. Route metadata is extracted during existing ffc app manifest and ffc portal manifest commands
  5. Routes are added to AppBuildManifest and PortalManifestBuildSchema as optional routes field
  6. The manifest contains only: path, description, params, searchno file paths, no component references
  7. The <Router> component injects the Fusion framework instance into every loader via React Router's context
  8. Loaders access framework via loader({ context })context.framework with full TypeScript support
  9. No runtime cost: manifest is generated before bundling (static analysis only)
  10. Full TypeScript support: RouteNode, ParamSchema, SearchSchema, ManifestEntry, LoaderContext
  11. Works with React Router v7 (createBrowserRouter, lazy, handle, loader, action)

DSL API Design

  1. route(path, component, options?) - Define a route with optional metadata
  2. index(component, options?) - Define an index route
  3. layout(component, children, options?) - Define a layout route
  4. prefix(prefix, children) - Group routes with a common prefix
  5. DSL supports nested routes via children array
  6. DSL supports all React Router features: lazy, loader, action, errorElement, handle
  7. DSL is backward compatible: existing RouteObject[] can be gradually migrated

Framework Injection

  1. Framework instance is injected via React Router's context option in createBrowserRouter
  2. Loader context type: { framework: Fusion, params: Record<string, string>, request: Request }
  3. Framework is available in all loaders regardless of route depth
  4. Framework injection works with nested routers (if any)
  5. Type-safe loader function: loader: (args: LoaderArgs) => Promise<Response> where LoaderArgs includes context.framework

Build & Integration

  1. Route extraction runs during build process (before bundling) as part of manifest generation
  2. Route extraction does not require app execution or DOM environment
  3. CLI validates route schemas and reports errors with file locations during manifest generation
  4. Routes in manifest can be consumed by documentation tools, SSG tools, and other build-time tools
  5. Routes field is optional - apps without routes still generate valid manifests
  6. Link generation: Tools can generate links to routes using only the DSL/manifest (no runtime execution or file paths needed)
  7. Chatbot/AI agent integration: Manifest routes can be used by AI agents to understand route structure and validate params/search args when generating links

Type Safety & Developer Experience

  1. TypeScript infers route paths from DSL definitions
  2. Type-safe route generation: generatePath and useParams work with typed routes
  3. IntelliSense support for route metadata (autocomplete descriptions, params, search)
  4. Compile-time validation of enum values matches route usage
  5. Clear error messages when route definitions are invalid

Non-Functional Requirements

  1. Zero runtime overhead: DSL is compile-time only
  2. Bundle size impact: < 1KB for route DSL utilities
  3. Build time impact: < 100ms for typical app (50-100 routes)
  4. Backward compatible: existing apps continue to work without migration
  5. Migration path: apps can gradually adopt DSL alongside existing routes

Edge Cases & Error Handling

  1. Handles routes with dynamic segments (:param, *splat)
  2. Handles optional route segments
  3. Handles routes with query string parameters
  4. Handles routes with no metadata (optional feature)
  5. Handles invalid route definitions with clear error messages
  6. Handles circular route dependencies
  7. Handles routes defined in multiple files

Sub-issues

Metadata

Metadata

Assignees

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions