CSS-in-JS within app dir

CSS-in-JS libraries often have a provider component that needs to wrap your entire application, we'll explore how to do this with a Providers client component that wraps our app. Although client components can't include server components, we can have a client component with server components as children.

Getting Started

we'll create a root layout for our app that will wrap its children with the Providers component. And a page server component that will use client components from the Chakra UI library.

|/app
|__/layout.js (client)
|__/page.js (server)
|__/providers.js (client)
// app/providers.js
'use client'

import { ChakraProvider } from '@chakra-ui/react'

const Providers = ({ children }) => (
  <ChakraProvider>{children}</ChakraProvider>
)

export default Providers
// app/layout.js
import { Page } from '@vercel/examples-ui'
import Providers from './providers'

const RootLayout = ({ children }) => (
  <Page className="flex flex-col gap-6">
    <Providers>{children}</Providers>
  </Page>
)

export default RootLayout

After setting up Chakra in the layout component, we can now use some of its components in the page:

// app/page.js

import { Text } from '@vercel/examples-ui'
import { Buttons, Tabs, Skeletons } from './showcase'

const IndexPage = () => (
  <section className="flex flex-col gap-6">
    <article className="flex flex-col gap-3">
      <Text variant="h2">Buttons</Text>
      <Buttons />
    </article>
    <article className="flex flex-col gap-3">
      <Text variant="h2">Tabs</Text>
      <Tabs />
    </article>
    <article className="flex flex-col gap-3">
      <Text variant="h2">Skeleton</Text>
      <Skeletons />
    </article>
  </section>
)

export default IndexPage

This way, your layout and page components are still server components, where you can fetch data from the server, and more.

Demo

Click here to see a working demo.