Avoid layout unmount/remount
🐛 Bug Report
Most classic D2 sites will use the same layout component on every single page, apart from a few rare exceptions (like a code playground implemented with a custom page).
When navigating from one page to the other, the layout should not unmount/remount unnecessarily.
Currently, when navigating from the home page to the /docs page, the layout unmounts/remounts.
The only case I found where it does not unmount/remount is when navigating from one doc to another.
Avoiding unmounts/remounts when possible is important for 2 reasons:
- faster transition from one page to another
- avoid resetting state of the layout
Probably not urgent to work on this, just wanted to backlog it somewhere :)
Useful link: https://www.gatsbyjs.org/packages/gatsby-plugin-layout/
To Reproduce
yarn docusaurus swizzle @docusaurus/theme-classic Navbar
Add this button somewhere in the navbar:
const TestButton = () => {
const [bool, setBool] = useState(false);
return (
<button onClick={() => setBool((b) => !b)}>Toggle me {String(bool)}</button>
);
};

Expected behavior
Navigating should not reset the button state
Actual Behavior
The button state is reset
Edit: this is also a problem for our mobile drawer that may not animate properly on all page transitions, see https://github.com/facebook/docusaurus/discussions/11063#discussioncomment-12763738
@slorber Do you think this is ever attainable? FWIW, it seems like a very common problem in SSR sites. Unless we can have RSC or something similar, I don't think it's possible under the current architecture.
Yes this is achievable.
We need the layout to be declared statically on the route level so that te parent component can read that info and render the layout above the route (directly in docusaurus core)
addRoute({
layout: "@theme/Layout",
})
And we need a way for pages to declare that layout as well + a way to extract it from pages. Not sure what's the best solution, but maybe:
export const layout = "@theme/Layout";
This is not very different from how the docs sidebar is handled, just one layer above so that it can work when transitioning from one plugin to another.
We also need a way to have no layout.
For example if you want to create a standalone page not rendering the default layout but something unique.
export const layout = undefined
Just a note: the mobile sidebar collapses gracefully when navigating between doc pages because the layout doesn't unmount, but when navigating between two non-doc pages it just disappears without the animation