特別なファイル
このページの内容

特別なファイル

React Routerがプロジェクト内で探す特別なファイルがいくつかあります。これらのファイルはすべて必須ではありません。

react-router.config.ts

このファイルはオプションです。

設定ファイルは、サーバーサイドレンダリングを使用しているかどうか、特定のディレクトリの場所など、アプリの特定の側面を設定するために使用されます。

import type { Config } from "@react-router/dev/config";

export default {
  // Config options...
} satisfies Config;

詳細は、react-router config APIを参照してください。

root.tsx

このファイルは必須です。

ルートルート(app/root.tsx)は、React Routerアプリケーションで唯一の*必須*ルートです。これは、routes/ディレクトリ内のすべてのルートの親であり、ルート<html>ドキュメントのレンダリングを担当するためです。

ルートルートはドキュメントを管理するため、React Routerが提供する少数の「ドキュメントレベル」コンポーネントをレンダリングする適切な場所です。これらのコンポーネントは、ルートルート内で一度だけ使用され、ページを正しくレンダリングするためにReact Routerが把握または構築したすべてが含まれています。

import type { LinksFunction } from "react-router";
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "react-router";

import "./global-styles.css";

export default function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1"
        />

        {/* All `meta` exports on all routes will render here */}
        <Meta />

        {/* All `link` exports on all routes will render here */}
        <Links />
      </head>
      <body>
        {/* Child routes render here */}
        <Outlet />

        {/* Manages scroll position for client-side transitions */}
        {/* If you use a nonce-based content security policy for scripts, you must provide the `nonce` prop. Otherwise, omit the nonce prop as shown here. */}
        <ScrollRestoration />

        {/* Script tags go here */}
        {/* If you use a nonce-based content security policy for scripts, you must provide the `nonce` prop. Otherwise, omit the nonce prop as shown here. */}
        <Scripts />
      </body>
    </html>
  );
}

レイアウトエクスポート

ルートルートは、すべてのルートモジュールエクスポートをサポートしています。

ルートルートは、追加のオプションのLayoutエクスポートもサポートしています。Layoutコンポーネントには2つの目的があります。

  1. ルートコンポーネント、HydrateFallback、およびErrorBoundaryでドキュメントの「アプリシェル」が重複するのを避けます。
  2. ルートコンポーネント/ HydrateFallback / ErrorBoundaryを切り替えるときに、Reactがアプリシェル要素を再マウントするのを防ぎます。これは、Reactが<Links>コンポーネントから<link rel="stylesheet">タグを削除して再追加する場合にFOUCを引き起こす可能性があります。
