Featured image of post Nested Layouts Without Nested Urls

Nested Layouts Without Nested Urls

RemixでRoutingする際、ファイル名の先頭に _ を付ける場合と付けない場合がある。

_ を付けると、URLにPATH Segmentを追加せずにルートのグループとレイアウトを共有できるようになる1らしい。

公式のDocを参考に、各種ファイルを配置して挙動を見てみる。

1
2
3
4
5
6
app/
├── routes/
│   ├── about.tsx
│   ├── _auth.register.tsx
│   └── _auth.tsx
└── root.tsx

root.tsx には、初期生成されたTSXに対してHeaderとFooterを追加しておく。

@remix-run/cloudflare から import しているが、Cloudflareへデプロイする予定がないのであれば @remix-run/node から import すればOK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// app/root.tsx
import type { LinksFunction } from "@remix-run/cloudflare";
import { cssBundleHref } from "@remix-run/css-bundle";
import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";

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

export default function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <header>This is Header</header>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
        <footer>This is Footer</footer>
      </body>
    </html>
  );
}

UnderBarなし

about.tsx にレイアウト h1 のみ追加。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// app/about.tsx
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/cloudflare";
import { json } from "@remix-run/cloudflare";


export async function loader({ context }: LoaderFunctionArgs) {
  console.log(context);
  return json({});
}

export const meta: MetaFunction = () => {
  return [
    { title: "About" },
    { name: "description", content: "About" },
  ];
};

export default function About() {
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
      <h1>About</h1>
    </div>
  );
}

/about にアクセスしてみる。

http://localhost:8788/about

h1 と共に、 root.tsx で設定したHeaderとFooterが表示される。

UnderBarあり

_auth.tsx に独自のHeaderとFooterを追加。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// app/_auth.tsx
import type { LinksFunction } from "@remix-run/cloudflare";
import { cssBundleHref } from "@remix-run/css-bundle";
import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";

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

export default function Auth() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <header>Auth Header</header>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
        <footer>Auth Footer</footer>
      </body>
    </html>
  );
}

_auth.register.tsx にレイアウト h1 のみ追加。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// app/_auth.register.tsx
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/cloudflare";
import { json } from "@remix-run/cloudflare";


export async function loader({ context }: LoaderFunctionArgs) {
  console.log(context);
  return json({});
}

export const meta: MetaFunction = () => {
  return [
    { title: "Register" },
    { name: "description", content: "Register" },
  ];
};

export default function Register() {
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
      <h1>Register</h1>
    </div>
  );
}

/auth/_auth にアクセスすると404となる。

/register にアクセスしてみる。

http://localhost:8788/register

root.tsx で設定したHeader/Footerの内側に、_auth.tsx で設定した Header/Footerが表示される。

_auth.register.tsxh1 が内側に表示される。

整理

公式Docに記載されているとおり。

Pathless Routes と呼ばれ、URLに Path Segment を追加せずにレイアウトを共有できる。

Think of the _leading underscore as a blanket you’re pulling over the filename, hiding the filename from the URL.

_ をつけると、URLからファイル名が隠される。authに直接アクセスできなかったのはそのため。

Built with Hugo
Theme Stack designed by Jimmy