ファイルルート規則
このページの内容

ファイルルート規則

@react-router/fs-routesパッケージは、ファイル規則に基づくルート設定を可能にします。

セットアップ

まず、@react-router/fs-routesパッケージをインストールします。

npm i @react-router/fs-routes

次に、それを使用して、`app/routes.ts`ファイルでルート設定を提供します。

import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;

デフォルトでは、app/routes ディレクトリ内のルートが検索されますが、これはアプリディレクトリからの相対パスである rootDirectory オプションで設定できます。

import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes({
  rootDirectory: "file-routes",
}) satisfies RouteConfig;

このガイドの残りの部分では、デフォルトの app/routes ディレクトリを使用していることを前提としています。

基本的なルート

app/routes ディレクトリ内のモジュールはすべて、アプリケーションのルートになります。ファイル名は、ルートの URL パス名に対応します。ただし、_index.tsx は例外で、ルートルートインデックスルートとなります。.js.jsx.ts、または .tsx のファイル拡張子を使用できます。

app/
├── routes/
│   ├── _index.tsx
│   └── about.tsx
└── root.tsx
URL 一致するルート
/ app/routes/_index.tsx
/about app/routes/about.tsx

ネストされたルーティングのため、これらのルートは app/root.tsx のアウトレットにレンダリングされます。

ドット区切り文字

ルートファイル名に . を追加すると、URL に / が作成されます。

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts.trending.tsx
│   ├── concerts.salt-lake-city.tsx
│   └── concerts.san-diego.tsx
└── root.tsx
URL 一致するルート
/ app/routes/_index.tsx
/about app/routes/about.tsx
/concerts/trending app/routes/concerts.trending.tsx
/concerts/salt-lake-city app/routes/concerts.salt-lake-city.tsx
/concerts/san-diego app/routes/concerts.san-diego.tsx

ドット区切り文字はネストも作成します。詳細はネストのセクションを参照してください。

動的セグメント

通常、URL は静的ではなく、データ駆動型です。動的セグメントを使用すると、URL のセグメントを一致させ、その値をコードで使用できます。$ プレフィックスを使用して作成します。

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts.$city.tsx
│   └── concerts.trending.tsx
└── root.tsx
URL 一致するルート
/ app/routes/_index.tsx
/about app/routes/about.tsx
/concerts/trending app/routes/concerts.trending.tsx
/concerts/salt-lake-city app/routes/concerts.$city.tsx
/concerts/san-diego app/routes/concerts.$city.tsx

値は URL から解析され、さまざまな API に渡されます。これらの値を「URL パラメータ」と呼びます。URL パラメータにアクセスするのに最も便利な場所は、ローダーアクションです。

export async function serverLoader({ params }) {
  return fakeDb.getAllConcertsForCity(params.city);
}

params オブジェクトのプロパティ名は、ファイルの名前 ($city.tsxparams.city になる) に直接対応していることに注意してください。

ルートには、concerts.$city.$date のように、複数の動的セグメントを含めることができます。どちらも params オブジェクトで名前によってアクセスされます。

export async function serverLoader({ params }) {
  return fake.db.getConcerts({
    date: params.date,
    city: params.city,
  });
}

詳細は、ルーティングガイドを参照してください。

ネストされたルート

ネストされたルーティングとは、URL のセグメントをコンポーネント階層とデータに結合するという一般的な考え方です。ルーティングガイドで詳細を読むことができます。

ドット区切り文字を使用してネストされたルートを作成します。. の前のファイル名が別のルートファイル名と一致する場合、自動的に一致する親のルートの子ルートになります。これらのルートを検討してください。

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts._index.tsx
│   ├── concerts.$city.tsx
│   ├── concerts.trending.tsx
│   └── concerts.tsx
└── root.tsx

app/routes/concerts. で始まるすべてのルートは、app/routes/concerts.tsx の子ルートとなり、親ルートのアウトレット内にレンダリングされます。

