Remix: Sharing Your Index Layout with Sub-Routes
Patrick Kilgore

Patrick Kilgore @pckilgore

About: Rescript, ReasonML, Javascript, React, Functional Programming, Serverless.

Location:
Chicago, IL
Joined:
Nov 25, 2019

Remix: Sharing Your Index Layout with Sub-Routes

Publish Date: Jan 16 '22
25 10

I've been poking at Remix as a SSR framework. It appeals because I agree with the philosophy: react focused, leaning into web standards, and with good developer UX.

But, similar to other convention-based frameworks, I quickly ran into a situation where I knew how to write the code but not how to implement it via convention.

The site I'm building with Remix shares a layout between the index and its sub-pages. Essentially the index / route is the home, and shares its layout with any /subpage.

Basically:

wireframe demonstrating desired mapping of route to layout

What Doesn't Work

Naively, I started building out a layout with this file structure:



routes/
└── index.tsx
└── subpage.tsx


Enter fullscreen mode Exit fullscreen mode

But remix considers /subpage a peer, of /, even if the url reads like subpage is a child of /. And so the subpage route contains none of the shared layout defined in the index file.

So clearly the index.tsx file is not the right place to put shared layout code. But where?

What Does Work

The remix documentation has two other concepts that compose to solve this problem, layout routes and pathless routes.

Layout Routes

A layout route is a file with the same name as a directory:



routes/
├── app
│   ├── index.tsx   # <-- page rendered inside layout
│   └── subpage.tsx # <-- page rendered inside layout
├── app.tsx         # <--- the layout file
└── index.tsx


Enter fullscreen mode Exit fullscreen mode

But that alone doesn't solve my problem unless I want the entire app to exist at a nested route /app (or whatever). I don't.

Pathless Routes

The second concept is the pathless route, which is any folder that starts with __. This allows you to create nesting in the filesystem that isn't reflected in the url, for example:



routes/
├── app
│   ├── __admin
│   │   ├── admin-login.tsx # <-- renders at /app/admin-login
│   │   └── moderation.tsx  # <-- renders at /app/moderation
│   ├── page1.tsx           # <-- renders at /app/page1
│   └── page2.tsx           # <-- renders at /app/page2
├── app.tsx
└── index.tsx               # <-- renders at /


Enter fullscreen mode Exit fullscreen mode

Combining the Two with Index Pages

Frankly, I didn't expect combining pathless and layout routes to work to work with index pages, as index pages are usually a bit special in that they're usually expect to exist as files not directories. And especially not as directories starting with __!

But--credit to remix--the rules here compose well with indexes just as well as they do with other pages and routes. Applying the rules above, I ended up with:



routes/
├── __index
│   ├── index.tsx
│   └── subpage.tsx
└── __index.tsx


Enter fullscreen mode Exit fullscreen mode

Which renders exactly like you think it might:

Screenshot of index route rendering correctly with shared layout

Screenshot of subpage route rendering correctly with shared layout

Code

You can checkout code for the example above on Github.

Comments 10 total

  • Ryan Florence
    Ryan FlorenceJan 18, 2022

    Any reason you didn't use root.tsx?

    • Patrick Kilgore
      Patrick KilgoreJan 18, 2022

      Simplified example above, but some of the other pages don't share that layout. Putting layout in the root was causing it to show up everywhere. I miss something?

  • Vira Vnh
    Vira VnhAug 21, 2022

    Saved me a lot of trouble planning my routes, thanks !
    For some reason browsing the docs I kept overlooking the part about using __ before the name of a folder...

  • john_dev
    john_devSep 14, 2022

    Hello, I'm looking in the documentation for the part that talks about __ for routing but I can't find it, do you have a link? Thank you for your reply.

  • autsada
    autsadaJan 18, 2023

    @pckilgore Thank you for sharing, your tutorial saves my day, I spent more than an hour with this issue before finding your post.

  • Quack Quack
    Quack QuackApr 6, 2023

    Thanks @pckilgore. I've been looking for this for hours

  • Walter Jenkins
    Walter JenkinsApr 30, 2023

    It seems like this might not work on the new v2 routing. It keeps saying that you cannot use a path less on index. Do you know if that is the case?

    • Walter Jenkins
      Walter JenkinsApr 30, 2023

      For anyone still struggling with this with the new v2 routing. you CANNOT use __index.index.tsx you have to use something other than __index in the v2 update. So just using something like __landing.index.tsx would be a good replacement.
      Image description

Add comment