TanStack Router предоставляет гибкую архитектуру для управления маршрутизацией как на клиенте, так и на сервере. Серверная навигация становится особенно актуальной в приложениях с SSR (Server-Side Rendering) и при построении изоморфных приложений, где один и тот же маршрут должен корректно обрабатываться как на сервере, так и в браузере.
На сервере маршруты определяются аналогично клиентской стороне с
использованием объекта createRouter. Ключевым отличием
является необходимость подготовки данных до рендеринга страницы, что
обеспечивает корректное формирование HTML с уже загруженным
контентом.
import { createRouter, createRouteConfig } from '@tanstack/router';
import express from 'express';
import { renderToString } from 'react-dom/server';
import App from './App';
const routeConfig = createRouteConfig()
.createRoute({
path: '/',
component: App,
loader: async () => {
const data = await fetchDataForHome();
return data;
},
});
const router = createRouter({ routeConfig });
Ключевой момент: функция loader на
сервере вызывается до рендеринга, что позволяет серверу предоставлять
готовые данные вместе с HTML, минимизируя количество клиентских запросов
после загрузки страницы.
Маршруты на сервере могут принимать динамические сегменты пути и
query-параметры. TanStack Router предоставляет объект
context для передачи информации о запросе:
const routeConfig = createRouteConfig()
.createRoute({
path: '/users/:id',
loader: async ({ params, request }) => {
const { id } = params;
const userData = await fetchUserById(id);
return userData;
},
});
params содержит значения динамических сегментов, а
request — экземпляр запроса, что позволяет учитывать
заголовки, cookies или query-параметры при генерации контента.
TanStack Router интегрируется с React Query и другими библиотеками
управления состоянием для организации серверного рендеринга с
предзагрузкой данных. Использование loader в комбинации с
React Query позволяет кешировать данные на сервере и передавать их на
клиент:
import { QueryClient, dehydrate } from '@tanstack/react-query';
const queryClient = new QueryClient();
const routeConfig = createRouteConfig()
.createRoute({
path: '/posts',
loader: async () => {
await queryClient.prefetchQuery(['posts'], fetchPosts);
return dehydrate(queryClient);
},
});
Такой подход гарантирует, что клиент получит полностью подготовленное состояние, что ускоряет рендеринг и уменьшает количество сетевых запросов после загрузки страницы.
TanStack Router поддерживает серверные редиректы через специальное
исключение redirect. Вызов редиректа в loader
позволяет перенаправить пользователя до того, как страница будет
сгенерирована:
import { redirect } from '@tanstack/router';
const routeConfig = createRouteConfig()
.createRoute({
path: '/protected',
loader: async ({ request }) => {
const isAuthenticated = checkAuth(request);
if (!isAuthenticated) {
throw redirect('/login');
}
return null;
},
});
Важно: на сервере редирект должен быть обработан
соответствующим образом в маршрутизаторе Express, Fastify или любом
другом серверном фреймворке, чтобы корректно вернуть статус 302 и
заголовок Location.
Для серверной навигации TanStack Router позволяет централизованно
обрабатывать ошибки через errorBoundary или перехват
исключений в loader:
const routeConfig = createRouteConfig()
.createRoute({
path: '/dashboard',
loader: async () => {
try {
const data = await fetchDashboardData();
return data;
} catch (error) {
throw new Error('Ошибка загрузки данных для Dashboard');
}
},
errorComponent: DashboardError,
});
Серверный рендеринг передает состояние ошибки в компонент
errorComponent, что обеспечивает единый способ отображения
ошибок как на сервере, так и на клиенте.
TanStack Router легко интегрируется с популярными SSR-фреймворками, включая Next.js и Remix. В таких сценариях важно правильно передавать маршрутизатор и данные через контекст сервера:
app.get('*', async (req, res) => {
const context = { request: req };
const initialData = await router.load({ url: req.url, context });
const html = renderToString( );
res.send(`${html}`);
});
Такой подход обеспечивает корректную маршрутизацию, предзагрузку данных и обработку редиректов на уровне сервера.
Для больших приложений серверная навигация требует внимания к
производительности. TanStack Router позволяет кэшировать результаты
loader с помощью React Query или собственного механизма
мемоизации, снижая нагрузку на сервер и ускоряя генерацию страниц.