DEV Community

Patrick Kilgore
Patrick Kilgore

Posted on

Remix: Sharing Your Index Layout with Sub-Routes

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.

Top comments (10)

Collapse
 
ryanflorence profile image
Ryan Florence

Any reason you didn't use root.tsx?

Collapse
 
pckilgore profile image
Patrick Kilgore

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?

Collapse
 
jgb profile image
Jean Gérard Bousiquot

@pckilgore Yes I'm in the same situation now. The login page has its own layout. Thanks for this tutorial!

@ryanflorence thanks for Remix. It's awesome!

Collapse
 
autsada profile image
autsada

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

Collapse
 
quackquack profile image
Quack Quack

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

Collapse
 
aviddabbler profile image
Walter Jenkins

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?

Collapse
 
aviddabbler profile image
Walter Jenkins

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

Collapse
 
vira profile image
Vira Vnh

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...

Collapse
 
j314h profile image
john_dev

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.

Collapse
 
aissabouguern profile image
Aissa BOUGUERN