-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Reset layout inheritance in nested routes #626
Comments
I had the same request. IMO, it is simple, clear, and consistent to the current layout mechanism. |
@zwz I like the idea, but would reconsider the name. From a quick glance the difference between Maybe |
That's because that is the Regarding this request, this is something that has come up several times. There has been quite a bit of discussion around what the best way is to achieve this. Additional I'm inclined to think that this kind of behaviour is better handled with a config file, but I know that Rich is (or at least has been) against adding a config file to Sapper. I am personally of the opinion that with the amount of CLI options we now have and with feature requests like this, a configuration file should be reconsidered. One other option is to use a special layouts folder to 'shadow' specific layouts (or vice-versa—define them in a layouts file and shadow them in If a config file is the best way to go then we need to have a conversation about whether or not we should have a configuration file in Sapper (and some related details) before this issue is tackled. |
@pngwn could you elaborate how a config file would look like to solve this layout inheritance issue? Would there be a root config with a list of routes that inherit/don't inherit layouts? For now I will make layout components and import them explicitly until there is a Sapper solution. I think that is what one would do in Next.js. |
No, I couldn't because I've given it approximately zero thought. But it seems like it might provide a relatively flexible solution. |
Another idea:
or
All the ideas proposed so far work for me. |
@InstanceOfMichael I don't think this is an issue that should/can be solved in Svelte. It only concerns how Sapper builds pages by building a Svelte component per page and nesting all If I use Svelte outside of Sapper, there is no concept of layout inheritance. |
Throwing in my 2 sense... Would it make sense to return a configuration object as part of the output of preload or another method like preload? That way you have a place in JS where you can make the decision on how a layout needs to behave. Hypothetically. I like the idea of it being part of the route path as well. But this would give programatic control. For example a blog post that is part of a series and should inherit the current layout, vs is not part of a series and should not. |
@khrome83 I'm not sure if that is a possible solution. As I understand it |
I think that the hole layout thing makes no sense, is better if each page imports the layout |
Hello everyone, but maybe you’ll make a type like this person’s, he added _reset.svelte ? |
Any progress? |
I found the routify (https://routify.dev/ ) approach very straightforward, if you have a _reset.svelte file on a folder, you use that and stop traversing the filesystem. I don't get by there a 2 projects with so many similarities instead of one, it's a hard decision to make a choice between booth, I'm evaluating what to use for a very constrained device (a tv with a low end SOC), and using svelte instead of angular has bring a lot of improvement to the speed of the interface, but having to decide between so many options on routing is tiresome |
I really like the I am amazed Sapper does not yet have the ability to use multiple layouts. |
Created a PR with _reset.svelte implementation: sveltejs/sapper#1141 |
I actually quite like the |
@joycollector it appears there may need to be some more thought put into a solution for this. As @pngwn pointed out:
Likewise, what if one is nested three deep and wants to re-inherit the root layout. As much as I ::shudder:: at the thought of a config file to solve this, sadly 🐧 might be right. Let's keep digging on solutions until we can hit something that answers all the right questions. |
I'd favour the |
A few things:
What about if layout files had an (optional) layout name:
and then to manage inheritance:
This might be harder to express, however, but something along those lines would allow your layout choice not to depend on hierarchy. |
@antony mmmm...interesting idea there, but I can poke holes in it. Which layout is the default? What if you want to use a particular layout, but don't need to change it—does that mean just putting an empty file with the same name in the nested folder? Seems an odd convention. At first I liked the idea until I saw these holes. I am wondering though if this is closer... |
@arxpoetica my intention was (and I didn't express it as I didn't want to muddy the waters), that it would work the same as it does now. The The behaviour of sub-directories would be similar. It's not unusual to have (in file-system based routing), a layout file which simply defines |
I quite like the Routify way of doing it, just a _reset.svelte file in the folder you want to stop the inheritance in: https://github.com/sveltech/routify-starter/tree/master/src/pages/example/reset Might it be a good idea to make the API cross-over as much as possible between the two projects? Maybe it's not something that's possible to do though. |
Hi there, I am only learning sapper and svelte right now and I was browsing the web for a "sapper change layout", to discover the discussion is quite actual. |
@elromano it's not stupid IMO, for me it would also make sense if layouts wouldn't add up. We would be able to create different layout components and use them as desired in |
I think it should be easier but I did following for a personal project:
if the segment is profile it renders slot but the default is still my main layout, therefore I can use custom _layout.svelte for that segment. |
Routify handles this problem really well with their |
Is this an actual concern? I don't really think so, but could be wrong.
then just use
again. |
It's funny that there is no solution for such a simple issue. I'm decided to rebuild my app with Nuxt.js (Vue.js) or maybe React. This wasn't what you told us Mr @Rich-Harris . |
@babakfp attitude + take a look at routify if you need extreme routing capabilities "right now or else" |
@babakfp what a pity your tone. |
The route manifest is generated purely based on the files inside
then your route manifest would look like this: import * as layout from "../../../src/routes/$layout.svelte";
const components = [
() => import("../../../src/routes/foo/$layout.svelte"),
() => import("../../../src/routes/foo/bar/$layout.svelte"),
() => import("../../../src/routes/foo/bar/baz/$layout.svelte"),
() => import("../../../src/routes/foo/bar/baz/index.svelte")
];
export const routes = [
// src/routes/foo/bar/baz/index.svelte
[/^\/foo\/bar\/baz$/, [components[0], components[1], components[2], components[3]]]
];
export { layout }; In other words you need to import all those components. That's true regardless of whether one of those layouts has the src/routes/$layout.svelte
src/routes/foo/$layout.svelte
src/routes/foo/bar/$layout.svelte
-src/routes/foo/bar/baz/$layout.svelte
+src/routes/foo/bar/baz/$layout.reset.svelte
src/routes/foo/bar/baz/index.svelte import * as layout from "../../../src/routes/$layout.svelte";
const components = [
- () => import("../../../src/routes/foo/$layout.svelte"),
- () => import("../../../src/routes/foo/bar/$layout.svelte"),
- () => import("../../../src/routes/foo/bar/baz/$layout.svelte"),
+ () => import("../../../src/routes/foo/bar/baz/$layout.reset.svelte"),
() => import("../../../src/routes/foo/bar/baz/index.svelte")
];
export const routes = [
// src/routes/foo/bar/baz/index.svelte
- [/^\/foo\/bar\/baz$/, [components[0], components[1], components[2], components[3]]]
+ [/^\/foo\/bar\/baz$/, [components[0], components[1]]]
];
export { layout }; (I'm glossing over the fact that right now the root layout is always included; we'd need to start explicitly including it in route definitions if we started having resets. Which is totally fine as it would actually simplify some stuff.) |
Interesting! You can also use |
Would it be possible then to have one layout in-between have it reset, but everything below will be able to opt in to all parent's layouts again? Like a |
@dummdidumm what's the usecase? (I already asked this somewhere in this thread)
on root If it's no implementation overhead, of course it would be cool. |
@Florian-Schoenherr A use case I have found is a kind of "summary" page in a long journey. You would want the layout all the way down but somehow exclude it for that page and then be included afterwards. At the moment I just toggle components in my layout page based on the page path, but that requires anyone updating my "summary" page to be aware that they need to go up the tree and update the layout if they want to make changes. |
@seanlail 😕 |
@Florian-Schoenherr very true. That does make it simpler. I guess then the restore part is left? Would the reset only work in that specific route and not cascade? |
What about |
Hi @Rich-Harris @SillyFreak |
@babakfp |
* failing test for #626 * update create_manifest_data and unit tests * update types * get existing tests working * WIP * nested error pages working in SSR, pass error/status via load * most tests passing * make it possible to filter tests * all tests passing except the new one * refactor some stuff, fix types * fix/simplify caching * refactoring and stuff * remove unused property * bypass _load on initial hydration * pass entire route to this._load * fix caching * it works * lint/check * document a and b * explain what layout_stack and error_stack are * slight touch-up * document nested error pages * changeset
I’m just a newbie. src/routes/$layout.svelte <---src/routes/index.svelte----> <---src/routes/foo/index.svelte----> <---src/routes/foo/bar/index.svelte----> |
A Huge thanks! @Rich-Harris 🎉 🎉 |
Is your feature request related to a problem? Please describe.
When building a website I want pages to share a specific layout with common UI elements like a navigation, sidebar, footer, etc. Other pages might want to use different layouts like a custom landing page. This works fine as long as my landing page is not a sub page of an existing page with layout.
In this example
/bikes
has a custom layout. Individual bike routes like/bikes/fancy-bike-3000
add their own layout and inherit the one from/bikes
.The problem appears when I want to make a super fancy landing page to promote all my mountain bikes. This page is completely individual and uses its own layout.
/bikes/category/mountain-bike-promo
will always inherit the layout from/bikes
, but in this case it's not wanted.Sapper needs a feature to bail out of the layout inheritance and let sub pages define their own layouts.
Describe the solution you'd like
I would like an API that allows me as developer to get more flexibility when needed but has the layout inheritance by default.
Ideas:
layout/
folder with custom layouts that you can specify in your page (https://nuxtjs.org/api/pages-layout). This probably doesn't work well with the current inheritance model but I like it.Describe alternatives you've considered
In the end it's always possible to import layout components like any other component on every page. This provides full flexibility but can be a bit cumbersome if something like the inheritance model already exists.
A different solution could be to structure routes differently but a site structure should ideally not be constrained by the framework of choice.
How important is this feature to you?
I think this is a use case every application of a particular size will eventually run into. May it be custom landing pages or interactive stories with data visualizations.
Additional context
There was a former discussion in this issue sveltejs/sapper#809.
The idea to hide elements in a root layout based on
segment
doesn't really work since not the full route is available.Looking at my example
bikes/_layout.svelte
hassegment === "category"
butmountain-bike-promos
is needed to know if layout components need to be hidden.I look forward to any API discussion and can maybe come up with an implementation if this is a feature you want to integrate into Sapper.
The text was updated successfully, but these errors were encountered: