new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

React Router · Getting started · all subjects

routing/basics

146 notes in this subject, read out of this brain and free to use. This is page 3 of 3.

Declarative mode example code

```tsx import { BrowserRouter } from "react-router"; ReactDOM.createRoot(root).render( <BrowserRouter> <App /> </BrowserRouter>, ); ``` This example shows how to set up Declarative mode in React Router.

Tutorials order in React Router documentation

The tutorials section is ordered as position 3 in the React Router documentation structure.

Root Route file location and purpose

Create app/root.jsx as the Root Route. This file defines the root layout of the entire app and must export a component that includes the Outlet component and Scripts component from react-router.

Routes definition file

Create app/routes.js to define your routes. This file is required to build a React Router app. For a minimal setup with no routes, export an empty array: export default [].

Layout routes to scope nested content

Use `layout()` in routes.ts to create a layout route that wraps specific child routes. Syntax: `layout('layouts/sidebar.tsx', [child1, child2])`. This is useful to avoid rendering certain layouts on unrelated routes (e.g., excluding sidebar from an about page) and to scope data loading to specific route branches.

Address book tutorial completion

The address book tutorial for React Router covers building a contacts application with routing basics, form handling, optimistic updates with fetchers, and other core features. The tutorial concludes by noting there are additional APIs available in the React Router documentation.

Address Book tutorial overview and setup

The Address Book tutorial is a feature-rich contacts app that demonstrates React Router capabilities. It takes 30-45 minutes to follow along. Setup: run `npx create-react-router@latest --template remix-run/react-router/tutorials/address-book` to generate a template with CSS and data model, then `npm install` and `npm run dev` to start the app on http://localhost:5173.

Root Route and app/root.tsx

The file app/root.tsx contains the Root Route, which is the first component in the UI that renders. It typically contains the global layout for the page and a default Error Boundary. The root component renders Layout and ErrorBoundary exports, which are special exports for the root route. The Layout export acts as the document's app shell for all route components, HydrateFallback, and ErrorBoundary.

Creating route modules and routes.ts configuration

Route modules are created in the app/routes directory and configured in routes.ts (a special file for route configuration). Use `route()` to configure routes with URL pattern and file path. Dynamic URL segments use colons: `route('contacts/:contactId', 'routes/contact.tsx')` matches /contacts/123, /contacts/abc, etc. The `:contactId` syntax makes a segment dynamic.

Outlet component for nested routing

To render child routes inside parent layouts, import and render the `<Outlet />` component from react-router in the parent component. This allows nested routing to work, displaying child route content where the Outlet is placed.

Client-side routing with Link component

Use `<Link to>` component from react-router instead of HTML `<a href>` to enable client-side routing. When clicking Links, the app updates the URL without reloading the entire page or remounting the app. This allows immediate rendering of new UI instead of making full document requests.

Type safety with Route.ComponentProps

Import `type { Route } from './+types/root'` (React Router generates these types automatically). Use `Route.ComponentProps` to type component props, which provides automatic type safety for loaderData. The types automatically know about properties returned from loaders without manual type definition.

HydrateFallback for client-side loading state

Export a `HydrateFallback` component from the root route to show before the app is hydrated (rendering on the client for the first time). This eliminates the white flash when the page first loads with client-side rendering. Example: `export function HydrateFallback() { return <div id='loading-splash'>Loading...</div>; }`

Index routes as default child routes

Index routes serve as the default child route when a parent route has children but no child matches the current URL. Create index routes using `index('routes/home.tsx')` in routes.ts. Index routes fill empty space in an Outlet when at the parent route's path. Common uses: dashboards, stats, feeds.

NavLink for active route styling

Use `<NavLink>` from react-router instead of `<Link>` to get access to active state information. Pass a function to className that receives `{ isActive, isPending }` to apply styles based on navigation state. `isActive` is true when the URL matches; `isPending` is true while data is loading.

routeDiscovery config option

The routeDiscovery option configures how routes are discovered and loaded by the client. It defaults to mode: 'lazy' with manifestPath: '/__manifest'. Two modes are available: mode: 'lazy' (routes discovered as user navigates, with optional custom manifestPath) and mode: 'initial' (all routes included in initial manifest).

basename config option

The basename option sets the React Router app basename. It defaults to '/'.

app/routes.ts now uses default export

The `app/routes.ts` file API changed to use a default export instead of a named `routes` export, maintaining consistency with other React Router config files like `react-router.config.ts`.

RouterProvider with createBrowserRouter pattern

React Router moved from DataBrowserRouter (and memory/hash siblings) with JSX children to a pattern where developers create a router singleton outside the React tree and pass it to RouterProvider. The new pattern: const router = createBrowserRouter([{ path: '/', element: <Layout />, children: [...] }]); function App() { return <RouterProvider router={router} />; }. This approach eliminates singleton management issues in tests, enables proper HMR handling with router.dispose(), and avoids non-intuitive behavior with conditional routes.

Link preventScrollReset prop

The Link component accepts a preventScrollReset prop that disables scroll reset behavior for that specific navigation. Normally React Router resets scroll to the top on new routes (unless scroll can be restored to a previously known location). This prop is useful for navigating within tabbed views or similar contexts where resetting scroll is undesirable.

ScrollRestoration getKey prop

The ScrollRestoration component now accepts an optional getKey prop that receives a function with signature function getKey(location: Location, matches: DataRouteMatch[]). This function returns the key to use for scroll restoration, allowing developers to restore scroll by pathname, location.key, or any custom logic. By default it uses location.key for backwards compatibility.

GET form submissions state behavior

Form submissions with method="get" result in useNavigation().state === 'loading', not 'submitting'. This aligns with browser behavior since GET requests are navigations that fetch data, not mutations. POST and other methods that perform mutations result in state === 'submitting'.

useNavigation state structure

useNavigation() returns an object with the structure: { state: 'idle' | 'loading' | 'submitting'; location?: Location; formMethod?: FormMethod; formAction?: string; formEncType?: FormEncType; formData?: FormData; }. The type field was removed because in practice only the state was needed, and type could be deduced from state, current location, next location, and submission info. The submission property was flattened so formMethod and formData are directly on the navigation object rather than nested.

useNavigation hook replaces useTransition

The useTransition hook was renamed to useNavigation in React Router to avoid confusion with the useTransition hook in React 18 and because 'navigation' is more semantically correct for what is triggered by router.navigate() or useNavigate(). The deprecated useTransition will remain in Remix for backwards compatibility.

createRoutesFromElements helper

Developers who prefer JSX notation for routes can use createRoutesFromElements (aliased from createRoutesFromChildren) to convert JSX routes to the route configuration format. This enables the cleaner createBrowserRouter pattern while maintaining JSX readability: const routes = createRoutesFromElements(<Route path="/" element={<Layout />><Route index element={<Home /></></Route>); const router = createBrowserRouter(routes);

Single errorElement replaces error/catch distinction

React Router uses a single errorElement instead of separate error and catch boundaries. If anything is thrown, it ends up in the error boundary and is accessible via useRouteError(). Developers can maintain a similar split if desired by checking the error type: if (error instanceof Response) { /* catch case */ } else { /* error case */ }.

Give your agent this brain