В веб-приложениях часто возникает необходимость после авторизации или выполнения определённого действия возвращать пользователя на страницу, с которой он пришёл. TanStack Router предоставляет гибкие механизмы для работы с редиректами и сохранением исходного URL.
Каждый маршрут в TanStack Router может хранить состояние через объект
state. Для сохранения redirect URL чаще всего используют
ключ from, который указывает исходный путь пользователя до
перенаправления.
Пример:
import { useNavigate, useLocation } from '@tanstack/router';
function Login() {
const navigate = useNavigate();
const location = useLocation();
const handleLogin = async () => {
await performLogin();
// Определяем исходный путь
const redirectTo = location.state?.from || '/dashboard';
navigate({ to: redirectTo });
};
return (
<button onCl ick={handleLogin}>Войти</button>
);
}
В этом примере при переходе на страницу логина можно передавать
исходный путь через state:
navigate({ to: '/login', state: { from: location.pathname } });
Таким образом, после успешной авторизации пользователь автоматически вернётся на страницу, с которой начинал работу.
Другой подход — передавать URL через query-параметры. Это полезно, когда состояние маршрута не сохраняется при перезагрузке страницы:
import { useSearch } from '@tanstack/router';
function Login() {
const search = useSearch();
const navigate = useNavigate();
const handleLogin = async () => {
await performLogin();
const redirectTo = search.redirect || '/dashboard';
navigate({ to: redirectTo });
};
return (
<button onCl ick={handleLogin}>Войти</button>
);
}
Переход на страницу логина с сохранением исходного URL:
navigate({ to: '/login', search: { redirect: location.pathname } });
Преимущество такого метода — URL всегда виден в адресной строке и доступен после полной перезагрузки страницы.
loader и редиректов для защищённых маршрутовTanStack Router позволяет использовать асинхронные
loader функции для проверки доступа к маршруту. Если
пользователь не авторизован, loader может инициировать
редирект с сохранением исходного пути:
import { redirect } from '@tanstack/router';
async function protectedLoader({ context, params }) {
const user = await context.getCurrentUser();
if (!user) {
return redirect('/login', { state: { from: window.location.pathname } });
}
return user;
}
Здесь redirect передаёт исходный путь через
state, что позволяет после авторизации вернуть пользователя
обратно.
Для крупных приложений удобнее централизованно обрабатывать редиректы через middleware. Это позволяет не дублировать логику проверки авторизации на каждом маршруте:
router.use(({ next }) => {
const user = getCurrentUser();
if (!user && next.route.meta.requiresAuth) {
return redirect('/login', { state: { from: window.location.pathname } });
}
return next();
});
Такой подход делает маршрутизацию более предсказуемой и упрощает поддержку приложения.
Выбор способа хранения URL:
state маршрута подходит для SPA без перезагрузок.Обработка отсутствующего redirect URL: Всегда
указывайте fallback, например /dashboard, чтобы избежать
ошибок при навигации.
Безопасность: Не используйте непроверенные
внешние URL для редиректа, чтобы исключить открытые редиректы. Лучше
проверять, что redirectTo принадлежит вашему
приложению.
Эти подходы позволяют гибко управлять сохранением redirect URL в TanStack Router, обеспечивая корректную навигацию и удобство работы пользователя с приложением.