useNavigate is a React hook that provides programmatic navigation within your AppShell application. It’s re-exported from react-router v7 and is essential for navigating between pages in response to user actions.
Always import useNavigate from @tailor-platform/app-shell, not from react-router directly. AppShell manages its own router instance, and importing from the wrong package will cause navigation to fail.
Usage
import { useNavigate } from '@tailor-platform/app-shell';
const MyComponent = () => {
const navigate = useNavigate();
const handleClick = () => {
// Navigate to a route
navigate('/dashboard/overview');
};
return <button onClick={handleClick}>Go to Dashboard</button>;
};
Signature
const navigate: NavigateFunction = useNavigate();
type NavigateFunction = (
to: string | number,
options?: NavigateOptions
) => void;
interface NavigateOptions {
replace?: boolean; // Replace current entry in history
state?: any; // Pass state to the new location
preventScrollReset?: boolean; // Prevent scroll reset on navigation
relative?: 'route' | 'path'; // Relative path resolution strategy
}
Examples
Basic Navigation
import { useNavigate } from '@tailor-platform/app-shell';
const ProductList = () => {
const navigate = useNavigate();
const viewProduct = (productId: string) => {
navigate(`/products/${productId}`);
};
return (
<div>
<button onClick={() => viewProduct('123')}>View Product</button>
</div>
);
};
Navigate with Replace
Use replace: true to replace the current history entry instead of adding a new one:
const LoginPage = () => {
const navigate = useNavigate();
const handleLogin = async (credentials) => {
await loginUser(credentials);
// Replace login page in history so back button doesn't return to login
navigate('/dashboard', { replace: true });
};
return <LoginForm onSubmit={handleLogin} />;
};
Navigate with State
Pass data to the destination route using the state option:
import { useNavigate, useLocation } from '@tailor-platform/app-shell';
// Source component
const OrderList = () => {
const navigate = useNavigate();
const createOrder = () => {
navigate('/orders/new', {
state: { from: 'order-list', timestamp: Date.now() }
});
};
return <button onClick={createOrder}>Create Order</button>;
};
// Destination component
const NewOrderPage = () => {
const location = useLocation();
const { from, timestamp } = location.state || {};
return (
<div>
<h1>New Order</h1>
{from && <p>Navigated from: {from}</p>}
</div>
);
};
Navigate Back
Use negative numbers to navigate backward in history:
const ProductDetail = () => {
const navigate = useNavigate();
return (
<div>
<button onClick={() => navigate(-1)}>← Back</button>
<h1>Product Details</h1>
</div>
);
};
Dynamic Routes with Params
import { useNavigate, useParams } from '@tailor-platform/app-shell';
const OrderDetail = () => {
const navigate = useNavigate();
const { id } = useParams();
const goToEditPage = () => {
navigate(`/orders/${id}/edit`);
};
return (
<div>
<h1>Order {id}</h1>
<button onClick={goToEditPage}>Edit Order</button>
</div>
);
};
Type-Safe Navigation with Generated Routes
When using file-based routing with the Vite plugin, you can generate type-safe route helpers:
import { useNavigate } from '@tailor-platform/app-shell';
import { paths } from './routes.generated';
const MyComponent = () => {
const navigate = useNavigate();
// ✅ Type-checked path and params
const goToOrder = (orderId: string) => {
navigate(paths.for('/orders/:id', { id: orderId }));
};
// ✅ Static routes
const goToDashboard = () => {
navigate(paths.for('/dashboard'));
};
return (
<div>
<button onClick={() => goToOrder('123')}>View Order</button>
<button onClick={goToDashboard}>Dashboard</button>
</div>
);
};
Common Patterns
Conditional Navigation
const handleSubmit = async (formData) => {
const result = await saveData(formData);
if (result.success) {
navigate('/success');
} else {
navigate('/error', { state: { error: result.error } });
}
};
Navigation with Confirmation
const DeleteButton = ({ itemId }) => {
const navigate = useNavigate();
const handleDelete = async () => {
if (window.confirm('Are you sure?')) {
await deleteItem(itemId);
navigate('/items');
}
};
return <button onClick={handleDelete}>Delete</button>;
};
Comparison with Link Component
| Use Case | Use |
|---|
| User clicks a link or button | <Link to="/path"> |
| Navigate after form submission | navigate('/path') |
| Navigate after API call | navigate('/path') |
| Conditional navigation based on logic | navigate('/path') |
| Navigate backward | navigate(-1) |
See Also