Remix ルーティング早見表:ネスト・可変パラメータ・モーダルルート対応一覧

Remix のファイルシステムベースルーティングは、シンプルで直感的な設計が魅力ですが、ネスト構造や可変パラメータ、モーダル表示など、少し複雑なパターンになると「この場合はどうファイルを配置すればいいの?」と迷うことも多いですよね。
この記事では、Remix のルーティングパターンを体系的に整理し、実際のファイル配置とそれに対応する URL パスを一覧表でまとめました。基本パターンから、ネストレイアウト、動的パラメータ、パスなしレイアウト、モーダルルートまで、網羅的に解説します。この早見表を参考にすれば、どんなルーティング要件にも素早く対応できるようになるでしょう。
ルーティングパターン早見表
全パターン一覧
# | カテゴリ | ファイルパス | URL パス | パラメータ | 説明 |
---|---|---|---|---|---|
1 | 基本 | app/routes/_index.tsx | / | - | トップページ |
2 | 基本 | app/routes/about.tsx | /about | - | 単一の静的ページ |
3 | 基本 | app/routes/contact.tsx | /contact | - | 単一の静的ページ |
4 | 基本 | app/routes/blog._index.tsx | /blog | - | /blog のインデックスページ |
5 | 基本 | app/routes/blog.posts.tsx | /blog/posts | - | /blog/posts ページ |
6 | 動的 | app/routes/users.$userId.tsx | /users/:userId | userId | ユーザー詳細ページ |
7 | 動的 | app/routes/posts.$postId.tsx | /posts/:postId | postId | 投稿詳細ページ |
8 | 動的 | app/routes/products.$productId.tsx | /products/:productId | productId | 商品詳細ページ |
9 | 動的 | app/routes/blog.$slug.tsx | /blog/:slug | slug | ブログ記事ページ |
10 | 動的 | app/routes/users.$userId.edit.tsx | /users/:userId/edit | userId | ユーザー編集ページ |
11 | ネスト | app/routes/blog.tsx | /blog | - | 親レイアウト(Outlet で子を表示) |
12 | ネスト | app/routes/blog._index.tsx | /blog | - | /blog のインデックス |
13 | ネスト | app/routes/blog.posts.tsx | /blog/posts | - | ブログ投稿一覧 |
14 | ネスト | app/routes/blog.posts.$postId.tsx | /blog/posts/:postId | postId | ブログ投稿詳細 |
15 | ネスト | app/routes/blog.posts.$postId.edit.tsx | /blog/posts/:postId/edit | postId | ブログ投稿編集 |
16 | パスなし | app/routes/_app.tsx | - | - | レイアウトのみ(URL に現れない) |
17 | パスなし | app/routes/_app.dashboard.tsx | /dashboard | - | _app レイアウトを継承 |
18 | パスなし | app/routes/_app.settings.tsx | /settings | - | _app レイアウトを継承 |
19 | パスなし | app/routes/_auth.tsx | - | - | 認証レイアウト |
20 | パスなし | app/routes/_auth.login.tsx | /login | - | ログインページ(_auth レイアウトを継承) |
21 | パスなし | app/routes/_auth.register.tsx | /register | - | 登録ページ(_auth レイアウトを継承) |
22 | Splat | app/routes/$.tsx | /* | * | すべてのパスをキャッチ |
23 | Splat | app/routes/docs.$.tsx | /docs/* | * | /docs 配下の全パスをキャッチ |
24 | Splat | app/routes/files.$path.$.tsx | /files/:path/* | path , * | 複数セグメントをキャッチ |
25 | モーダル | app/routes/photos.tsx | /photos | - | 写真一覧ページ |
26 | モーダル | app/routes/photos.$photoId.modal.tsx | /photos/:photoId | photoId | モーダルで写真詳細を表示 |
27 | モーダル | app/routes/products.tsx | /products | - | 商品一覧ページ |
28 | モーダル | app/routes/products.$productId.modal.tsx | /products/:productId | productId | モーダルで商品詳細を表示 |
29 | 複合 | app/routes/users.$userId.posts.$postId.tsx | /users/:userId/posts/:postId | userId , postId | ユーザーの投稿詳細 |
30 | 複合 | app/routes/orgs.$orgId.projects.$projectId.tsx | /orgs/:orgId/projects/:projectId | orgId , projectId | 組織のプロジェクト詳細 |
31 | 複合 | app/routes/stores.$storeId.products.$productId.tsx | /stores/:storeId/products/:productId | storeId , productId | 店舗の商品詳細 |
記号の役割早見表
記号 | 役割 | 例 | URL パス |
---|---|---|---|
. | パスの区切り | blog.posts.tsx | /blog/posts |
$ | 動的パラメータ | $userId.tsx | /:userId |
_ (プレフィックス) | パスなしレイアウト | _app.tsx | URL に影響なし |
_index | インデックスルート | blog._index.tsx | /blog |
() | グループ化(整理用) | (auth).login.tsx | /login |
$.tsx | Splat ルート | $.tsx | /* (全パス) |
背景
ファイルシステムベースルーティングとは
Remix は Next.js のページルーターと同様に、app/routes
ディレクトリ内のファイル構造がそのままアプリケーションのルーティング構造に反映される ファイルシステムベースルーティング を採用しています。
この方式では、app/routes/about.tsx
というファイルを作成すれば、自動的に /about
というパスでアクセスできるページが生成されます。コード上でルート定義を行う必要がなく、視覚的にルーティング構造を把握できるのが最大の利点です。
Remix ルーティングの特徴
Remix のルーティングには、以下のような独自の特徴があります。
- ネストレイアウト: 親ルートのレイアウトを継承しながら子ルートをレンダリング
- 可変パラメータ:
$
記号を使った動的セグメント(例:$userId
) - パスなしレイアウト: URL に影響せず、レイアウトだけを共有する
_
プレフィックス - Splat ルート:
$
で残りの全パスをキャッチ - モーダル/並列ルート: 同じ URL で複数のコンポーネントを表示
これらのパターンを組み合わせることで、複雑な UI 構造も柔軟に実現できます。
以下の図は、Remix のファイル構造が URL パスとどう対応するかを示しています。
mermaidflowchart TD
routes["app/routes/"] --> index["index.tsx<br/>→ /"]
routes --> about["about.tsx<br/>→ /about"]
routes --> blog["blog.tsx<br/>→ /blog"]
blog --> blogIndex["blog._index.tsx<br/>→ /blog"]
blog --> blogPost["blog.$postId.tsx<br/>→ /blog/:postId"]
routes --> user["users.$userId.tsx<br/>→ /users/:userId"]
この図から分かるように、ファイル名の .
がパスの /
に、$
が動的パラメータに変換されます。
課題
ルーティングパターンの複雑さ
Remix のファイルベースルーティングは直感的ですが、以下のような課題があります。
- ネストが深くなると命名規則が分かりにくい:
blog.posts.$postId.edit.tsx
のようなファイル名が長くなる - 特殊記号の意味を覚える必要がある:
$
、_
、()
などの記号が持つ役割を理解していないと混乱する - レイアウト共有とパス構造の関係が複雑: パスなしレイアウトを使う場合と使わない場合で、ファイル配置が大きく変わる
- モーダルや並列ルートの実装方法が分かりにくい: 同じ URL で複数のコンポーネントをどう表示するか
これらの課題により、実装時に「このファイル名で本当に正しいのか?」と不安になったり、試行錯誤に時間がかかったりすることが多くなります。
以下の図は、ファイル名の記号とその役割を整理したものです。
mermaidflowchart LR
file["ファイル名記号"] --> dot["「.」<br/>パス区切り"]
file --> dollar["「$」<br/>動的パラメータ"]
file --> underscore["「_」<br/>パスなしレイアウト"]
file --> paren["「()」<br/>グループ化"]
dot --> dotEx["/blog/posts"]
dollar --> dollarEx["/:userId/:postId"]
underscore --> underEx["URL に影響なし"]
paren --> parenEx["整理用"]
情報の散在
公式ドキュメントには各機能の説明がありますが、実際のファイル構造と URL の対応を一覧で確認できる資料は少なく、複数のページを行き来しながら理解する必要があります。
特に以下のような情報が欲しい場面で困ることが多いでしょう。
- 「この URL 構造を実現するには、どんなファイル名にすればいい?」
- 「このファイル名だと、どんな URL でアクセスできる?」
- 「ネストレイアウトと可変パラメータを組み合わせるには?」
解決策
ルーティングパターンの体系化
この記事では、Remix の主要なルーティングパターンを 機能別・構造別 に分類し、以下の情報を一覧表でまとめました。
- ファイルパス:
app/routes
内のファイル配置 - URL パス: アクセス可能な URL
- パラメータ: 動的パラメータの受け取り方
- 用途・説明: そのパターンの使いどころ
一覧表を参照すれば、目的のルーティング構造を実現するためのファイル名がすぐに分かります。
記号の役割の明確化
Remix のルーティングで使われる記号とその役割を以下にまとめます。
記号 | 役割 | 例 |
---|---|---|
. | パスの区切り(/ に変換される) | blog.posts.tsx → /blog/posts |
$ | 動的パラメータ | $userId.tsx → /:userId |
_ | パスなしレイアウト | _layout.tsx → URL に影響なし |
() | グループ化(整理用) | (auth).login.tsx → /login |
_index | インデックスルート | blog._index.tsx → /blog |
$.tsx | Splat ルート(全パスキャッチ) | $.tsx → /any/path/here |
これらの記号を組み合わせることで、柔軟なルーティング構造を構築できます。
以下の図は、記号を組み合わせた実例を示しています。
mermaidflowchart TD
example["ファイル名例"]
example --> ex1["blog.posts.$postId.edit.tsx"]
example --> ex2["_app.dashboard.tsx"]
example --> ex3["users.$userId.$.tsx"]
ex1 --> ex1Path["/blog/posts/:postId/edit"]
ex2 --> ex2Path["/dashboard<br/>(レイアウト共有)"]
ex3 --> ex3Path["/users/:userId/*"]
早見表の提供
次のセクションでは、以下のカテゴリに分けて早見表を提供します。
- 基本ルート: 静的パス、インデックスルート
- 動的ルート: 可変パラメータ、複数パラメータ
- ネストルート: レイアウト共有、深いネスト
- パスなしレイアウト:
_
プレフィックスを使ったレイアウト共有 - Splat ルート: 残りの全パスをキャッチ
- モーダル・並列ルート: URL を変えずに複雑な UI を実現
具体例
基本ルート
基本的な静的パスとインデックスルートのパターンです。
# | ファイルパス | URL パス | 説明 |
---|---|---|---|
1 | app/routes/_index.tsx | / | トップページ |
2 | app/routes/about.tsx | /about | 単一の静的ページ |
3 | app/routes/contact.tsx | /contact | 単一の静的ページ |
4 | app/routes/blog._index.tsx | /blog | /blog のインデックスページ |
5 | app/routes/blog.posts.tsx | /blog/posts | /blog/posts ページ |
コード例:トップページ
app/routes/_index.tsx
はサイトのトップページを定義します。
typescript// app/routes/_index.tsx
import type { MetaFunction } from '@remix-run/node';
export const meta: MetaFunction = () => {
return [
{ title: 'ホーム - My Remix App' },
{
name: 'description',
content: 'Remix アプリのトップページです',
},
];
};
メタ情報とローダー
メタ情報を定義し、SEO に最適化します。
typescriptexport default function Index() {
return (
<div>
<h1>ようこそ、My Remix App へ</h1>
<p>Remix のルーティングを活用したサイトです。</p>
</div>
);
}
コード例:静的ページ
app/routes/about.tsx
は /about
にアクセスできる静的ページです。
typescript// app/routes/about.tsx
export default function About() {
return (
<div>
<h1>About Us</h1>
<p>このサイトについて説明します。</p>
</div>
);
}
動的ルート
URL パラメータを受け取る動的ルートのパターンです。
# | ファイルパス | URL パス | パラメータ | 説明 |
---|---|---|---|---|
6 | app/routes/users.$userId.tsx | /users/:userId | userId | ユーザー詳細ページ |
7 | app/routes/posts.$postId.tsx | /posts/:postId | postId | 投稿詳細ページ |
8 | app/routes/products.$productId.tsx | /products/:productId | productId | 商品詳細ページ |
9 | app/routes/blog.$slug.tsx | /blog/:slug | slug | ブログ記事ページ |
10 | app/routes/users.$userId.edit.tsx | /users/:userId/edit | userId | ユーザー編集ページ |
コード例:ユーザー詳細ページ
app/routes/users.$userId.tsx
でユーザー ID を受け取り、データを表示します。
typescript// app/routes/users.$userId.tsx
import {
json,
type LoaderFunctionArgs,
} from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
// ローダーでパラメータを受け取る
export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const userId = params.userId;
// ユーザーデータの取得(実際は DB や API から取得)
const user = {
id: userId,
name: '山田太郎',
email: 'taro@example.com',
};
return json({ user });
};
コンポーネントでのデータ表示
ローダーから取得したデータを表示します。
typescriptexport default function UserDetail() {
const { user } = useLoaderData<typeof loader>();
return (
<div>
<h1>{user.name} のプロフィール</h1>
<p>ID: {user.id}</p>
<p>Email: {user.email}</p>
</div>
);
}
ネストルート
親子関係を持つルートで、レイアウトを共有するパターンです。
# | ファイルパス | URL パス | パラメータ | 説明 |
---|---|---|---|---|
11 | app/routes/blog.tsx | /blog | - | 親レイアウト(Outlet で子を表示) |
12 | app/routes/blog._index.tsx | /blog | - | /blog のインデックス |
13 | app/routes/blog.posts.tsx | /blog/posts | - | ブログ投稿一覧 |
14 | app/routes/blog.posts.$postId.tsx | /blog/posts/:postId | postId | ブログ投稿詳細 |
15 | app/routes/blog.posts.$postId.edit.tsx | /blog/posts/:postId/edit | postId | ブログ投稿編集 |
コード例:親レイアウト
app/routes/blog.tsx
は /blog
配下のすべてのページに共通するレイアウトを定義します。
typescript// app/routes/blog.tsx
import { Outlet } from '@remix-run/react';
export default function BlogLayout() {
return (
<div>
<header>
<h1>ブログ</h1>
<nav>
<a href='/blog'>トップ</a> |{' '}
<a href='/blog/posts'>記事一覧</a>
</nav>
</header>
<main>
{/* 子ルートがここに表示される */}
<Outlet />
</main>
<footer>© 2025 My Blog</footer>
</div>
);
}
Outlet の役割
<Outlet />
は子ルートのコンポーネントをレンダリングする場所を示します。
コード例:子ルート
app/routes/blog.posts.$postId.tsx
は親レイアウト内に表示されます。
typescript// app/routes/blog.posts.$postId.tsx
import {
json,
type LoaderFunctionArgs,
} from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const postId = params.postId;
const post = {
id: postId,
title: 'Remix 入門',
content: 'Remix の使い方を解説します。',
};
return json({ post });
};
データの表示
typescriptexport default function BlogPost() {
const { post } = useLoaderData<typeof loader>();
return (
<article>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
);
}
以下の図は、ネストルートのレンダリング構造を示しています。
mermaidflowchart TD
root["blog.tsx<br/>(親レイアウト)"] --> outlet["Outlet"]
outlet --> index["blog._index.tsx<br/>/blog"]
outlet --> posts["blog.posts.$postId.tsx<br/>/blog/posts/:postId"]
outlet --> edit["blog.posts.$postId.edit.tsx<br/>/blog/posts/:postId/edit"]
パスなしレイアウト
URL に影響を与えずにレイアウトを共有する _
プレフィックスのパターンです。
# | ファイルパス | URL パス | 説明 |
---|---|---|---|
16 | app/routes/_app.tsx | - | レイアウトのみ(URL に現れない) |
17 | app/routes/_app.dashboard.tsx | /dashboard | _app レイアウトを継承 |
18 | app/routes/_app.settings.tsx | /settings | _app レイアウトを継承 |
19 | app/routes/_auth.tsx | - | 認証レイアウト |
20 | app/routes/_auth.login.tsx | /login | ログインページ(_auth レイアウトを継承) |
21 | app/routes/_auth.register.tsx | /register | 登録ページ(_auth レイアウトを継承) |
コード例:パスなしレイアウト
app/routes/_app.tsx
は URL に現れませんが、レイアウトを提供します。
typescript// app/routes/_app.tsx
import { Outlet } from '@remix-run/react';
export default function AppLayout() {
return (
<div>
<aside>
<nav>
<a href='/dashboard'>ダッシュボード</a>
<a href='/settings'>設定</a>
</nav>
</aside>
<main>
<Outlet />
</main>
</div>
);
}
子ルートの定義
app/routes/_app.dashboard.tsx
は /dashboard
でアクセスでき、_app
レイアウトを継承します。
typescript// app/routes/_app.dashboard.tsx
export default function Dashboard() {
return (
<div>
<h1>ダッシュボード</h1>
<p>アプリのメイン画面です。</p>
</div>
);
}
コード例:認証レイアウト
app/routes/_auth.tsx
はログイン・登録ページで共有されるレイアウトです。
typescript// app/routes/_auth.tsx
import { Outlet } from '@remix-run/react';
export default function AuthLayout() {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
}}
>
<div
style={{
border: '1px solid #ccc',
padding: '2rem',
borderRadius: '8px',
}}
>
<Outlet />
</div>
</div>
);
}
ログインページ
typescript// app/routes/_auth.login.tsx
export default function Login() {
return (
<form>
<h2>ログイン</h2>
<input type='email' placeholder='メールアドレス' />
<input type='password' placeholder='パスワード' />
<button type='submit'>ログイン</button>
</form>
);
}
以下の図は、パスなしレイアウトの構造を示しています。
mermaidflowchart TD
auth["_auth.tsx<br/>(URL に現れない)"] --> login["_auth.login.tsx<br/>/login"]
auth --> register["_auth.register.tsx<br/>/register"]
app["_app.tsx<br/>(URL に現れない)"] --> dashboard["_app.dashboard.tsx<br/>/dashboard"]
app --> settings["_app.settings.tsx<br/>/settings"]
Splat ルート
URL の残りの全パスをキャッチする Splat ルートのパターンです。
# | ファイルパス | URL パス | パラメータ | 説明 |
---|---|---|---|---|
22 | app/routes/$.tsx | /* | * | すべてのパスをキャッチ |
23 | app/routes/docs.$.tsx | /docs/* | * | /docs 配下の全パスをキャッチ |
24 | app/routes/files.$path.$.tsx | /files/:path/* | path , * | 複数セグメントをキャッチ |
コード例:404 ページ
app/routes/$.tsx
は存在しないパスをすべてキャッチし、404 ページを表示します。
typescript// app/routes/$.tsx
import { useParams } from '@remix-run/react';
export default function NotFound() {
const params = useParams();
return (
<div>
<h1>404 - ページが見つかりません</h1>
<p>
お探しのページ <code>/{params['*']}</code>{' '}
は存在しません。
</p>
</div>
);
}
コード例:ドキュメントルート
app/routes/docs.$.tsx
は /docs
配下のすべてのパスで同じコンポーネントを表示します。
typescript// app/routes/docs.$.tsx
import { useParams } from '@remix-run/react';
export default function Docs() {
const params = useParams();
const docPath = params['*'] || 'index';
return (
<div>
<h1>ドキュメント: {docPath}</h1>
<p>このパスのドキュメントを表示します。</p>
</div>
);
}
モーダル・並列ルート
同じ URL で複数のコンポーネントを表示する、モーダルや並列ルートのパターンです。
# | ファイルパス | URL パス | 説明 |
---|---|---|---|
25 | app/routes/photos.tsx | /photos | 写真一覧ページ |
26 | app/routes/photos.$photoId.modal.tsx | /photos/:photoId | モーダルで写真詳細を表示 |
27 | app/routes/products.tsx | /products | 商品一覧ページ |
28 | app/routes/products.$productId.modal.tsx | /products/:productId | モーダルで商品詳細を表示 |
コード例:写真一覧ページ
app/routes/photos.tsx
は写真一覧を表示します。
typescript// app/routes/photos.tsx
import { Link, Outlet } from '@remix-run/react';
export default function Photos() {
const photos = [
{ id: '1', title: '風景 1' },
{ id: '2', title: '風景 2' },
{ id: '3', title: '風景 3' },
];
return (
<div>
<h1>写真一覧</h1>
<div style={{ display: 'flex', gap: '1rem' }}>
{photos.map((photo) => (
<Link key={photo.id} to={`/photos/${photo.id}`}>
<img
src={`/images/${photo.id}.jpg`}
alt={photo.title}
style={{ width: '200px' }}
/>
</Link>
))}
</div>
{/* モーダルがここに表示される */}
<Outlet />
</div>
);
}
コード例:モーダル表示
app/routes/photos.$photoId.modal.tsx
はモーダルで写真詳細を表示します。
typescript// app/routes/photos.$photoId.modal.tsx
import {
json,
type LoaderFunctionArgs,
} from '@remix-run/node';
import {
useLoaderData,
useNavigate,
} from '@remix-run/react';
export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const photoId = params.photoId;
const photo = {
id: photoId,
title: `風景 ${photoId}`,
url: `/images/${photoId}.jpg`,
};
return json({ photo });
};
モーダルコンポーネント
typescriptexport default function PhotoModal() {
const { photo } = useLoaderData<typeof loader>();
const navigate = useNavigate();
return (
<div
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.8)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
onClick={() => navigate('/photos')}
>
<div
style={{
backgroundColor: 'white',
padding: '2rem',
borderRadius: '8px',
}}
>
<h2>{photo.title}</h2>
<img
src={photo.url}
alt={photo.title}
style={{ maxWidth: '600px' }}
/>
</div>
</div>
);
}
以下の図は、モーダルルートの動作を示しています。
mermaidsequenceDiagram
participant User as ユーザー
participant List as photos.tsx<br/>(一覧)
participant Modal as photos.$photoId.modal.tsx<br/>(モーダル)
User->>List: /photos にアクセス
List->>User: 写真一覧を表示
User->>Modal: 写真をクリック<br/>/photos/:photoId
Modal->>User: モーダルで詳細表示
User->>List: モーダル外をクリック
List->>User: 一覧に戻る
複雑なパラメータパターン
複数の動的パラメータを組み合わせたパターンです。
# | ファイルパス | URL パス | パラメータ | 説明 |
---|---|---|---|---|
29 | app/routes/users.$userId.posts.$postId.tsx | /users/:userId/posts/:postId | userId , postId | ユーザーの投稿詳細 |
30 | app/routes/orgs.$orgId.projects.$projectId.tsx | /orgs/:orgId/projects/:projectId | orgId , projectId | 組織のプロジェクト詳細 |
31 | app/routes/stores.$storeId.products.$productId.tsx | /stores/:storeId/products/:productId | storeId , productId | 店舗の商品詳細 |
コード例:複数パラメータの取得
app/routes/users.$userId.posts.$postId.tsx
で複数のパラメータを受け取ります。
typescript// app/routes/users.$userId.posts.$postId.tsx
import {
json,
type LoaderFunctionArgs,
} from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const { userId, postId } = params;
// ユーザーと投稿のデータ取得
const user = { id: userId, name: '山田太郎' };
const post = {
id: postId,
title: 'Remix の使い方',
content: 'Remix について解説します。',
};
return json({ user, post });
};
データの表示
typescriptexport default function UserPost() {
const { user, post } = useLoaderData<typeof loader>();
return (
<div>
<h1>{user.name} の投稿</h1>
<article>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
</div>
);
}
図で理解できる要点
- ファイル名の
.
は URL パスの/
に変換される $
は動的パラメータを示し、params
で取得できる_
プレフィックスは URL に影響せず、レイアウトのみを提供する- ネストルートでは親の
<Outlet />
に子コンポーネントがレンダリングされる - Splat ルート(
$.tsx
)は残りの全パスをキャッチする
まとめ
Remix のファイルシステムベースルーティングは、直感的でありながら非常に柔軟な設計が特徴です。この記事では、基本的な静的パスから、動的パラメータ、ネストレイアウト、パスなしレイアウト、Splat ルート、モーダルルートまで、主要なパターンを網羅的に解説しました。
ファイル名の記号(.
、$
、_
)の役割を理解し、早見表を参照することで、どんなルーティング要件にも素早く対応できるようになります。特に以下のポイントを押さえておくと、実装がスムーズに進むでしょう。
- ネストレイアウト: 親ルートで
<Outlet />
を配置し、子ルートを表示する - 動的パラメータ:
$
を使い、params
で値を取得する - パスなしレイアウト:
_
プレフィックスで URL に影響しないレイアウトを共有する - Splat ルート:
$.tsx
で柔軟なパスキャッチを実現する
Remix のルーティングをマスターすることで、複雑な UI 構造も簡潔に実装でき、保守性の高いアプリケーションを構築できます。ぜひこの早見表を活用して、効率的な開発を進めてくださいね。
関連リンク
- article
Remix ルーティング早見表:ネスト・可変パラメータ・モーダルルート対応一覧
- article
Remix 最短セットアップ:初期化から初デプロイまで 10 分で完走する手順
- article
Remix と Next.js/Vite/徹底比較:選ぶべきポイントはここだ!
- article
【実測検証】Remix vs Next.js vs Astro:TTFB/LCP/開発体験を総合比較
- article
【2025 年完全版】Remix の特徴・メリット・適用領域を総まとめ
- article
Remix の Mutation とサーバーアクション徹底活用
- article
Motion(旧 Framer Motion)useAnimate/useMotionValueEvent 速習チートシート
- article
Remix ルーティング早見表:ネスト・可変パラメータ・モーダルルート対応一覧
- article
JavaScript IntersectionObserver レシピ集:無限スクロール/遅延読込を最短実装
- article
Preact チートシート【保存版】:JSX/Props/Events/Ref の書き方早見表
- article
Playwright コマンド&テストランナー チートシート【保存版スニペット集】
- article
htmx 属性チートシート:hx-get/hx-post/hx-swap/hx-target 早見表【実例付き】
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来