useLocation is a React hook that returns the current location object, which contains information about the current URL including pathname, search parameters, hash, and navigation state. It’s re-exported from react-router v7.
Always import
useLocation from @tailor-platform/app-shell, not from react-router directly. AppShell manages its own router instance, and importing from the wrong package will cause the hook to return incorrect values.Usage
import { useLocation } from '@tailor-platform/app-shell';
const MyComponent = () => {
const location = useLocation();
return <div>Current path: {location.pathname}</div>;
};
Signature
const location: Location = useLocation();
interface Location {
pathname: string; // Current URL path (e.g., "/orders/123")
search: string; // Query string (e.g., "?tab=details&sort=asc")
hash: string; // URL hash (e.g., "#section")
state: any; // State passed via navigate() or Link
key: string; // Unique key for this location
}
Examples
Access Current Path
import { useLocation } from '@tailor-platform/app-shell';
const Breadcrumbs = () => {
const location = useLocation();
const paths = location.pathname.split('/').filter(Boolean);
return (
<nav>
{paths.map((path, index) => (
<span key={index}>
{index > 0 && ' / '}
{path}
</span>
))}
</nav>
);
};
Access Query Parameters
import { useLocation } from '@tailor-platform/app-shell';
const ProductList = () => {
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const category = searchParams.get('category') || 'all';
const sortBy = searchParams.get('sort') || 'name';
return (
<div>
<h1>Products - Category: {category}</h1>
<p>Sorted by: {sortBy}</p>
</div>
);
};
Track Navigation State
Access state passed from the previous page:import { useLocation, useNavigate } from '@tailor-platform/app-shell';
// Source page
const OrderList = () => {
const navigate = useNavigate();
const createOrder = () => {
navigate('/orders/new', {
state: { returnTo: '/orders', filter: 'pending' }
});
};
return <button onClick={createOrder}>Create Order</button>;
};
// Destination page
const NewOrderPage = () => {
const location = useLocation();
const navigate = useNavigate();
const { returnTo, filter } = location.state || {};
const handleCancel = () => {
if (returnTo) {
navigate(returnTo);
} else {
navigate('/orders');
}
};
return (
<div>
<h1>New Order</h1>
<button onClick={handleCancel}>Cancel</button>
{filter && <p>Will return to {filter} orders</p>}
</div>
);
};
Conditional Rendering Based on Path
import { useLocation } from '@tailor-platform/app-shell';
const Header = () => {
const location = useLocation();
const isOrdersPage = location.pathname.startsWith('/orders');
return (
<header>
<h1>My App</h1>
{isOrdersPage && <OrderFilters />}
</header>
);
};
Highlight Active Navigation Items
import { useLocation, Link } from '@tailor-platform/app-shell';
const Navigation = () => {
const location = useLocation();
const navItems = [
{ path: '/dashboard', label: 'Dashboard' },
{ path: '/orders', label: 'Orders' },
{ path: '/products', label: 'Products' },
];
return (
<nav>
{navItems.map((item) => (
<Link
key={item.path}
to={item.path}
style={{
fontWeight: location.pathname === item.path ? 'bold' : 'normal',
color: location.pathname === item.path ? 'blue' : 'black',
}}
>
{item.label}
</Link>
))}
</nav>
);
};
Sync UI with URL
import { useLocation, useNavigate } from '@tailor-platform/app-shell';
import { useEffect, useState } from 'react';
const TabbedView = () => {
const location = useLocation();
const navigate = useNavigate();
const searchParams = new URLSearchParams(location.search);
const activeTab = searchParams.get('tab') || 'details';
const setActiveTab = (tab: string) => {
const newParams = new URLSearchParams(location.search);
newParams.set('tab', tab);
navigate(`${location.pathname}?${newParams.toString()}`);
};
return (
<div>
<div>
<button onClick={() => setActiveTab('details')}>Details</button>
<button onClick={() => setActiveTab('history')}>History</button>
<button onClick={() => setActiveTab('notes')}>Notes</button>
</div>
{activeTab === 'details' && <DetailsTab />}
{activeTab === 'history' && <HistoryTab />}
{activeTab === 'notes' && <NotesTab />}
</div>
);
};
Analytics and Tracking
import { useLocation } from '@tailor-platform/app-shell';
import { useEffect } from 'react';
const Analytics = () => {
const location = useLocation();
useEffect(() => {
// Track page view
analytics.track('page_view', {
path: location.pathname,
search: location.search,
});
}, [location.pathname, location.search]);
return null;
};
Scroll Restoration
import { useLocation } from '@tailor-platform/app-shell';
import { useEffect, useRef } from 'react';
const ScrollManager = () => {
const location = useLocation();
const prevLocation = useRef(location);
useEffect(() => {
// Scroll to top on route change (unless hash is present)
if (location.pathname !== prevLocation.current.pathname) {
if (!location.hash) {
window.scrollTo(0, 0);
}
}
prevLocation.current = location;
}, [location]);
return null;
};
Working with Search Parameters
Using URLSearchParams
import { useLocation } from '@tailor-platform/app-shell';
const FilteredList = () => {
const location = useLocation();
const params = new URLSearchParams(location.search);
// Get single value
const category = params.get('category');
// Get multiple values
const tags = params.getAll('tag');
// Check if param exists
const hasSort = params.has('sort');
// Get all params as object
const allParams = Object.fromEntries(params.entries());
return (
<div>
<p>Category: {category}</p>
<p>Tags: {tags.join(', ')}</p>
<p>Has sort: {hasSort.toString()}</p>
<pre>{JSON.stringify(allParams, null, 2)}</pre>
</div>
);
};
Updating Query Parameters
import { useLocation, useNavigate } from '@tailor-platform/app-shell';
const SearchFilters = () => {
const location = useLocation();
const navigate = useNavigate();
const updateFilter = (key: string, value: string) => {
const params = new URLSearchParams(location.search);
params.set(key, value);
navigate(`${location.pathname}?${params.toString()}`);
};
const removeFilter = (key: string) => {
const params = new URLSearchParams(location.search);
params.delete(key);
navigate(`${location.pathname}?${params.toString()}`);
};
return (
<div>
<input
type="text"
onChange={(e) => updateFilter('search', e.target.value)}
placeholder="Search..."
/>
<button onClick={() => removeFilter('search')}>Clear</button>
</div>
);
};
Comparison with Other Hooks
| Use Case | Hook |
|---|---|
| Get current URL path | useLocation() |
Get route parameters (:id) | useParams() |
| Navigate programmatically | useNavigate() |
| Get and set search params | useSearchParams() |
Common Patterns
Create a Custom Hook for Query Params
import { useLocation } from '@tailor-platform/app-shell';
import { useMemo } from 'react';
function useQueryParams() {
const location = useLocation();
return useMemo(
() => new URLSearchParams(location.search),
[location.search]
);
}
// Usage
const MyComponent = () => {
const params = useQueryParams();
const tab = params.get('tab') || 'default';
return <div>Active tab: {tab}</div>;
};
Preserve Query Params on Navigation
import { useLocation, useNavigate } from '@tailor-platform/app-shell';
const ProductCard = ({ productId }) => {
const location = useLocation();
const navigate = useNavigate();
const viewProduct = () => {
// Preserve existing query params when navigating
navigate(`/products/${productId}${location.search}`);
};
return <button onClick={viewProduct}>View Product</button>;
};
Related Hooks
useNavigate- Programmatic navigationuseParams- Access route parameters
See Also
- Routing and Navigation Guide
- Location API - React Router v7 documentation