Next.js Discord

Discord Forum

A issue in RootLayout.

Answered
Huntaway posted this in #help-forum
Open in Discord
HuntawayOP
hello, so here the code
export default function MyPage() {
  // page content
}

MyPage.hideLayout = true;

now can can we get this hideLayout in RootLayout?
Answered by fuma
You are not allowed to pass data from a page to layout in App Router, please consider other alternatives such as detecting pathname in a client component with usePathname hook
View full answer

157 Replies

@Ejayz || PiggyDev you mean pass the data from pages.js to layout.js ?
HuntawayOP
pass data from page.js
and want data in layout.js
You are not allowed to pass data from a page to layout in App Router, please consider other alternatives such as detecting pathname in a client component with usePathname hook
Answer
i don't want to show navbar in 404 error
also what about /dashbaord/[id]/settings
Use a global not-found page for that
Your not-found.tsx is passed to the nearest layout
@fuma Your `not-found.tsx` is passed to the nearest layout
HuntawayOP
how make this global?
where is your not-found?
Like app/not-found or somewhere else
@fuma Like `app/not-found` or somewhere else
HuntawayOP
yes app/not-found
same like app/layout.js
i just want to remove navbar for not found page
I see your issue here, the global not-found is rendered in the root layout (since you may want to keep the fonts, etc).
You may want to use [Route Groups](https://nextjs.org/docs/app/building-your-application/routing/route-groups) in order to extract your navbar from the root layout
also you say that use usePahtname
Unhandled Runtime Error
Error: usePathname only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
it also not work
export default function RootLayout({ children }) {
> 49 | const pathname = usePathname();
Use route groups,
HuntawayOP
how but can you explain
By using multiple Route Groups, you can make the layout only rendered in specific pages

For pages that need a navbar, put it in /app/(your-group)/ where /app/(your-group)/layout.tsx includes a navbar
HuntawayOP
okay but what about not found
and you always need a root layout, please read the docs
HuntawayOP
it on global
Then it is what you expect
not-found is rendered in the nearest layout, in this case, your root layout no longer contains navbar
because it is in the layout of your route group now
HuntawayOP
so per group like app/shop/[id]/cart
so i need to add layout there app/shop/layout.js?
like this way?
@fuma Please read the docs, I think you misunderstood what is a route group
HuntawayOP
pls just 2 secs reply
is i am right
or wrong?
I can't understand your intention
Route groups look like app/(something)
not a regular folder
HuntawayOP
i mean i have a shop folder
so in folder i want to add new layout?
/app/shop/layout.js
to remove navbar
Why? It is not how Route groups work or what I am telling you
it is not /app/shop/ but /app/(shop)/
HuntawayOP
okay
the layout is only rendered when your page is under that route group
so you can put your navbar there
HuntawayOP
it also export like export default function RootLayout({ children }) {}?
Yes, it is same for all layouts
HuntawayOP
okay
notice that the root layout must contain the html and body tag, while sub layouts don't
HuntawayOP
in (shop) there are a new layout global layout no matter here
That is wrong, everything must be rendered in root layout
HuntawayOP
or can we do
/app/shop/[id]/(store)/page.js
Where the navbar should be added?
Only for not found pages?
@fuma Where the navbar should be added?
HuntawayOP
I want the navbar all pages, but for the store page, I want to remove the navbar from the top and add a new side navbar.
When rendering /app/(group)/page.tsx, it is similar to:

<RootLayout>
  <RouteGroupLayout>
    <YourPage />
  </RouteGroupLayout>
</RootLayout>


Route Group can only control which layout to use in the same level, Hence:
- app/shop/[id]/(store)/layout.tsx renders sidebar only
- app/shop/[id]/(other)/layout.tsx renders navbar only
HuntawayOP
okay
in app/shop/[id]/(store)/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AuthOptions>
          <SideNavbar />
          <main>{children}</main>
        </AuthOptions>
        <Footer />
      </body>
    </html>
  )
}
like this?
No, root layout must be under app folder
and it contains html and body tags
yes
HuntawayOP
what is issue here?
@fuma No, root layout must be under `app` folder
layout under a route group isn't called root layout, root layout means the layout that always renders (usually in app/layout)
Put your html and body tag in root layout
HuntawayOP
okay
export default function RootLayout({ children }) {
  return (
        <AuthOptions>
          <SideNavbar />
          <main>{children}</main>
        </AuthOptions>
        <Footer />
  )
}
like this?
in app/shop/[id]/(store)/layout.tsx
Yes, wrap it in a fragment since the syntax is invalid
also rename it to StoreLayout or something similar
HuntawayOP
okay so like this
export default function StoreLayout({ children }) {
  return (
        <AuthOptions>
          <SideNavbar />
          <main>{children}</main>
        </AuthOptions>
        <Footer />
  );
}
export default function StoreLayout({ children }) {
  return (
      <>
        <AuthOptions>
          <SideNavbar />
          <main>{children}</main>
        </AuthOptions>
        <Footer />
      </>
  );
}
HuntawayOP
we need to proivde auth option here or not?
I don't know what is your auth options
@fuma I don't know what is your auth options
HuntawayOP
its a session of nextauth
which some from client component
Depends on you, you may put it in root layout if it doesn't render anything
@fuma Depends on you, you may put it in root layout if it doesn't render anything
HuntawayOP
export default function StoreLayout({ children }) {
  return (
      <>
          <SideNavbar />
          <main>{children}</main>
        <Footer />
      </>
  );
}
i think this works
Has your problem solved?
@fuma Has your problem solved?
HuntawayOP
trying if it work or not
404 page come
not works
where is your page and how do you access it?
HuntawayOP
Route groups don't affect the actual url, use (settings)/settings/page.js
you can access the page in /dashboard/xxx/settings
work
but navbar still there
both navbar comes
side and top
where does the navbar render? Make sure you're not rendering it in root layout
@fuma where does the navbar render? Make sure you're not rendering it in root layout
HuntawayOP
it rendering main layout app/layout.js
HuntawayOP
hmm??
i added everything
as you said to me
app/shop/[id]/(other)/layout.tsx -> Your navbar, not the main layout
HuntawayOP
app/shop/[id]/(settings)/layout.tsx
import SideNavBar from "@/componenets/SideNavbar"
import AuthOptions from "@/components/AuthProvide";

export default function SettingsLayout({ children }) {
    return (
        <>
            <AuthOptions>
                <SideNavBar />
                <main>{children}</main>
            </AuthOptions>
        </>
    );
}
i also need to make (other)?
Yes, in that route group, you render the navbar
HuntawayOP
this is my app/layout.js
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AuthOptions>
          <Navbar />
          <main>{children}</main>
        </AuthOptions>
        <Footer />
    </html>
  )
}
can't find what wrong here
Well, you're rendering the navbar in root layout, of course, it doesn't disappear because your root layout is always rendered no matter what.

Please [read the docs](https://nextjs.org/docs/app/building-your-application/routing/route-groups) and find the correct usage of route groups, I won't help with everything
HuntawayOP
so i need to remove navbar from root and add it (shop)
true
HuntawayOP
right?
for all pages i need to make app/(pageFolder)/layout.js
or i need to just make (dashboard) and (others)
for all pages i need to make app/(pageFolder)/layout.js
For what?
HuntawayOP
like i want navbar for all pages but for /dashboard i want sidenavbar
Correct, you can put all pages except /dashboard into a route group, and put /dashboard into a specific group like (dashboard)
HuntawayOP
how can we devide but
like where we need navbar
where we not
(others) -> with navbar
(dashboard) -> with sidebar
tbh, I believe if you knew how to use Route Groups, you won't even ask this question here
HuntawayOP
still issue lol
for /dashboard need navbar
for /dashboard/id/settings
not need navbar
:meow_stare:
also for domain.com
we need navbar to
:this_is_fine:
When it is a complex logic, you can try either:

1. Still, route groups

so move /dashboard under your (others) route group, and create another /dashboard in (dashboard) route group
Hence, (dashboard)/dashboard/id/settings/ doesn't share the layout with (others)

2. usePathname

Manually check and return an empty fragment if user open specific page, for instance:

const pathname = usePathname()
if (pathname.startsWith(...)) return <></>

return <nav />

Notice that you have to mark it as client component
HuntawayOP
2 works find
so for path dashboard can we do /dashboard/
???
For option 2?
HuntawayOP
yes
to find out that path is /dashboard/id/settings
First, get params with useParams hook
Then, check the pathname with:
pathname.startsWith(`/dashboard/${params.id}/settings`)


you know what to do
<Navbar id={ id } />
we can do
pathname.startsWith(`/dashboard/*`)
No, it doesn't support regex, you may use regex match but I won't help with that
please find a solution yourself, this is just a common Javascript question
HuntawayOP
hmmk
@fuma please find a solution yourself, this is just a common Javascript question
HuntawayOP
here we go
let pathname = usePathname();
let result = pathname.match(/^\/dashboard\/.*/);