URL 一致するルート レイアウト
/ app/routes/_index.tsx app/root.tsx
/about app/routes/about.tsx app/root.tsx
/concerts app/routes/concerts._index.tsx app/routes/concerts.tsx
/concerts/trending app/routes/concerts.trending.tsx app/routes/concerts.tsx
/concerts/salt-lake-city app/routes/concerts.$city.tsx app/routes/concerts.tsx

ユーザーが親 URL を直接訪れたときに親のアウトレット内に何かがレンダリングされるように、ネストされたルートを追加するときには、通常、インデックスルートを追加することをお勧めします。

たとえば、URL が /concerts/salt-lake-city の場合、UI 階層は次のようになります。

<Root>
  <Concerts>
    <City />
  </Concerts>
</Root>

レイアウトのネストがないネストされた URL

URL をネストしたいが、自動レイアウトネストは望まない場合があります。親セグメントにアンダースコアを付けることで、ネストをオプトアウトできます。

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts.$city.tsx
│   ├── concerts.trending.tsx
│   ├── concerts.tsx
│   └── concerts_.mine.tsx
└── root.tsx
URL 一致するルート レイアウト
/ app/routes/_index.tsx app/root.tsx
/about app/routes/about.tsx app/root.tsx
/concerts/mine app/routes/concerts_.mine.tsx app/root.tsx
/concerts/trending app/routes/concerts.trending.tsx app/routes/concerts.tsx
/concerts/salt-lake-city app/routes/concerts.$city.tsx app/routes/concerts.tsx

/concerts/mineapp/routes/concerts.tsx ではなく、app/root.tsx とネストすることに注意してください。`trailing_` アンダースコアはパスセグメントを作成しますが、レイアウトネストは作成しません。

`trailing_` アンダースコアは、親の署名の最後に長いビットがあり、あなたを遺言から除外し、後に続くセグメントをレイアウトネストから削除するようなものと考えてください。

ネストされた URL がないネストされたレイアウト

これをパスレスルートと呼びます。

URL にパスセグメントを追加せずに、レイアウトをルートのグループと共有したい場合があります。一般的な例として、公開ページやログインしたアプリエクスペリエンスとは異なるヘッダー/フッターを持つ認証ルートのセットがあります。これは `_leading` アンダースコアを使用して行うことができます。

 app/
├── routes/
│   ├── _auth.login.tsx
│   ├── _auth.register.tsx
│   ├── _auth.tsx
│   ├── _index.tsx
│   ├── concerts.$city.tsx
│   └── concerts.tsx
└── root.tsx
URL 一致するルート レイアウト
/ app/routes/_index.tsx app/root.tsx
/login app/routes/_auth.login.tsx app/routes/_auth.tsx
/register app/routes/_auth.register.tsx app/routes/_auth.tsx
/concerts app/routes/concerts.tsx app/routes/concerts.tsx
/concerts/salt-lake-city app/routes/concerts.$city.tsx app/routes/concerts.tsx

`_leading` アンダースコアは、ファイル名の上にブランケットを引いて、URL からファイル名を隠していると考えてください。

オプションのセグメント

ルートセグメントを括弧で囲むと、セグメントがオプションになります。

 app/
├── routes/
│   ├── ($lang)._index.tsx
│   ├── ($lang).$productId.tsx
│   └── ($lang).categories.tsx
└── root.tsx
URL 一致するルート
/ app/routes/($lang)._index.tsx
/categories app/routes/($lang).categories.tsx
/en/categories app/routes/($lang).categories.tsx
/fr/categories app/routes/($lang).categories.tsx
/american-flag-speedo app/routes/($lang)._index.tsx
/en/american-flag-speedo app/routes/($lang).$productId.tsx
/fr/american-flag-speedo app/routes/($lang).$productId.tsx

なぜ/american-flag-speedo($lang).$productId.tsx ルートではなく ($lang)._index.tsx ルートに一致するのか疑問に思うかもしれません。これは、オプションの動的パラメータセグメントの後に別の動的パラメータが続く場合、/american-flag-speedo のような単一セグメントの URL が /:lang /:productId に一致する必要があるかどうかを確実に判断できないためです。オプションのセグメントは積極的に一致するため、/:lang に一致します。このタイプのセットアップがある場合は、($lang)._index.tsx ローダーで params.lang を確認し、params.lang が有効な言語コードでない場合は、現在/デフォルトの言語の /:lang/american-flag-speedo にリダイレクトすることをお勧めします。

