Перейти к содержимому

3. Файловая маршрутизация

В Remix маршруты определяются структурой файлов в папке app/routes/. Каждый файл — это отдельный маршрут. Никаких конфигурационных файлов с перечислением маршрутов.

app/routes/
_index.tsx → /
about.tsx → /about
contact.tsx → /contact
blog.tsx → /blog (layout для /blog/*)
blog._index.tsx → /blog
blog.$slug.tsx → /blog/:slug

Точки в именах файлов создают вложенные сегменты URL:

user.profile.tsx → /user/profile
user.settings.tsx → /user/settings
admin.users.$id.tsx → /admin/users/:id

Это НЕ вложенные маршруты в смысле Outlet — просто сегменты URL.

Символ $ обозначает динамический параметр:

// app/routes/blog.$slug.tsx
import { useParams } from "@remix-run/react";
export default function BlogPost() {
const { slug } = useParams();
return <h1>Статья: {slug}</h1>;
}
// Или через loader:
export async function loader({ params }) {
const post = await getPost(params.slug);
return json(post);
}

Для настоящей вложенности (с <Outlet>) файлы помещаются в папки:

app/routes/
dashboard.tsx → layout для /dashboard/*
dashboard._index.tsx → /dashboard
dashboard.stats.tsx → /dashboard/stats
dashboard.users.tsx → /dashboard/users

Родительский маршрут рендерит <Outlet>:

app/routes/dashboard.tsx
import { Outlet, NavLink } from "@remix-run/react";
export default function Dashboard() {
return (
<div>
<nav>
<NavLink to="/dashboard/stats">Статистика</NavLink>
<NavLink to="/dashboard/users">Пользователи</NavLink>
</nav>
<main>
<Outlet /> {/* дочерние маршруты */}
</main>
</div>
);
}
ПаттернЗначение
_index.tsxIndex route (без суффикса)
_layout.tsxPathless layout (не добавляет сегмент URL)
$.tsxSplat route (ловит всё)
[brackets].tsxЭкранирование спецсимволов

Подчёркивание делает маршрут “невидимым” в URL:

app/routes/
_auth.tsx → layout (без URL)
_auth.login.tsx → /login
_auth.register.tsx → /register