'Extensible layout components in nextjs

I am creating an application in nextjs. I understand that I can generate a layout like the example given in the docs

import Navbar from './navbar'
import Footer from './footer'

export default function Layout({ children }) {
  return (
    <>
      <Navbar />
      <main>{children}</main>
      <Footer />
    </>
  )
}

However, I would like to change the contents of the Navbar on a per page basis.

export default function ListPage() {
  return {
    /** I want to add a secondary nav to the Navbar on this page */
    <>
      <Navbar><MySecondaryNav></Navbar>
      ....
    </>
  }
}

export default function ClientPage() {
  return {
    /** I want to add a a different secondary nav to the Navbar on this page */
    <>
      <Navbar><ClientNavbar></Navbar>
      ....
    </>
  }
}

I also need the markup to be rendered server-side. Is it possible to achieve this in nextjs?



Solution 1:[1]

Yes, you can!

You could use useRouter and then depending on the path render the correct component in NavBar

import { useRouter } from "next/router";
const router = useRouter();

now you should have access to router.pathname, depending on the pathname just render the correct component inside NavBar

@Edit - SSR solution

If you want this SSR, then this is how you do it

in your _app.tsx/jsx you can use getServerSideProps and then get directly resolvedUrl

export default function App({ Component, pageProps }) {

  return (
    <Layout {...pageProps}>
      <Component {...pageProps} />
    </Layout>
  );
}
export async function getServerSideProps({{req, res, resolvedUrl}) {

  return { props: { resolvedUrl } }
}

At this point you should be receiving resolvedUrl and based on that render the required component.

If this wont work for you we might need to setup a codesandbox

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1