ルーティング

共通のレイアウト、ショートカット付きリンク、履歴を使って、アプリをルートに分割します。

この章のアプリはコンソールで動作しています。⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥Cで開き(先に開発者向け機能を有効化)、試してください。
章の動画を見る3:46

この章の内容

  • ファイルがルート
  • 共通のレイアウト
  • 前のページに戻る
  • 動的セグメント

App RouterはNext.jsのApp Routerの規約に従い、app/ 内のファイルをURLに対応付けます。ブラウザーのアドレスバーと履歴は同期されるため、UIがコンソールに描画されている間も、戻る、進む、ディープリンクが機能します。

ファイルがルート

一覧を専用のルートに移し、設定ページを追加します。

app/+5text
app/  layout.tsx  page.tsx                 → /追加:  deployments/追加:    page.tsx               → /deployments追加:    [id]/page.tsx          → /deployments/dpl_8fK2追加:  settings/追加:    page.tsx               → /settings

共通のレイアウト

layout.tsx はすべてのページをラップし、ページを移動しても状態を保持します。トップバーとナビゲーションをここに配置します。

app/layout.tsx+25tsx
追加:import type { ReactNode } from "react";追加:import { Box, Spacer, Text } from "@textjs/app";追加:import Link from "@textjs/app/link";追加:import { usePathname } from "@textjs/app/navigation";追加:追加:export const metadata = { title: { default: "Acme Deploys", template: "%s · Acme" } };追加:追加:export default function RootLayout({ children }: { children?: ReactNode }) {追加:  const pathname = usePathname();追加:  return (追加:    <Box className="flex-col grow">追加:      <Box className="flex-row h-1 px-1 gap-2">追加:        <Text bold>▼ Acme</Text>追加:        <Text color="subtle">{`acme.local${pathname === "/" ? "" : pathname}`}</Text>追加:        <Spacer />追加:      </Box>追加:      <Box className="flex-row h-1 px-1 gap-3">追加:        <Link href="/" shortcut="1">Overview</Link>追加:        <Link href="/deployments" shortcut="2">Deployments</Link>追加:        <Link href="/settings" shortcut="3">Settings</Link>追加:      </Box>追加:      <Box className="flex-col grow p-1">{children}</Box>追加:    </Box>追加:  );追加:}

shortcut は1つのキーをリンクに割り当てます。コンソールで 1、2、3 を押すと、実際のアプリではそれぞれに応じてURLが変わります。

前のページに戻る

useRouter() はコードからページを移動します。レイアウトで Backspace を router.back() に接続します。

app/layout.tsx+7-2tsx
削除:import { Box, Spacer, Text } from "@textjs/app";追加:import { Box, Spacer, Text, useInput } from "@textjs/app";import Link from "@textjs/app/link";削除:import { usePathname } from "@textjs/app/navigation";追加:import { usePathname, useRouter } from "@textjs/app/navigation";export default function RootLayout({ children }: { children?: ReactNode }) {  const pathname = usePathname();追加:  const router = useRouter();追加:追加:  useInput((e) => {追加:    if (e.key === "backspace") router.back();追加:  });

動的セグメント

[id] フォルダーは params で値を受け取ります。

app/deployments/[id]/page.tsxtsx
import { Text, type PageProps } from "@textjs/app";export default function DeploymentPage({ params }: PageProps<{ id: string }>) {  return <Text bold>{params.id}</Text>;}

静的ホストでは、このような動的セグメントには index.html へのリライトが必要です。第10章で説明します。

試す

これは章の終わりに完成するAcme Deploysで、DevToolsで動作しています。パッドをクリックして、以下のキーを使います。

▼ 05 · ルーティング

コンソールを開く

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

アプリはDevToolsに描画されます。まずSafariの「設定」→「詳細」で「Webデベロッパ用の機能を表示」をオンにします。 次にここをクリックして、2を押します。

デスクトップで開く

このアプリはDevToolsのコンソールに描画されるため、デスクトップブラウザーが必要です。

クイズ

2問

すべての問題に回答すると章を完了できます。

/deploymentsではどのファイルが描画されますか?

 

ページ間の移動で保持されるものは何ですか?