Add layout endpoints
See original GitHub issueDescribe the problem
Page endpoints have been a popular addition to SvelteKit, despite a few lingering bugs. Since before they landed, people have (quite reasonably) been asking why we don’t have layout endpoints.
The biggest reason, frivolous as it might sound, is naming. ‘Layout’ is very much a UI concept, and so a __layout.js file that is solely concerned with loading data feels a bit weird.
Describe the proposed solution
As part of a wider overhaul of routing (follow-up issue to come, which will address pathless routes and granular layout resets) I propose changing __layout.svelte to __section.svelte and adding a corresponding __section.js (or .ts, etc) endpoint. ‘Section’ feels like a sufficiently agnostic word — it leans towards UI terminology, but it doesn’t feel weird to talk about a ‘section endpoint’, as in ‘the endpoint for the blog section’ or the admin section or whatever.
Just as page endpoints expose their data as a virtual child __data.json route, section data will need to be exposed, perhaps by appending __section.json (i.e. src/routes/foo/__section.js is exposed as /foo/__section.json).
One major difference between section endpoints and page endpoints: since sections don’t ‘own’ a specific URL, it doesn’t make sense to be able to POST to them etc. I’d therefore argue that non-get handlers should be forbidden in section endpoints.
Alternatives considered
Other frameworks like Nuxt and Remix think about nested routes differently to how SvelteKit does it. Consider a route like /settings/notifications/email where email is nested within the notifications section, which is nested inside the settings section.
In SvelteKit the filesystem would look like this:
routes/
├── settings/
│ ├── billing/
│ ├── └── [files]
│ ├── notifications/
│ ├── ├── desktop.{js,svelte}
│ ├── ├── email.{js,svelte}
│ ├── └── __section.{js,svelte}
│ └── __section.{js,svelte}
Instead of having something like __section, Nuxt and Remix use a filename with the same name as the directory:
routes/
├── settings/
│ ├── billing/
│ ├── └── [files]
│ ├── notifications/
│ ├── ├── desktop.js (or desktop.vue, in Nuxt's case)
│ ├── └── email.js
│ ├── billing.js
│ └── notifications.js
├── settings.js
(In both cases, /settings and /settings/notifications routes can be added with index files.)
I don’t think one of these approaches is unambiguously better than the other, but we can enumerate some pros and cons of the SvelteKit approach. Pros:
- Things are appropriately colocated — all the notifications-related code lives together, rather than being split between
notifications/andnotifications.{js,svelte} - Renaming ‘settings’ to ‘preferences’ happens in one place, not two
- If you expand a folder like
settingsin your editor, the breadth of the folder is capped atn+2rather than3nwherenis the number of nested sections (i.e.billing/,notifications/,__section.jsand__section.svelterather thanbilling/,notifications/,billing.js,billing.svelte,notifications.jsandnotifications.svelte) - It’s arguably more explicit
- If you needed
/settingsto have a completely different layout than/settings/*for some reason, it’s easy — you can haveroutes/settings.{js,svelte}. If that file is instead used for layout,/settings/index.{js,svelte}must inherit from it unless you add a new convention for exempting it, like Remix’sroutes/settings.index.js(I’ve also seenroutes/settings+index.js), which feels less than 100% intuitive to me
Cons:
- The Nuxt/Remix convention is arguably more aesthetically pleasing than
__section. Though as an aside, we’re using the__prefix convention anyway for__error.svelte, and we’ll likely add directory-scoped__middleware.jsat some point settings.jsis a more descriptive basename than__section.jssettings.jsandsettings/notifications.jslend themselves more easily to endpoint URLs (though we would need a way to disambiguate betweensettings.jsandsettings/index.jsendpoint URLs in any case)- We’re going against the grain. (Same as it ever was.)
In summary, I lean towards the __section proposal, but I would be curious to hear any arguments in favour of (or against) a more Nuxty/Remixy approach that I haven’t considered here.
Importance
would make my life easier
Additional Information
No response
Issue Analytics
- State:
- Created 2 years ago
- Reactions:25
- Comments:31 (15 by maintainers)

Top Related StackOverflow Question
Yeah, we had a discussion about this in the maintainers’ chat and concluded that keeping
__layoutis probably better on balance. A key realisation for me was that you wouldn’t want to get the data for a layout/section individually, i.e. there’d be no__layout.jsonor__section.json— instead, a page’s__data.jsonshould include the layout data as well as the leaf data. Otherwise you’ll find yourself making unnecessary round trips.Reading through all of these comments makes me wonder what the proposed difference would be between an endpoint “layout” or “section” vs endpoint middleware. It seems like the primary ask of this thread is to have endpoint wrapper logic, which seems like server middleware to me.
My primary use-case for this would be auth guards. I currently safelist certain paths and check for them in
handle(). I’d much rather have something likeroutes/api/__middleware.tsthat executes it’s ownhandle()like function for everything in its subtree.