🐡

「Remix v2」 のルーティングがごっちゃなので整理する

2024/04/14に公開

Remixの公式の説明が雑でわからないのでこの画面を作って頭の中を整理する。

https://github.com/harukihosono/remix-routing-example

スタイルだけtailwindを使います。remixとtailwindは以下のページにコマンドのせてあります。

Remixのインストール、Tailwindの適用

1.Remixのインストール

https://remix.run/docs/en/main/start/quickstart

npx create-remix@latest

開発ディレクトリに移動

cd my-remix-app

開発用ビルドとランコマンドで起動

npm run dev

Remixのインストール完。

2.tailwindcssのインストール

https://tailwindcss.com/docs/guides/remix

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init --ts -p

./tailwind.config.tsを編集

tailwind.config.ts
import type { Config } from 'tailwindcss'

export default {
  content: ['./app/**/*.{js,jsx,ts,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
} satisfies Config

./app/tailwind.cssファイルを作成する

tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;

./app/root.tsxにコードを挿入する

root.tsx
import type { LinksFunction } from "@remix-run/node";
import stylesheet from "~/tailwind.css?url";

export const links: LinksFunction = () => [
  { rel: "stylesheet", href: stylesheet },
];
//~~~~~~~~~~~~~
app\root.tsx
app\root.tsx
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  Link
} from "@remix-run/react";

import type { LinksFunction } from "@remix-run/node";
import stylesheet from "~/tailwind.css?url";

export const links: LinksFunction = () => [
  { rel: "stylesheet", href: stylesheet },
];

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" />
        <Meta />
        <Links />
      </head>
      <body>
        <div className="flex h-screen bg-blue-500">
          {/* Sidebar */}
          <div className="w-1/5 bg-black text-white p-4 space-y-6">
            <h2 className="text-white text-lg font-semibold">Fakebooks</h2>
            <nav className="flex flex-col">
              <Link to="/" className="hover:bg-gray-700 p-2 rounded">Dashboard</Link>
              <Link to="/accounts" className="hover:bg-gray-700 p-2 rounded">Accounts</Link>
              <Link to="/sales" className="hover:bg-gray-700 p-2 rounded">Sales</Link>
              <Link to="/expenses" className="hover:bg-gray-700 p-2 rounded">Expenses</Link>
              <Link to="/reports" className="hover:bg-gray-700 p-2 rounded">Reports</Link>
            </nav>
          </div>

          {/* Main content area */}
          <div className="w-4/5">
            {children}
          </div>
        </div>

        <ScrollRestoration />
        <Scripts />
      </body>


    </html>
  );
}

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


app\routes\_index.tsx
export default function Index() {
  return (
    <div className="bg-blue-100">
      <p>index</p>
    </div>
  );
}

app/
└── routes/
├── _index.tsx
├── sales.tsx
├── sales.invoices.tsx
└── sales.invoices.$id.tsx

1. sales

app\routes\sales.tsx
app\routes\sales.tsx
import { Link, Outlet } from "@remix-run/react";

export default function Sales() {
  return (
    <div className="flex flex-col flex-1">
      {/* セールスセクションのヘッダー */}
      <header className="bg-green-500 text-white p-4 shadow-md">
        <div className="max-w-7xl mx-auto">
          <h1 className="text-xl font-bold">Sales</h1>
          {/* サブナビゲーションリンク */}
          <nav className="flex space-x-4 mt-2">
            <Link to="." className="hover:underline">Overview</Link>
            <Link to="subscriptions" className="hover:underline">Subscriptions</Link>
            <Link to="invoices" className="hover:underline">Invoices</Link>
            <Link to="customers" className="hover:underline">Customers</Link>
            <Link to="deposits" className="hover:underline">Deposits</Link>
          </nav>
        </div>
      </header>
      <main className="flex-1 p-4">
        <Outlet />
      </main>
    </div>
  );
}


2. sales/invoices

app\routes\sales.invoices.tsx
app\routes\sales.invoices.tsx
import { Link, Outlet } from "@remix-run/react";

export default function Invoices() {
  return (
    <div className="flex">
      {/* サイドバー */}
      <div className="w-1/5 bg-yellow-500 p-5 text-white">
        <div className="mb-4">
          <p className="font-semibold">Invoice Numbers:</p>
          <Link to="123" className="block mt-2 hover:bg-blue-700 p-2 rounded">
            123
          </Link>
          <Link to="124" className="block mt-2 hover:bg-blue-700 p-2 rounded">
            124
          </Link>
          <Link to="125" className="block mt-2 hover:bg-blue-700 p-2 rounded">
            125
          </Link>
        </div>
      </div>
      {/* メインコンテンツエリア */}
      <div className="flex-1 bg-yellow-500">
        <p>Invoices</p>
        <Outlet /> {/* ここで選択された子ルートがレンダリングされる */}
      </div>
    </div>
  );
}



3. sales/invoices/$id

app\routes\sales.invoices.$id.tsx
app\routes\sales.invoices.$id.tsx
import { useParams } from "@remix-run/react";

export default function InvoiceDetail() {
  const { id } = useParams(); // 請求書IDをURLから取得
  
  return (
    <div className="bg-red-500">
      <p>{id}</p>
    </div>
  );
}


githubに置いとくね。
https://github.com/harukihosono/remix-routing-example

Discussion