← All @molecule/* packages · App templates

@molecule/app-routing-react-router

Provider bond · routing · App (browser) · v1.0.1 · Apache-2.0

React Router v7 provider for @molecule/app-routing

npm install @molecule/app-routing-react-router

npm · Source on GitHub · Implements @molecule/app-routing

How it works

@molecule/app-routing-react-router is a provider bond on the app (browser) side: it implements the routing core interface (@molecule/app-routing) with a concrete vendor or library behind it.

Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.

import { BrowserRouter, Routes, Route } from 'react-router'
import { MoleculeRouterProvider } from '@molecule/app-routing-react-router'

function App() {
  // MoleculeRouterProvider bonds the adapter automatically (calls setRouter in an
  // effect on mount), so @molecule/app-routing's navigate()/getRouter() drive THIS
  // real React Router — no manual setRouter wiring needed.
  return (
    <BrowserRouter>
      <MoleculeRouterProvider>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/users/:id" element={<UserProfile />} />
        </Routes>
      </MoleculeRouterProvider>
    </BrowserRouter>
  )
}

Works with: @molecule/app-i18n, @molecule/app-routing

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

React Router (v7/v8) provider for @molecule/app-routing.

This package provides a React Router implementation of the molecule Router interface, allowing you to use molecule's routing abstractions with React Router.

Quick Start

import { BrowserRouter, Routes, Route } from 'react-router'
import { MoleculeRouterProvider } from '@molecule/app-routing-react-router'

function App() {
  // MoleculeRouterProvider bonds the adapter automatically (calls setRouter in an
  // effect on mount), so @molecule/app-routing's navigate()/getRouter() drive THIS
  // real React Router — no manual setRouter wiring needed.
  return (
    <BrowserRouter>
      <MoleculeRouterProvider>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/users/:id" element={<UserProfile />} />
        </Routes>
      </MoleculeRouterProvider>
    </BrowserRouter>
  )
}

Type

provider

Installation

npm install @molecule/app-routing-react-router @molecule/app-i18n @molecule/app-routing react react-router
npm install -D @types/react

API

Interfaces

MoleculeRouterProviderProps

Provider props.

interface MoleculeRouterProviderProps {
  /**
   * Child components.
   */
  children: ReactNode

  /**
   * Optional route definitions for named routes.
   */
  routes?: RouteDefinition[]

  /**
   * Callback when router is ready.
   */
  onRouterReady?: (router: Router) => void
}

Options for programmatic navigation (replace vs push, carry state, preserve query/hash).

interface NavigateOptions {
  /**
   * Replace current history entry instead of pushing.
   */
  replace?: boolean
  /**
   * State to pass with navigation.
   */
  state?: unknown
  /**
   * Preserve current query params.
   */
  preserveQuery?: boolean
  /**
   * Preserve current hash.
   */
  preserveHash?: boolean
}

ReactRouterConfig

React Router-specific configuration.

interface ReactRouterConfig {
  /**
   * React Router navigate function (from useNavigate).
   */
  navigate?: NavigateFunction

  /**
   * Current location (from useLocation).
   */
  location?: {
    pathname: string
    search: string
    hash: string
    state?: unknown
    key?: string
  }

  /**
   * Current params (from useParams).
   */
  params?: Record<string, string | undefined>

  /**
   * Initial route definitions.
   */
  routes?: RouteDefinition[]
}

ReactRouterHooks

React Router hooks adapter.

interface ReactRouterHooks {
  /**
   * The navigate function from useNavigate.
   */
  navigate: NavigateFunction

  /**
   * Location from useLocation.
   */
  location: {
    pathname: string
    search: string
    hash: string
    state?: unknown
    key?: string
  }

  /**
   * Params from useParams.
   */
  params: Record<string, string | undefined>

  /**
   * Search params from useSearchParams.
   */
  searchParams: URLSearchParams
}

RouteDefinition

Route configuration entry (path pattern, name, auth requirements, roles, children).

interface RouteDefinition {
  /**
   * Route path pattern.
   */
  path: string
  /**
   * Route name (for named routes).
   */
  name?: string
  /**
   * Whether the route requires exact matching.
   */
  exact?: boolean
  /**
   * Whether the route requires authentication.
   */
  requiresAuth?: boolean
  /**
   * Required roles/permissions.
   */
  roles?: string[]
  /**
   * Route metadata.
   */
  meta?: Record<string, unknown>
  /**
   * Child routes.
   */
  children?: RouteDefinition[]
}

RouteLocation

Current URL decomposed into pathname, search string, hash, navigation state, and unique key.

