Declarative routing for React web applications
—
Components for creating navigation interfaces including links, forms, and programmatic navigation with support for active states and form handling.
Creates navigation links that update the URL without full page reloads.
/**
* Navigation link component for client-side routing
* @param props - Link configuration including destination and options
* @returns Anchor element with router navigation
*/
function Link(props: LinkProps): JSX.Element;
interface LinkProps {
/** Navigation destination */
to: To;
/** Child content to render inside the link */
children?: React.ReactNode;
/** Replace current entry instead of pushing new entry */
replace?: boolean;
/** State object to pass with navigation */
state?: any;
/** Prevent default scroll reset behavior */
preventScrollReset?: boolean;
/** Enable relative path resolution */
relative?: RelativeRoutingType;
/** Standard anchor props */
target?: React.HTMLAttributeAnchorTarget;
className?: string;
style?: React.CSSProperties;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
}
type To = string | Partial<Path>;
interface Path {
/** URL pathname */
pathname: string;
/** URL search parameters */
search: string;
/** URL hash fragment */
hash: string;
}
type RelativeRoutingType = "route" | "path";Usage Examples:
import { Link } from "react-router-dom";
// Basic link
<Link to="/about">About Us</Link>
// Link with state
<Link to="/user" state={{ from: "dashboard" }}>
User Profile
</Link>
// Link with path object
<Link to={{ pathname: "/search", search: "?q=react" }}>
Search React
</Link>
// Replace navigation (no back button)
<Link to="/login" replace>
Login
</Link>Enhanced link component that knows whether it's "active" based on current location.
/**
* Navigation link with active state awareness
* @param props - NavLink configuration with active state handling
* @returns Link component with active state styling support
*/
function NavLink(props: NavLinkProps): JSX.Element;
interface NavLinkProps extends Omit<LinkProps, 'className' | 'style'> {
/** Class name or function returning class name based on active state */
className?: string | ((props: NavLinkRenderProps) => string);
/** Style object or function returning styles based on active state */
style?: React.CSSProperties | ((props: NavLinkRenderProps) => React.CSSProperties);
/** Child content or function returning content based on active state */
children?: React.ReactNode | ((props: NavLinkRenderProps) => React.ReactNode);
/** Only active when location matches exactly */
end?: boolean;
/** Enable case-sensitive matching */
caseSensitive?: boolean;
}
interface NavLinkRenderProps {
/** True if the link matches the current location */
isActive: boolean;
/** True if the link matches the current location but not exactly */
isPending: boolean;
/** True if navigation is currently in progress */
isTransitioning: boolean;
}Usage Examples:
import { NavLink } from "react-router-dom";
// Basic active-aware navigation
<NavLink
to="/dashboard"
className={({ isActive }) => isActive ? "active" : ""}
>
Dashboard
</NavLink>
// Style function
<NavLink
to="/profile"
style={({ isActive }) => ({
color: isActive ? "red" : "blue",
textDecoration: isActive ? "underline" : "none"
})}
>
Profile
</NavLink>
// Children function
<NavLink to="/notifications">
{({ isActive, isPending }) => (
<span>
Notifications
{isPending && " (loading...)"}
{isActive && " (current)"}
</span>
)}
</NavLink>
// Exact matching
<NavLink to="/" end>
Home
</NavLink>Component for programmatic navigation that triggers on render.
/**
* Component that navigates when rendered
* @param props - Navigation destination and options
* @returns Navigation side effect component
*/
function Navigate(props: NavigateProps): null;
interface NavigateProps {
/** Navigation destination */
to: To;
/** Replace current entry instead of pushing */
replace?: boolean;
/** State to pass with navigation */
state?: any;
/** Enable relative path resolution */
relative?: RelativeRoutingType;
}Usage Example:
import { Navigate } from "react-router-dom";
function ProtectedRoute({ user, children }) {
if (!user) {
// Redirect to login if not authenticated
return <Navigate to="/login" replace />;
}
return children;
}Enhanced form component that works with React Router's data loading and actions.
/**
* Form component integrated with router actions and data loading
* @param props - Form configuration with action handling
* @returns Form element with router integration
*/
function Form(props: FormProps): JSX.Element;
interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'action' | 'method'> {
/** Form action URL or relative path. Defaults to current route */
action?: string;
/** HTTP method for form submission */
method?: "get" | "post" | "put" | "patch" | "delete";
/** Form encoding type */
encType?: "application/x-www-form-urlencoded" | "multipart/form-data" | "text/plain";
/** Replace current entry instead of pushing */
replace?: boolean;
/** Enable relative path resolution */
relative?: RelativeRoutingType;
/** Prevent default scroll reset */
preventScrollReset?: boolean;
/** Navigate on successful submission */
navigate?: boolean;
}Usage Examples:
import { Form } from "react-router-dom";
// Basic form with action
<Form method="post" action="/contact">
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send Message</button>
</Form>
// Form with file upload
<Form method="post" encType="multipart/form-data">
<input type="file" name="document" />
<button type="submit">Upload</button>
</Form>
// GET form for search
<Form method="get" action="/search">
<input type="search" name="q" placeholder="Search..." />
<button type="submit">Search</button>
</Form>Component that manages scroll position during navigation.
/**
* Component that manages scroll restoration behavior
* @param props - Scroll restoration configuration
* @returns Scroll management component
*/
function ScrollRestoration(props: ScrollRestorationProps): null;
interface ScrollRestorationProps {
/** Function to get scroll restoration key */
getKey?: GetScrollRestorationKeyFunction;
/** Storage key for scroll positions */
storageKey?: string;
}
type GetScrollRestorationKeyFunction = (
location: Location,
matches: UIMatch[]
) => string | null;
interface UIMatch<Data = unknown, Handle = unknown> {
id: string;
pathname: string;
params: Params;
data: Data;
handle: Handle;
}Usage Example:
import { ScrollRestoration } from "react-router-dom";
function Root() {
return (
<div>
{/* Your app content */}
<Outlet />
{/* Restore scroll position on navigation */}
<ScrollRestoration />
</div>
);
}function ConditionalNavigation({ user, redirectTo }) {
if (!user.isAuthenticated) {
return <Navigate to={redirectTo} replace />;
}
return <Outlet />;
}// Pass state with navigation
<Link
to="/details"
state={{ from: location.pathname, user: currentUser }}
>
View Details
</Link>
// Access state in destination component
function Details() {
const location = useLocation();
const { from, user } = location.state || {};
return (
<div>
<p>Came from: {from}</p>
<p>User: {user?.name}</p>
</div>
);
}// Multiple active states
<nav>
<NavLink
to="/dashboard"
className={({ isActive, isPending }) =>
`nav-link ${isActive ? 'active' : ''} ${isPending ? 'pending' : ''}`
}
>
Dashboard
</NavLink>
</nav>// Form with router action
<Form method="post" action="/api/users">
<input name="name" type="text" />
<input name="email" type="email" />
<button type="submit">Create User</button>
</Form>
// Corresponding route
<Route
path="/users"
element={<Users />}
action={async ({ request }) => {
const formData = await request.formData();
const user = {
name: formData.get("name"),
email: formData.get("email")
};
return await createUser(user);
}}
/>Install with Tessl CLI
npx tessl i tessl/npm-react-router-dom