スプラットルート

動的セグメントは単一のパスセグメント (URL 内の 2 つの / の間の部分) に一致するのに対し、スプラットルートはスラッシュを含む URL の残りの部分に一致します。

 app/
├── routes/
│   ├── _index.tsx
│   ├── $.tsx
│   ├── about.tsx
│   └── files.$.tsx
└── root.tsx
URL 一致するルート
/ app/routes/_index.tsx
/about app/routes/about.tsx
/beef/and/cheese app/routes/$.tsx
/files app/routes/files.$.tsx
/files/talks/react-conf_old.pdf app/routes/files.$.tsx
/files/talks/react-conf_final.pdf app/routes/files.$.tsx
/files/talks/react-conf-FINAL-MAY_2024.pdf app/routes/files.$.tsx

動的ルートパラメータと同様に、スプラットルートの params"*" キーを使用して、一致したパスの値にアクセスできます。

export async function serverLoader({ params }) {
  const filePath = params["*"];
  return fake.getFileInfo(filePath);
}

特殊文字のエスケープ

これらのルート規則に使用される特殊文字の 1 つを実際に URL の一部にしたい場合は、[] 文字を使用して規則をエスケープできます。これは、URL に拡張子を含むリソースルートに特に役立ちます。

ファイル名 URL
app/routes/sitemap[.]xml.tsx /sitemap.xml
app/routes/[sitemap.xml].tsx /sitemap.xml
app/routes/weird-url.[_index].tsx /weird-url/_index
app/routes/dolla-bills-[$].tsx /dolla-bills-$
app/routes/[[so-weird]].tsx /[so-weird]
`app/routes/reports.$id[.pdf].ts `/reports/123.pdf

整理のためのフォルダ

ルートは、ルートモジュールを定義する route.tsx ファイルを含むフォルダにすることもできます。フォルダ内の残りのファイルはルートになりません。これにより、他のフォルダで機能名を繰り返す代わりに、コードをルートの近くに整理できます。

フォルダ内のファイルはルートパスには意味がなく、ルートパスはフォルダ名によって完全に定義されます。

これらのルートを検討してください。

 app/
├── routes/
│   ├── _landing._index.tsx
│   ├── _landing.about.tsx
│   ├── _landing.tsx
│   ├── app._index.tsx
│   ├── app.projects.tsx
│   ├── app.tsx
│   └── app_.projects.$id.roadmap.tsx
└── root.tsx

一部またはすべてが、独自の `route` モジュールを保持するフォルダにすることができます。

app/
├── routes/
│   ├── _landing._index/
│   │   ├── route.tsx
│   │   └── scroll-experience.tsx
│   ├── _landing.about/
│   │   ├── employee-profile-card.tsx
│   │   ├── get-employee-data.server.ts
│   │   ├── route.tsx
│   │   └── team-photo.jpg
│   ├── _landing/
│   │   ├── footer.tsx
│   │   ├── header.tsx
│   │   └── route.tsx
│   ├── app._index/
│   │   ├── route.tsx
│   │   └── stats.tsx
│   ├── app.projects/
│   │   ├── get-projects.server.ts
│   │   ├── project-buttons.tsx
│   │   ├── project-card.tsx
│   │   └── route.tsx
│   ├── app/
│   │   ├── footer.tsx
│   │   ├── primary-nav.tsx
│   │   └── route.tsx
│   ├── app_.projects.$id.roadmap/
│   │   ├── chart.tsx
│   │   ├── route.tsx
│   │   └── update-timeline.server.ts
│   └── contact-us.tsx
└── root.tsx

ルートモジュールをフォルダに変換すると、ルートモジュールは `folder/route.tsx` になり、フォルダ内の他のすべてのモジュールはルートにならないことに注意してください。例えば

# these are the same route:
app/routes/app.tsx
app/routes/app/route.tsx

# as are these
app/routes/app._index.tsx
app/routes/app._index/route.tsx
ドキュメントと例 CC 4.0