Next.js Discord

Discord Forum

Reading page property in layout.tsx.

Answered
Lawrence's Goldfinch posted this in #help-forum
Open in Discord
Lawrence's GoldfinchOP
Hello, so I have this page

const Page = () => {
  return <>Test</>;
};

Page.theme = "green";

export default Page;


I want to be able to read this property "theme" of this page in my layout.tsx so I can pass it to ThemeProvider component. I could do this before with using _app.tsx's Component but now with the removal of that I am nto sure if i can do that.

Here's my layout.tsx:

async function RootLayout({ children }: any) {
  return (
    <html suppressHydrationWarning={true} lang="en" className="scroll-smooth">
      <body suppressHydrationWarning={true} className={inter.className}>
        <ThemeProvider>
          <RainbowProvider>
            <header className="supports-backdrop-blur:bg-background/60 bg-menu container sticky top-0 z-40 m-0 w-full border-b p-0 text-[17px] backdrop-blur lg:mx-auto">
              <DesktopNav />
              <MobileNav />
            </header>
            <main className="container m-0 p-0 lg:mx-auto">{children}</main>
            <footer className="container m-0 p-0 lg:mx-auto">
              <Separator className="my-8" />
              <div className="flex justify-between p-4 md:p-8 lg:px-[62px]">
                <div>© 2023 BN Technology</div>
                <div>
                  <Link href="/privacy-policy">Privacy Policy</Link>
                </div>
                <div>
                  <Link href="/terms-and-conditions">Terms and conditions</Link>
                </div>
                <div className="flex">
                  <Twitter className="mx-4" />
                  <Instagram className="mx-4" />
                  <Youtube className="mx-4" />
                  <Linkedin className="mx-4" />
                </div>
              </div>
            </footer>
            <Toaster />
          </RainbowProvider>
        </ThemeProvider>
      </body>
    </html>
  );
}

export default RootLayout;
Answered by aardani
try creating something like this, im gonna send you a pseudocode
export function ThemeProviderOverrider({ children }) {
  const path = usePathname()
  
  return(
    <ThemeProvider forceTheme={path === '/specificroute' ? 'green' : undefined}>
      {children}
    </ThemeProvider>
  )
}
View full answer

87 Replies

Lawrence's GoldfinchOP
I found this - https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts

But its also talking about _app.js which as far as i know has been deprecated in next.js 13?
are you using pages dir or app dir?
in next.js 13 you can use both, but preferable only using one is more maintainable
Lawrence's GoldfinchOP
i use app dir
i dont think you can do that anymore in app dir
Lawrence's GoldfinchOP
😭
is there any other way I can pass value to a provider in the layout
from the page component
yeah
use a setter
call the setTheme hook from a child client component
Lawrence's GoldfinchOP
and I can read it in the layout.tsx ?
it will be read in the <ThemeProvider> during hydration from client
yes
Lawrence's GoldfinchOP
oh wow
ok, will try. thanks
like that?
no
the setter needs to come from the <ThemeProvider>
Theme Provider is a context provider that you can use in the child component
a context provider usually provides a setter() function and the theme value
there should be a hook that lets you consume the theme context provider already
Lawrence's GoldfinchOP
TIL, ok
@Lawrence's Goldfinch Click to see attachment
you only do this if you want to decide the initial theme from the server, which is usually not what you want to do
or else it will flash/shutter
Lawrence's GoldfinchOP
i want to have a specific page
that has a green theme
and the other ones should have completely different theme
whatever the user wants to have
try setting the theme on a useEffect then
check the docs, there should be a way to set the theme programmatically
Lawrence's GoldfinchOP
there is one way but when i set it in one page
it changes everywhere
oh
isn't there a way to just override the theme for a specific page
Lawrence's GoldfinchOP
and the docs use _app.tsx
what ui lib is it
Lawrence's GoldfinchOP
its this one
can't you just wrap another <ThemeProvider> on that specific page? and set it to green
Lawrence's GoldfinchOP
feels like its gonna break everything but gonna give it a try
😄
like that, right?
yeah
should be possible
TIL too aha
Lawrence's GoldfinchOP
never lucky
😭
wym
Lawrence's GoldfinchOP
still white
oh wait
ah
ahhh
i get it now
try creating something like this, im gonna send you a pseudocode
export function ThemeProviderOverrider({ children }) {
  const path = usePathname()
  
  return(
    <ThemeProvider forceTheme={path === '/specificroute' ? 'green' : undefined}>
      {children}
    </ThemeProvider>
  )
}
Answer
does that make mroe sense
Lawrence's GoldfinchOP
holy moly
ye
god help me if there's more pages with specific themes 😄
since in Pages dir, everything is a client component so sharing component attributes like Page.theme is possible. However, in RSC/app dir, server comps and client comps are interleaved and such, those context can be lost iirc
I haven't experimented much on this pattern
especially if Page is passed into the props of { children } and you can't extract attributes from { chidlren }, atleast without some hacky ways
Lawrence's GoldfinchOP
ye exactly
you cant get attributes from children
i will use the pseudocode pattern you sent me
thank you
lmk if it works
Lawrence's GoldfinchOP
will do
Lawrence's GoldfinchOP
worked out just fine
i don't like that it uses the usePathname hook, would like it more if i could somehow attach it to the page somehow but i think it's gonna work for now
will think of a new solution if this doesnt work anymore lol
thank you a looooot, i really appreciate your help and time ❤️
if i could help you somehow. rate you somethink, star something whatever you want just @ me 🙂
@Lawrence's Goldfinch i don't like that it uses the usePathname hook, would like it more if i could somehow attach it to the page somehow but i think it's gonna work for now
Its hard coz conceptually, due to partial rendering. Layouts are persistent while sub child may change or rerendered on server
@Lawrence's Goldfinch will think of a new solution if this doesnt work anymore lol
Should not change for a while, its the app router way after all
Lawrence's GoldfinchOP
🤞 that we wont have to add new feature that require a forced theme based on something else
ye i should read more about the way it renders stuff
all i know is server rendering is like in the old days with php rendering everything serverside
and clientside is "hell yeah, brother use that client's RAM"
Im also still exploring how to switch themes