<RouterProvider>
を使用している場合は、代わりにRouterProviderからのフレームワーク導入をご覧ください。
<Routes>
を使用している場合は、ここは正しい場所です。
React Router Viteプラグインは、React Routerにフレームワーク機能を追加します。このガイドは、アプリにプラグインを導入するのに役立ちます。問題が発生した場合は、TwitterまたはDiscordでヘルプを求めてください。
Viteプラグインは以下を追加します
初期設定には最も手間がかかります。ただし、完了すれば、新しい機能をルートごとに段階的に採用できます。
Viteプラグインを使用するには、プロジェクトに以下が必要です。
👉 React Router Viteプラグインをインストールします。
npm install -D @react-router/dev
👉 ランタイムアダプターをインストールします。
ランタイムとしてNodeを使用していると仮定します。
npm install @react-router/node
👉 ReactプラグインをReact Routerに置き換えます。
-import react from '@vitejs/plugin-react'
+import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
- react()
+ reactRouter()
],
});
👉 react-router.config.ts
ファイルを作成します。
プロジェクトのルートに以下を追加します。この設定では、アプリディレクトリの場所や、今のところSSR(サーバーサイドレンダリング)を使用しないなど、React Routerにプロジェクトについて指示できます。
touch react-router.config.ts
import type { Config } from "@react-router/dev/config";
export default {
appDirectory: "src",
ssr: false,
} satisfies Config;
典型的なViteアプリでは、 index.html
ファイルがバンドルのエントリポイントです。 React Router Viteプラグインは、エントリポイントを root.tsx
ファイルに移動するため、静的HTMLの代わりにReactを使用してアプリのシェルをレンダリングし、最終的には必要に応じてサーバーレンダリングにアップグレードできます。
👉 既存の index.html
を root.tsx
に移動します。
たとえば、現在の index.html
が次のようになっている場合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
そのマークアップを src/root.tsx
に移動し、 index.html
を削除します。
touch src/root.tsx
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "react-router";
export function Layout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
<meta charSet="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>My App</title>
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function Root() {
return <Outlet />;
}
典型的なViteアプリでは、 index.html
ファイルは src/main.tsx
をクライアントエントリポイントとして指します。 React Routerは代わりに src/entry.client.tsx
という名前のファイルを使用します。
👉 src/entry.client.tsx
をエントリポイントにします。
現在の src/main.tsx
が次のようになっている場合
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router";
import "./index.css";
import App from "./App";
ReactDOM.createRoot(
document.getElementById("root")!
).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
それを entry.client.tsx
に名前変更し、次のように変更します。
import React from "react";
import ReactDOM from "react-dom/client";
import { HydratedRouter } from "react-router/dom";
import "./index.css";
ReactDOM.hydrateRoot(
document,
<React.StrictMode>
<HydratedRouter />
</React.StrictMode>
);
createRoot
の代わりに hydrateRoot
を使用します。<App/>
コンポーネントの代わりに <HydratedRouter>
をレンダリングします。<App/>
コンポーネントのレンダリングを停止しました。後の手順で戻しますが、まずは新しいエントリポイントでアプリを起動できるようにします。root.tsx
と entry.client.tsx
の間で、いくつかの要素を整理したい場合があります。
一般的に
root.tsx
には、コンテキストプロバイダー、レイアウト、スタイルなどのレンダリング関連のものが含まれます。entry.client.tsx
はできるだけ最小限にする必要があります。<App/>
コンポーネントをまだレンダリングしようとしないでください。後の手順で行います。root.tsx
ファイルは静的に生成され、アプリのエントリポイントとして提供されるため、そのモジュールのみがサーバーレンダリングと互換性がある必要があることに注意してください。 ここにほとんどの問題が発生します。
React Router Viteプラグインは、 routes.ts
ファイルを使用してルートを設定します。 とりあえず、物事を進めるために単純なキャッチオールルートを追加します。
👉 catchall.tsx
ルートを設定します。
touch src/routes.ts src/catchall.tsx
import {
type RouteConfig,
route,
} from "@react-router/dev/routes";
export default [
// * matches all URLs, the ? makes it optional so it will match / as well
route("*?", "catchall.tsx"),
] satisfies RouteConfig;
👉 プレースホルダーのルートをレンダリングします。
最終的にはこれを元の App
コンポーネントに置き換えますが、今のところはアプリを起動できることを確認するために簡単なものをレンダリングします。
export default function Component() {
return <div>Hello, world!</div>;
}
ルートの設定に関するガイドをご覧ください routes.ts
ファイルの詳細については。
この時点で、アプリを起動してルートレイアウトを表示できるはずです。
👉 dev
スクリプトを追加してアプリを実行します。
"scripts": {
"dev": "react-router dev"
}
次に進む前に、この時点でアプリを起動できることを確認してください。
npm run dev
アプリのレンダリングに戻るには、以前に設定したすべてのURLに一致する「キャッチオール」ルートを更新して、既存の <Routes>
がレンダリングされるようにします。
👉 アプリをレンダリングするようにキャッチオールルートを更新します。
import App from "./App";
export default function Component() {
return <App />;
}
アプリが画面に戻り、通常どおりに動作するはずです!
これで、ルートをルートモジュールに段階的に移行できます。
次のような既存のルートがあるとします。
// ...
import About from "./containers/About";
export default function App() {
return (
<Routes>
<Route path="/about" element={<About />} />
</Routes>
);
}
👉 routes.ts
にルート定義を追加します。
import {
type RouteConfig,
route,
} from "@react-router/dev/routes";
export default [
route("/about", "./pages/about.tsx"),
route("*?", "catchall.tsx"),
] satisfies RouteConfig;
👉 ルートモジュールを追加します。
ルートモジュールAPIを使用するようにルートモジュールを編集します。
export async function clientLoader() {
// you can now fetch data here
return {
title: "About page",
};
}
export default function Component({ loaderData }) {
return <h1>{loaderData.title}</h1>;
}
パラメータ、ローダーデータなどの自動生成された型安全性を設定するには、型安全性を参照してください。
移行する最初のいくつかのルートは、さまざまな抽象化に以前とは少し異なる方法でアクセスする必要があるため、最も困難です(フックやコンテキストではなくローダーなど)。 しかし、最も難しい部分が処理されると、段階的な流れに入ります。
サーバーレンダリングと静的プリレンダリングを有効にする場合は、バンドラープラグインの ssr
および prerender
オプションを使用して有効にできます。 SSRの場合、サーバービルドをサーバーにデプロイする必要もあります。 詳細については、デプロイを参照してください。
import type { Config } from "@react-router/dev/config";
export default {
ssr: true,
async prerender() {
return ["/", "/about", "/contact"];
},
} satisfies Config;