export function Layout({ children }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1"
        />
        <Meta />
        <Links />
      </head>
      <body>
        {/* children will be the root Component, ErrorBoundary, or HydrateFallback */}
        {children}
        <Scripts />
        <ScrollRestoration />
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

export function ErrorBoundary() {}

LayoutコンポーネントのuseLoaderDataに関する注意

useLoaderDataは、正常なパスルートレンダリングを目的としているため、ErrorBoundaryコンポーネントで使用することはできません。また、その型指定には、loaderが正常に実行されて何かを返したという組み込みの仮定があります。この仮定は、ErrorBoundaryでは成り立ちません。境界線をトリガーしたスローがloaderであった可能性があるためです。ErrorBoundaryでローダーデータにアクセスするには、ローダーデータがundefinedになる可能性を考慮したuseRouteLoaderDataを使用できます。

Layoutコンポーネントは成功フローとエラーフローの両方で使用されるため、この同じ制限が適用されます。リクエストが成功したかどうかによってLayoutのロジックを分岐する必要がある場合は、useRouteLoaderData("root")useRouteError()を使用できます。

<Layout>コンポーネントはErrorBoundaryのレンダリングに使用されるため、レンダリングエラーが発生することなくErrorBoundaryをレンダリングできるように*非常に慎重に*する必要があります。Layoutが境界線をレンダリングしようとして別のエラーをスローした場合、それは使用できなくなり、UIは非常に最小限の組み込みデフォルトErrorBoundaryにフォールバックします。

export function Layout({
  children,
}: {
  children: React.ReactNode;
}) {
  const data = useRouteLoaderData("root");
  const error = useRouteError();

  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1"
        />
        <Meta />
        <Links />
        <style
          dangerouslySetInnerHTML={{
            __html: `
              :root {
                --themeVar: ${
                  data?.themeVar || defaultThemeVar
                }
              }
            `,
          }}
        />
      </head>
      <body>
        {data ? (
          <Analytics token={data.analyticsToken} />
        ) : null}
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

routes.ts

このファイルは必須です。

routes.tsファイルは、どのURLパターンがどのルートモジュールに一致するかを設定するために使用されます。

import {
  type RouteConfig,
  route,
} from "@react-router/dev/routes";

export default [
  route("some/path", "./some/file.tsx"),
  // pattern ^           ^ module file
] satisfies RouteConfig;

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

entry.client.tsx

このファイルはオプションです。

デフォルトでは、React Routerはクライアントでアプリのハイドレーションを自動的に処理します。次の方法でデフォルトのエントリクライアントファイルを表示できます。

react-router reveal

このファイルはブラウザのエントリポイントであり、サーバーエントリモジュールでサーバーによって生成されたマークアップのハイドレーションを担当しますが、ここで他のクライアントサイドコードを初期化することもできます。

import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router/dom";

startTransition(() => {
  hydrateRoot(
    document,
    <StrictMode>
      <HydratedRouter />
    </StrictMode>
  );
});

これは、ブラウザで最初に実行されるコードです。クライアント側のライブラリを初期化したり、クライアント専用のプロバイダーを追加したりできます。

entry.server.tsx

このファイルはオプションです。

デフォルトでは、React RouterはHTTPレスポンスの生成を処理します。次の方法でデフォルトのエントリサーバーファイルを表示できます。

react-router reveal

このモジュールのdefaultエクスポートは、HTTPステータス、ヘッダー、HTMLを含むレスポンスを作成できる関数であり、マークアップが生成されてクライアントに送信される方法を完全に制御できます。

このモジュールは、現在のリクエストのcontexturlを使用して、<ServerRouter>要素を使用して現在のページのマークアップをレンダリングする必要があります。このマークアップは、JavaScriptがクライアントエントリモジュールを使用してブラウザにロードされると、(オプションで)再ハイドレートされます。

handleDataRequest

オプションのhandleDataRequest関数をエクスポートして、データリクエストのレスポンスを変更できます。これらはHTMLをレンダリングしないリクエストですが、クライアント側のハイドレーションが発生した後、ローダーとアクションデータをブラウザに返します。

export function handleDataRequest(
  response: Response,
  {
    request,
    params,
    context,
  }: LoaderFunctionArgs | ActionFunctionArgs
) {
  response.headers.set("X-Custom-Header", "value");
  return response;
}

handleError

デフォルトでは、React Routerは発生したサーバーサイドエラーをコンソールに記録します。ロギングをより詳細に制御したい場合、またはこれらのエラーを外部サービスにも報告したい場合は、制御できるオプションのhandleError関数をエクスポートできます(組み込みのエラーロギングは無効になります)。

export function handleError(
  error: unknown,
  {
    request,
    params,
    context,
  }: LoaderFunctionArgs | ActionFunctionArgs
) {
  if (!request.signal.aborted) {
    sendErrorToErrorReportingService(error);
    console.error(formatErrorForJsonLogging(error));
  }
}

React Routerのキャンセルと競合状態の処理により、多くのリクエストが中止される可能性があるため、リクエストが中止されたときのロギングは一般的に避けたいことに注意してください。

ストリーミングレンダリングエラー

renderToPipeableStreamまたはrenderToReadableStreamを介してHTMLレスポンスをストリーミングする場合、独自のhandleError実装は、初期シェルレンダリング中に発生したエラーのみを処理します。後続のストリーミングレンダリング中にレンダリングエラーが発生した場合、React Routerサーバーはその時点で既にレスポンスを送信しているため、これらのエラーを手動で処理する必要があります。

renderToPipeableStreamの場合、これらのエラーはonErrorコールバック関数で処理できます。エラーがシェルレンダリングエラー(無視できる)だったのか、非同期だったのかを知るために、onShellReadyでブール値を切り替える必要があります。

例については、Nodeのデフォルトのentry.server.tsxを参照してください。

スローされたレスポンス

これは、loader / action関数からスローされたResponseインスタンスを処理しないことに注意してください。このハンドラの目的は、予期しないスローエラーが発生するコードのバグを見つけることです。loader / actionでシナリオを検出して401/404/etc. Responseをスローしている場合、それはコードによって処理される予期されたフローです。それらをログに記録したり、外部サービスに送信したりする場合も、レスポンスをスローするときに行う必要があります。

ドキュメントと例 CC 4.0