#Set theme classname on body from a page? (appDir)

1 messages · Page 1 of 1 (latest)

summer pebble
#

Each page is fetched from a CMS serverside and has a theme setting. I want to update the <body> adding that classname depending on the response. How do I do that?

I'm new to appDir, and before I did this with emotion's <Global>. But since emotion is not supported, I'm looking for other alternatives to do this.

Does anyone do this? How?

ruby swallowBOT
#

Hi @summer pebble. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the information provided in the extracts, you can use Next.js's getServerSideProps function to fetch data from your CMS server-side. However, please note that in the Edge Runtime, you do not have access to the response object. If you need access to the response object, you should continue to use the Node.js runtime, which is the default runtime. You can explicitly set the runtime on a per-page basis by modifying the config source (https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props).

export const config = {
 runtime: 'nodejs', // or "edge"
}
 
export const getServerSideProps = async () => {}

As for adding a class name to the <body> tag based on the response, you can do this in your custom _document.js file. However, please note that customizing renderPage is advanced and only needed for libraries like CSS-in-JS to support server-side rendering. This is not needed for built-in styled-jsx support source (https://nextjs.org/docs/pages/building-your-application/routing/custom-document).

#
import Document, {
 Html,
 Head,
 Main,
 NextScript,
 DocumentContext,
 DocumentInitialProps,
} from 'next/document'
 
class MyDocument extends Document {
 static async getInitialProps(
 ctx: DocumentContext
 ): Promise<DocumentInitialProps> {
 const originalRenderPage = ctx.renderPage
 
 // Run the React rendering logic synchronously
 ctx.renderPage = () =>
 originalRenderPage({
 // Useful for wrapping the whole react tree
 enhanceApp: (App) => App,
 // Useful for wrapping in a per-page basis
 enhanceComponent: (Component) => Component,
 })
 
 // Run the parent `getInitialProps`, it now includes the custom `renderPage`
 const initialProps = await Document.getInitialProps(ctx)
 
 return initialProps
 }
 
 render() {
 return (
 <Html lang="en">
 <Head />
 <body className="yourClassName">
 <Main />
 <NextScript />
 </body>
 </Html>
 )
 }
}
 
export default MyDocument

Regarding your question about Emotion, it's mentioned that Emotion is currently being tested out and more examples will be added for libraries that support React 18 features and/or the app directory. If you want to style Server Components, it's recommended to use CSS Modules or other solutions that output CSS files, like PostCSS or Tailwind CSS source (https://nextjs.org/docs/app/building-your-application/styling/css-in-js).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: