#Using routes/_index.tsx as the layout for child routes

1 messages · Page 1 of 1 (latest)

hot agate
#

My current folder structure is as follows:

routes/
  ├── _index.tsx
  └── contacts.$contactId.tsx

I want to use _index.tsx as the layout for /contacts/$contactId and other routes, but currently, /contacts/$contactId is being rendered as a separate route instead of as a child route of _index.tsx.

I tried using root.tsx as the base, but it limits flexibility because I want to render different layouts (footer, menu, etc.) for different sections, such as the admin page. To my knowledge, it’s not possible to override the Layout export from root.tsx.

The _index.tsx file contains an Outlet component. I expected that routes matching _index.tsx (like /contacts/$contactId) would automatically be rendered inside _index's Outlet. However, they are being rendered in the root.tsx Outlet instead.

Could anyone help me resolve this issue?

mental flint
#
routes/
  ├── _main.tsx
  ├── _main._index.tsx
  └── _main.contacts.$contactId.tsx
hot agate
#

Thanks! much appreciated. Guess I shouldn't be trying out new stuff at 2am

vocal cairn
hot agate
#

Thank you! To me personally I think it would be awesome if we could use the Layout export in each of the routes to overwrite the base Layout

vocal cairn
#

You could use the handle export to define a custom <Layout> then in your root, check to see if it's defined or use the default.

// root.tsx
function DefaultLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <header>Header</header>
      <main>{children}</main>
      <footer>Footer</footer>
    </>
  );
}

export function Layout({ children }: { children: React.ReactNode }) {
  const MainLayout =
    useMatches().find((m) => m?.handle?.Layout)?.handle?.Layout ??
    DefaultLayout;

  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <MainLayout>{children}</MainLayout>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}
// routes/test.tsx
export const handle = {
  Layout: ({ children }: { children: React.ReactNode }) => (
    <div>
      <h1>Custom Layout</h1>
      {children}
    </div>
  ),
};

https://stackblitz.com/edit/remix-run-remix-tmvral?file=app%2Froot.tsx

hot agate
#

That is actually pretty neat, thank you! Awesome