interface RouteLocation {
  /**
   * Current pathname.
   */
  pathname: string
  /**
   * Query string (including leading ?).
   */
  search: string
  /**
   * Hash (including leading #).
   */
  hash: string
  /**
   * State data passed with navigation.
   */
  state?: unknown
  /**
   * Unique key for this location.
   */
  key?: string
}

RouteMatch

Result of matching a URL against a route pattern (path, params, query string).

interface RouteMatch<Params extends RouteParams = RouteParams> {
  /**
   * Route path pattern.
   */
  path: string
  /**
   * Matched URL pathname.
   */
  pathname: string
  /**
   * Route parameters.
   */
  params: Params
  /**
   * Whether this is an exact match.
   */
  isExact: boolean
}

Router

Client-side router providing navigation, guards, route matching, and history control.

All routing providers must implement this interface.

interface Router {
  /**
   * Returns the current route location (pathname, search, hash, state).
   */
  getLocation(): RouteLocation
  /**
   * Gets the current route params.
   */
  getParams<T extends RouteParams = RouteParams>(): T
  /**
   * Gets the current query params.
   */
  getQuery(): QueryParams
  /**
   * Gets a specific query parameter.
   */
  getQueryParam(key: string): string | undefined
  /**
   * Gets the current hash.
   */
  getHash(): string
  /**
   * Navigates to a path.
   */
  navigate(path: string, options?: NavigateOptions): void
  /**
   * Navigates to a named route.
   */
  navigateTo(
    name: string,
    params?: RouteParams,
    query?: QueryParams,
    options?: NavigateOptions,
  ): void
  /**
   * Goes back in history.
   */
  back(): void
  /**
   * Goes forward in history.
   */
  forward(): void
  /**
   * Goes to a specific point in history.
   */
  go(delta: number): void
  /**
   * Updates the current query params.
   */
  setQuery(params: QueryParams, options?: NavigateOptions): void
  /**
   * Updates a specific query parameter.
   */
  setQueryParam(key: string, value: string | undefined, options?: NavigateOptions): void
  /**
   * Updates the current hash.
   */
  setHash(hash: string, options?: NavigateOptions): void
  /**
   * Checks if a path matches the current location.
   *
   * @returns `true` if the path matches the current route.
   */
  isActive(path: string, exact?: boolean): boolean
  /**
   * Matches a path pattern against a pathname.
   */
  matchPath<Params extends RouteParams = RouteParams>(
    pattern: string,
    pathname: string,
  ): RouteMatch<Params> | null
  /**
   * Generates a URL from a named route.
   */
  generatePath(name: string, params?: RouteParams, query?: QueryParams): string
  /**
   * Subscribes to route changes.
   */
  subscribe(listener: RouteChangeListener): () => void
  /**
   * Adds a navigation guard.
   */
  addGuard(guard: NavigationGuard): () => void
  /**
   * Registers route definitions.
   */
  registerRoutes(routes: RouteDefinition[]): void
  /**
   * Gets all registered routes.
   */
  getRoutes(): RouteDefinition[]
  /**
   * Destroys the router.
   */
  destroy(): void
}

RouterConfig

Configuration options for creating a router instance.

interface RouterConfig {
  /**
   * Router mode.
   */
  mode?: 'history' | 'hash' | 'memory'
  /**
   * Base path.
   */
  basePath?: string
  /**
   * Initial routes.
   */
  routes?: RouteDefinition[]
}

Types

GuardResult

Navigation guard result.

type GuardResult =
  | boolean
  | string
  | {
      path: string
      replace?: boolean
    }
  | void

Navigation guard function invoked before each navigation. Return false to cancel, a string/path to redirect, or void to allow.

type NavigationGuard = (
  to: RouteLocation,
  from: RouteLocation | null,
) => GuardResult | Promise<GuardResult>

QueryParams

URL query string parameter map (single values or arrays for repeated keys).

type QueryParams = Record<string, string | string[] | undefined>

RouteChangeListener

Callback invoked on each route change with the new location and the navigation action that triggered it.

type RouteChangeListener = (location: RouteLocation, action: 'push' | 'replace' | 'pop') => void

RouteParams

URL path parameter key-value map extracted from dynamic route segments (e.g. { id: '123' }).

type RouteParams = Record<string, string>

Functions

createReactRouter(config)

Creates a React Router adapter that implements the molecule Router interface.

function createReactRouter(config?: ReactRouterConfig): Router
  • config — Configuration with React Router's navigate function, location, params, and optional routes.

Returns: A molecule Router with navigation, guards, query/hash management, and route matching.

generatePath(pattern, params)

Generates a concrete path from a route pattern by replacing :param segments with values. Throws if a required param is missing.

function generatePath(pattern: string, params?: RouteParams): string
  • pattern — The route pattern (e.g. '/users/:id').
  • params — A map of param names to values.

Returns: The resolved path string with params URL-encoded.

matchPath(pattern, pathname, exact)

Matches a path pattern (with :param segments and * wildcards) against a pathname.

function matchPath(pattern: string, pathname: string, exact?: boolean): RouteMatch<Params> | null
  • pattern — The route pattern (e.g. '/users/:id').
  • pathname — The actual URL pathname to test.
  • exact — Whether to require an exact match (default true). Set to false for prefix matching.

Returns: A RouteMatch with extracted params, or null if no match.

MoleculeRouterProvider(props)

Provider component that creates a molecule Router from React Router hooks and bonds it as the active singleton via @molecule/app-routing's setRouter.

Bonding happens in an effect on mount (and again whenever the location/params change), so @molecule/app-routing's navigate()/getRouter() drive THIS real React Router adapter — no manual setRouter wiring required. Mount it once inside <BrowserRouter>.

function MoleculeRouterProvider(props: MoleculeRouterProviderProps): React.JSX.Element
  • props — The provider props (see {@link MoleculeRouterProviderProps}): children (rendered inside the router context), routes (optional named-route definitions), and onRouterReady (optional callback invoked with the router after it is bonded, e.g. to register guards — bonding via setRouter happens regardless).

Returns: The rendered provider wrapping children with the router context.

normalizePath(path)

Removes trailing slashes from a path. Returns '/' for root/empty paths.

function normalizePath(path: string): string
  • path — The URL path to normalize.

Returns: The path without trailing slashes.

parseSearchParams(searchParams)

Parses URLSearchParams into a molecule QueryParams object. Duplicate keys are collected into arrays.

function parseSearchParams(searchParams: URLSearchParams): QueryParams
  • searchParams — The URLSearchParams instance (e.g. from useSearchParams()).

Returns: A QueryParams map where duplicate keys become string arrays.

resolvePath(to, fromPathname)

Resolves a relative path against a base pathname. Absolute paths (starting with /) are returned as-is. Relative paths handle .. (parent) and . (current) segments.

function resolvePath(to: string, fromPathname: string): string
  • to — The destination path (absolute or relative).
  • fromPathname — The current pathname to resolve against.

Returns: The resolved absolute path.

stringifyQuery(params)

Converts a molecule QueryParams object to a URL search string (e.g. ?key=val&arr=1&arr=2). Omits keys with undefined values. Returns empty string if no params.

function stringifyQuery(params: QueryParams): string
  • params — The query parameters to stringify.

Returns: A URL search string starting with ?, or empty string if no params.

useIsActive(path, exact)

Hook to check if a path is currently active.

function useIsActive(path: string, exact?: boolean): boolean
  • path — Path to check
  • exact — Whether to require exact match

Returns: Whether the path is active

useMoleculeNavigate()

Hook to get a navigate function with molecule Router options.

function useMoleculeNavigate(): (path: string, options?: NavigateOptions) => void

Returns: Navigate function

useMoleculeQuery()

Hook to get current query params as an object.

function useMoleculeQuery(): QueryParams

Returns: Query params object

useMoleculeRouter()

Hook to get the molecule Router.

function useMoleculeRouter(): Router

Returns: The molecule Router instance

Constants

provider

Default React Router provider (basic, no hooks). For full functionality, use createReactRouter with useNavigate/useLocation/useParams.

const provider: Router

Core Interface

Implements @molecule/app-routing interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setRouter } from '@molecule/app-routing'
import { provider } from '@molecule/app-routing-react-router'

export function setupRoutingReactRouter(): void {
  setRouter(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-i18n ^1.0.1
  • @molecule/app-routing ^1.0.1
  • react ^18.0.0 || ^19.0.0
  • react-router ^7.0.0 || ^8.0.0

Runtime Dependencies

  • @molecule/app-i18n

  • @molecule/app-routing

  • react

  • react-router

  • MoleculeRouterProvider bonds the router for you. On mount it calls @molecule/app-routing's setRouter with the live adapter, so other molecule packages' navigate()/getRouter() drive React Router (real SPA navigation) — no manual wiring. Pass onRouterReady only if you also need the router instance (e.g. to register guards); bonding happens either way.

  • Do NOT wire the exported provider const in a React Router app — it is a no-hooks fallback (empty params, window.location.href navigation). Use MoleculeRouterProvider (or createReactRouter with hook values) instead.

  • The provider must live INSIDE <BrowserRouter> (it calls React Router hooks).

  • Import from 'react-router', never 'react-router-dom'. The -dom package was discontinued after v7 (it was only a re-export shim); every API (BrowserRouter, Routes, Route, Link, hooks) lives in react-router.