Supported Routers
Refine officially supports:- React Router v6+ - Most popular React routing library
- Next.js Router - For Next.js applications (Pages and App Router)
- Remix Router - For Remix applications
- Expo Router - Community package for React Native
Understanding Router Providers
A router provider connects Refine with your routing library:Quick Setup
resources={[
{
name: "posts",
list: "/posts", // List page route
create: "/posts/create", // Create page route
edit: "/posts/edit/:id", // Edit page route
show: "/posts/show/:id", // Show page route
meta: {
canDelete: true, // Enable delete actions
label: "Blog Posts", // Display name in menus
icon: <PostIcon />, // Icon for navigation
},
},
{
name: "categories",
list: "/categories",
},
]}
Navigation Hooks
useNavigation
Navigate between pages programmatically:useGo
Lower-level navigation with more control:useBack
Navigate to the previous page:useLink
Get the Link component from the router provider:Reading Route Parameters
useResource
Get current resource information from the route:useParsed
Get parsed route information:useResourceParams
Get resource-specific route parameters:URL State Management
Refine automatically syncs state with URL parameters whensyncWithLocation is enabled:
- Pagination (page, pageSize)
- Filters
- Sorters
- Search parameters
In Tables
In Forms
Custom Router Integration
Create a custom router provider:import { RouterProvider } from "@refinedev/core";
import { useNavigate, useLocation, useParams } from "your-router";
const customRouterProvider: RouterProvider = {
go: () => {
const navigate = useNavigate();
return ({ to, query, hash, options, type }) => {
// Build the URL
let path = to || "";
// Add query parameters
if (query) {
const searchParams = new URLSearchParams();
Object.entries(query).forEach(([key, value]) => {
searchParams.append(key, String(value));
});
path += `?${searchParams.toString()}`;
}
// Add hash
if (hash) {
path += `#${hash}`;
}
// Navigate
if (type === "path") {
return path;
}
navigate(path, { replace: type === "replace" });
};
},
back: () => {
const navigate = useNavigate();
return () => navigate(-1);
},
parse: () => {
const location = useLocation();
const params = useParams();
return () => {
// Parse the current route
const { pathname, search } = location;
const queryParams = new URLSearchParams(search);
return {
pathname,
params: {
...params,
...Object.fromEntries(queryParams),
},
// Match resource and action from pathname
resource: undefined, // Implement resource matching
action: undefined, // Implement action matching
id: params.id,
};
};
},
Link: ({ to, children }) => {
const Link = useLink(); // Your router's Link component
return <Link to={to}>{children}</Link>;
},
};
Framework-Specific Patterns
React Router - Protected Routes
Next.js - Middleware for Auth
middleware.ts
Next.js - Dynamic Routes
app/posts/[id]/page.tsx
Remix - Loaders for Data Fetching
app/routes/posts.$id.tsx
Navigation Components
Breadcrumbs
Menu Items
Best Practices
- Use resource definitions - Define all routes in resource config for consistency
- Enable syncWithLocation - Keep URL in sync with table/form state
- Use navigation hooks - Don’t construct URLs manually
- Handle loading states - Show loading indicators during navigation
- Implement 404 pages - Handle unknown routes gracefully
- Use protected routes - Secure authenticated pages properly
- Preserve query params - Use
keepQuerywhen navigating
Common Patterns
Redirecting After Actions
Query Parameter Filters
Modal Forms with Route Sync
Troubleshooting
Routes Not Matching
Ensure resource routes match your actual route definitions:Query Params Not Syncing
EnablesyncWithLocation in both Refine and hooks:
Next Steps
- Learn about Forms
- Explore Authentication
- Discover Tables