Skip to content

haivuw/react-router-infer

Repository files navigation

react-router-infer

ci

A little type-safer react-router-dom. Inspired by @tanstack/router.

What's covered:

Prerequisites

  • typescript >= 5.3. This allows r helper or [...] as const sastisfies RouteObject[] to work. See this PR.
  • react-router-dom >= 6.0.0. For Outlet, RouteObject.

Quick start

Install packages:

npm install react-router-infer react-router-dom

Setup your routes:

// 1. Define routes with `r` function. `parseSearch` is added to type URL search params.
const routes = r([
  {
    path: '/',
    children: [
      {
        path: ':id',
        parseSearch: (jsonObject) =>
          z.object({ page: z.number().catch(1) }).parse(jsonObject),
      },
    ],
  },
])

// 2 Register root route:
declare module 'react-router-infer' {
  interface Register {
    routes: CreateRoutes<typeof routes>
  }
}

// 3. Wrap root route with `withSearchParamsProvider` before passing it to `createBrowserRouter` or `useRoutes`:
const router = createBrowserRouter(
  withSearchParamsProvider({
    routes,
    /**
     * Optionally customize search params stringify and parse functions
     *
     * @see https://tanstack.com/router/v1/docs/guide/custom-search-param-serialization
     */
    // stringifySearch,
    // parseSearch
  }),
)

// 4. Use hooks/components from `react-router-infer`:

// useParams
const { id } = useParams({ from: '/:id' }) // from is optional for useParams

// useNavigate/Link
const navigate = useNavigate()
navigate({
  to: '/:id',
  params: {
    id: '123',
  },
  search: {
    page: 1,
  },
})

// useSearch
const { search, setSearch, isInvalidRoute } = useSearch({
  from: '/:id',
})
// search/setSearch can be undefined
if (isInvalidRoute)
  throw new Error('useSearch is being called out of "/:id" route')
// search/setSearch is defined after checking isInvalidRoute
setSearch({
  page: search.page + 1,
})

API & Example

See the docs or the example app