Hello,
Long time user, first time issue writer.
In a recent project, I found myself adding the same code to every single page that Inertia was returning. Since I am trying to create the SPA experience, and assume all that use Inertia have the same end goal, I want a persistent layout.
import Layout from "@layouts/Default";
export default {
props: ["user"],
layout: Layout
};
Now, this isn't _that bad_ but I am now about 30 pages into my app and feel like this could be a bit of a better experience.
My request is to somehow make the layout a global setting that can be assigned once, and still be able to override this _should_ i need to use a different layout somewhere else in my app.
I will now click "Submit new issue" which really means, "Submit this feature request" in this case and wait for a response.
Thanks,
Yaz.
~Hmmm, can't you register the Layout as a global component and use that as a temporary solution? Looks like it would save you at least one import each time you make a new view :)~
Doesn't work, sorry
I think you can intercept resolveComponent and change the module layout.
resolveComponent: name => import(@/pages/${name}).then(module => {
if (!module.default.layout) {
module.default.layout = MainLayout
}
return module.default
})
I think you can even go further and on pages provide a string instead of importing layout on each page. Imagine you have a login page and you want to use different layout then instead of importing Layout in Login page you can just provide layout: 'LayoutName' then your resolveComponent can check if there is a string value then you can just import that from the layouts and use that.
I guess you can also check Nuxt's code to see how they do but I guess they do similar too.
Thanks
So I spent some time this morning hacking on this, (testing the solution in #212), and I actually think @azal-io's solution here is the right way to go鈥攊nstead of adding a new prop for this in each adapter.
Here's how easy it is to do this in the resolveComponent() callback:
resolveComponent: name => import(`./Pages/${name}`).then(({ default: page }) => {
page.layout = page.layout === undefined ? Layout : page.layout
return page
}),
And, what's really cool about this approach is that this method receives the current page name, meaning you can actually conditionally set the default layout based on this. For example:
resolveComponent: name => import(`./Pages/${name}`).then(({ default: page }) => {
if (!name.startsWith('Public/') && page.layout === undefined) {
page.layout = Layout
}
return page
}),
And, with both of these approaches, because I'm doing an explicit === undefined check, you can still disable this on a per page basis by setting layout: null.
Given how easy this is to do, and actually more powerful because of the name being available, I think I'm going to update the documentation to recommend this approach, and not build this into the adapters as a new prop.
Documentation has been added for this "feature": https://github.com/inertiajs/inertiajs.com/commit/97cc6787488576c891bff02d37f6c95bfa9352f0
Which you can see here: https://inertiajs.com/pages#default-layouts
Most helpful comment
I think you can intercept resolveComponent and change the module layout.
resolveComponent: name => import(@/pages/${name}).then(module => { if (!module.default.layout) { module.default.layout = MainLayout } return module.default })I think you can even go further and on pages provide a string instead of importing layout on each page. Imagine you have a login page and you want to use different layout then instead of importing Layout in Login page you can just provide
layout: 'LayoutName'then your resolveComponent can check if there is a string value then you can just import that from the layouts and use that.I guess you can also check Nuxt's code to see how they do but I guess they do similar too.
Thanks