question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Named layouts — solves pathless routes and granular layout resets

See original GitHub issue

Describe the problem

There’s a whole slew of issues surrounding layout resets, such as these:

There might well be others. The essence of them is that __layout.reset.svelte is too blunt an instrument for the problem it purports to solve — your / page might be unique (but you can’t have a root-level reset), or your nested route might want to reset an intermediate layout but not the root layout, or you might just want to reset a layout for a specific component without the overhead of creating a neighbouring reset component.

A separate issue asks for ‘pathless’ routes, so that your marketing pages and your app itself can both live at the root level, even though they have totally different layouts. But it’s actually the same problem, in disguise.

Describe the proposed solution

Credit for this belongs mostly to @mrkishi, not me. The idea is to have named layouts, and give components a way to declare which layouts they belong to.

We name a layout like so:

routes/
├ __layout.{js,svelte}
└ __layout-special.{js,svelte}

Any page can now mount inside the special layout rather than the default layout by specifying so in its own filename:

routes/
├ __layout.{js,svelte}
├ __layout-special.{js,svelte}
├ normal-page.{js,svelte}
├ abnormal-page#special.{js,svelte}

This applies at arbitrary depths: in this case, /deeply/nested/path will ignore the __layout, deeply/__layout and deeply/nested/__layout files.

routes/
├ __layout.{js,svelte}
├ __layout-special.{js,svelte}
├ deeply
│ ├ nested
│ │ ├ path#special.{js,svelte}
│ │ └ __layout.{js,svelte}
│ └ __layout.{js,svelte}

If a folder specifies a layout name, its contents will inherit it — /deeply/nested/path/contains/more/stuff would use __layout-special as well as any __layout files contained inside path#special:

routes/
├ __layout.{js,svelte}
├ __layout-special.{js,svelte}
├ deeply
│ ├ nested
│ │ ├ path#special
│ │ │ ├ contains
│ │ │ │ ├ more
│ │ │ │ │ └ stuff

At any point, you can reset to a layout further up the tree. This is a horribly contrived example, bear with me — /deeply/nested/path/contains/more/things would use deeply/__layout-x (which itself uses the root __layout), rather than __layout-special specified up-tree:

routes/
├ __layout.{js,svelte}
├ __layout-special.{js,svelte}
├ deeply
│ ├ __layout-x.{js,svelte}
│ ├ nested
│ │ ├ path#special
│ │ │ ├ contains
│ │ │ │ ├ more
│ │ │ │ │ ├ stuff
│ │ │ │ │ └ things#x

The most common cases are probably a) resetting to the default root layout, and b) resetting to no layout (i.e. a completely blank page). We could do these by using ~ as an alias for ‘default’, and omitting a name for ‘complete reset’:

page-that-uses-default-layout#~.svelte
page-that-uses-no-layout#.svelte

A little punctuation-heavy, but it reuses concepts efficiently I think.


We can now see how this solves the issues listed above.

#3832

Since sibling components can now use different layouts, there’s no need to invent syntax for ‘pathless’ routes, and the filesystem continues to match the routing table, rather than having things nested confusingly:

routes/
├ __layout-app.{js,svelte}
├ __layout-auth.{js,svelte}
├ __layout-marketing.{js,svelte}
├ [userId]#app
│ └ profile.svelte
├ dashboard#app.svelte
├ index#marketing.svelte
├ reset-password#auth.svelte
├ signin#auth.svelte
├ signup#auth.svelte
└ product#marketing.svelte

(In reality, you’d designate either app or marketing as the default, so you wouldn’t need to declare names for all these.)

#4103

Instead of this…

login
├ __layout.reset.svelte
└ index.svelte

…we could have this…

login
  index#.svelte

…or even this:

login#.svelte

#4133, #2647

Pages can now easily break out of any intermediate layouts between them and the root. The #2647 example, where you want test.svelte to render inside the root layout but not the admin layout…

routes
├ __layout.svelte
├ admin
│ ├ __layout.svelte
│ ├ spec
│ │ ├ __layout.reset.svelte
│ │ └ test.svelte

…is easily achieved:

routes
  __layout.svelte
  admin
    __layout.svelte
    spec
      test#~.svelte

#1685

The index page can now have a special layout:

__layout.{js,svelte}
__layout-special.{js,svelte}
index#special.svelte
other.svelte
stuff.svelte

Alternatives considered

The alternative people have suggested is exporting something from the page component — export const reset = 2, or export const Layout = SomeComponent.

But we can’t then know which layouts to use or omit without loading the component. Using filenames gives us the ability to figure out all the important stuff at build time.

Importance

would make my life easier

Additional Information

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:11
  • Comments:20 (14 by maintainers)

github_iconTop GitHub Comments

5reactions
Rich-Harriscommented, Mar 10, 2022

What would prevent us from parsing the exports at build time? They’d have to be static, but that’s already the case for path-based references.

The fact that this would work…

<script context="module">
  export const section = 'special';
</script>

…and this would fail…

<script context="module">
  import { SPECIAL_SECTION } from '$lib/constants';
  export const section = SPECIAL_SECTION;
</script>

…is way too deep in the uncanny valley for my liking.

The reason I’m not too concerned about causing punctuation soup in the file tree is that a) named sections would be the exception, not the rule (I think it’s much more common for layout trees to loosely follow URL structure than for every subtree to be unique), and b) inheritance. Besides, being able to see at a glance that these are my marketing pages and these are my app pages (without needing to open up files and scan for specific exports) is a good thing, I’d argue.

4reactions
vwkdcommented, Mar 24, 2022

Just a lose idea. Maybe it would make sense to have a single metadata file for a route (page and endpoint) that contains the information that should be available without needing to load the route.

This metadata file could contain the layout overrides discussed here, param validators (https://github.com/sveltejs/kit/issues/4291), and also more meta data like route redirects, etc.

Maybe that would deter too much from SvelteKit’s mentality to keep things straight forward to understand, as reading the file hierarchy isn’t enough anymore to know what route is running when. But then, those extra files (first normal layouts, now special layouts, then route parameters, etc.) introduce only increasing complexity and arguably just as well make it not straight forward anymore to understand what runs when.

I guess it remains to be seen where the tipping point is, when encoding metadata in one dimensional length-an-character-restricted file/folder names becomes more complex than in two dimensional unrestricted code files.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Qwik City - Grouped Layouts - Qwik - Builder.io
This is where "grouped" layouts come in (also referred to as a "pathless" layout route). By surrounding any directory name with parentheses, such...
Read more >
Create and Use a Layout with Remix Pathless Layout Routes
This is why Remix has layout routes and in this case because it's an application layout, you will want a pathless — pathless...
Read more >
ACI Multi-Pod White Paper - Cisco
This (ACI Multi-Pod White Paper) white paper investigates the business and technical issues pertaining to a platform, solution, or technology and examine ...
Read more >
Realizing common layouts using grids - CSS - MDN Web Docs
We're going to create this layout using the named template areas that we learned about in the guide Grid template areas.
Read more >
Advanced Search | Oxcyon
58. Centralpoint Template Gallery. Centralpoint's Template Gallery is a unique module that enables Oxcyon to send records downstream to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found