Skip to content

Remix Layouts — Shared UI Across Routes

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Remix Layouts. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Remix layouts: create shared layouts for groups of routes, use the root layout for the HTML shell, and combine nested layouts for complex page structures.

In this lesson, you'll create layout routes that wrap groups of pages, configure the root layout for global HTML structure, and nest layouts for multi-level shells.

What You'll Learn

How the root layout works, create layout routes with _layout.tsx, use <Outlet /> for nesting, and apply layouts to route groups.

Why It Matters

Layouts prevent code duplication. A header, footer, or sidebar defined once in a layout is shared across all routes that need it.

Real-World Use

DodaZIP's app uses a root layout for the HTML shell and meta tags, an auth layout for login/register pages, and an app layout for authenticated pages.

flowchart TD
    A[root.tsx] --> B[Auth Layout]
    A --> C[App Layout]
    B --> D[Login Route]
    B --> E[Register Route]
    C --> F[Dashboard Route]
    C --> G[Profile Route]
    style A fill:#121212,color:#fff

Root Layout

app/root.tsx is the top-level layout:

import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";

export default function Root() {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

Every page on your site renders inside this root layout.

Layout Routes with Underscore

Create a layout that applies to a group of routes:

app/routes/_auth.tsx:

import { Outlet } from "@remix-run/react";

export default function AuthLayout() {
  return (
    <div className="auth-layout">
      <div className="auth-container">
        <Outlet />
      </div>
    </div>
  );
}

Routes in the same directory inherit this layout:

app/routes/_auth.login.tsx/login app/routes/_auth.register.tsx/register

Both routes render inside the _auth.tsx layout's container.

Layout with Loaders

Layouts can have their own loaders:

import { json } from "@remix-run/node";
import { useLoaderData, Outlet } from "@remix-run/react";

export const loader = async () => {
  return json({ siteName: "My App" });
};

export default function AppLayout() {
  const { siteName } = useLoaderData<typeof loader>();
  return (
    <div>
      <header>{siteName}</header>
      <Outlet />
      <footer>Built by DodaTech</footer>
    </div>
  );
}

Combining Layouts

Nest layouts for complex shells. The root layout wraps everything, the app layout adds header/footer, and individual route layouts add sidebars.

Common Mistakes

  1. Not exporting a default component from a layout: Layouts must export a default function component that includes <Outlet />.
  2. Using layouts for single routes: If only one route needs a wrapper, add the wrapper directly in the route component instead of creating a layout.
  3. Forgetting <Scripts />: Without <Scripts /> in the root layout, Remix's client-side JavaScript won't load.
  4. Hardcoding meta tags in layouts: Each route should contribute its own meta tags. Use the meta export for per-route SEO.

Practice Questions

  1. What is the purpose of root.tsx? Answer: It's the top-most layout that renders the HTML document shell, including <html>, <head>, <body>, and Remix's client-side scripts.

  2. How do you create a layout for a group of routes? Answer: Create a file with an underscore prefix, like _auth.tsx. Routes sharing that prefix render inside it.

  3. What must every layout component include? Answer: <Outlet /> to render child route content.

  4. Can layouts have loaders? Answer: Yes. Layout loaders fetch data needed by the layout, like site metadata or user information.

Challenge

Create three layouts: a root layout with HTML shell, a marketing layout for the homepage and about page, and an app layout for authenticated pages with header and footer.

Mini Project

Build a site with separate layouts for public pages (landing, about, contact) and authenticated pages (dashboard, profile, settings). The authenticated layout should include a sidebar with navigation.

FAQ

Can I have multiple layout levels?

: Yes. Layouts nest recursively. Root → App → Section → Route is a common pattern.

Do layouts need to be in the same directory as routes?

: Layouts can be in app/routes/ or imported from app/layouts/. The underscore convention works in routes.

How do I apply a layout to specific routes only?

: Place the layout file alongside the routes in a shared directory. Routes not in that directory won't use the layout.

Can layouts use `useLoaderData`?

: Yes. Layouts can fetch their own data and access it with useLoaderData().

What's Next

Learn about Remix Loaders for server-side data fetching in routes.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro