menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Next.js

A place to chat about Next.js and answer questions. For all other ZEIT products, check this out.

Channels
Team

Is there a way to persist a layout for a given set of routes?

September 26, 2018 at 11:04am
The Next.js community has a new home. This thread is preserved for historical purposes. The content of this conversation may be innaccurrate or out of date. Go to new community home →

Is there a way to persist a layout for a given set of routes?

September 26, 2018 at 11:04am
I see that you can modify _app.js to persist a layout between pages. But lets say I have a /home, /about, and /login page that I don't want a persisted layout. But then I have /dashboard /dashboard/clients /dashboard/statistics where I want a dashboard layout to persist. Is there a way to achieve this? Thanks :)
Show previous messages

September 27, 2018 at 11:50pm
I actually do this! After a conversation with you ;)

September 28, 2018 at 11:40am
Hmm interesting! Thanks for the idea. Is there a next example repo demonstrating this??
Oh I guess it's as simple as passing a function from _app.js down haha. Sometimes when trying something new things seem like magic. Glad next is so simple. Thanks for this idea!
Here's an example:
_error.js:
import React from 'react'
export default class Error extends React.Component {
static getInitialProps ({ res, err }) {
const statusCode = res ? res.statusCode : err ? err.statusCode : null
return { statusCode }
}
static isErrorPage = true
render () {
return (
<h1>
{this.props.statusCode
? `An error ${this.props.statusCode} occurred on server`
: 'An error occurred on client'}
</h1>
)
}
}
_app.js:
import App, { Container } from 'next/app'
import Layout from 'components/Layout'
export default class MyApp extends App {
static async getInitialProps ({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
render () {
const { Component, pageProps } = this.props
return (
Component.isErrorPage
? (
<Container>
<Component {...pageProps} />
</Container>
)
: (
<Container>
<Layout>
<Component {...pageProps} />
</Layout>
</Container>
)
)
}
}
This renders the Layout component everywhere except the custom error page.
like-fill
2
Love it thank you for sharing this
Agreed, thanks for sharing an example!
Just to ward off any future bugs: make sure any HOCs you make/add around your pages use hoist-non-react-statics, so those properties don't get lost!
like-fill
1

September 29, 2018 at 11:52am
Also I wanted to clear up that it's probably better to do static Layout = YourComponent instead of passing up a true/false value, as that wouldn't scale if you have multiple layouts, or multiple conditions
Say if you have 2 or 3 layouts they'd all be shipped in _app.js to the client side, whereas when using static Layout = YourComponent would only have the specific layout needed to render the page
Using static Layout is also more flexible as the page defines what layout to render and it can be wrapped etc
Alternatively you could use next/dynamic to only load the javascript that has been rendered in _app.js
like-fill
1

October 8, 2018 at 6:31pm
Wow this great thank you
This would probably make a great first contribution, i.e. https://github.com/zeit/next.js/tree/master/examples

October 9, 2018 at 3:20am
How can I access these static property in "routeChangeStart(url)" event?
Do you have an example for that?

October 10, 2018 at 3:59pm
In _app.js
<Container>
<Component.Layout>
<Component { ...pageProps} />
</Component.Layout>
</Container>
In pages/mypage.js
const MyPage = () => <div></div>
MyPage.Layout = MyLayout;
MyPage.getInitialProps = async () => ({});
export default MyPage;
like-fill
6

August 15, 2019 at 10:20am
I really like this solution. Wrote a little type to make typescript stop complaining. But fairly uncertain these are correct.
type LayoutComponent = NextComponentType<NextPageContext, any, any> & {
Layout?: any;
};
interface Props extends AppProps {
Component: LayoutComponent;
}
Edited

August 21, 2019 at 2:43pm
So this works.. except now I have a server/client mismatch with Styled components. could this be a timing issue?

November 6, 2019 at 10:39am
The above solutions work, how could i do something similar to what proposed but for .mdx files?
Using a static true/false works, however is it possible to implement something like Page.Layout = Layout for .mdx files?
Edited