Unleash the Power of React Server Components with React18-Themes v2

Mayank Chaudhari
5 min readNov 30, 2023
https://github.com/react18-tools/react18-themes/

Are you ready to level up your React applications with the revolutionary React Server Components? Say goodbye to limitations and hello to enhanced theming capabilities with React18-Themes v2!

What’s New in Version 2?

Motivation for Migration:

In v2, we’ve upgraded server-side syncing using cookies and headers. This eliminates the need for a wrapper component, which forced server-side rendering of the entire app for each request. For apps serving mostly static content, the NextJsSSGThemeSwitcher can be used as first child of body along with CSS Combinators. Embrace the power of React 18 Server Components without sacrificing static site generation(SSG).

Migration Guide Highlights:

  • No changes required for projects not using Next.js app router or server components, except for updating the cookies' policy if required.
  • Persistent storage with cookies: Say goodbye to localStorage as we've shifted to cookies for improved server-side syncing.
  • Introducing NextJsSSGThemeSwitcher: No more wrapper components disrupting static generation. Enjoy improved performance and flexibility.

Check out the detailed migration guide to ensure a seamless transition.

Key Features:

  • Fully Treeshakable: Import only what you need from react18-themes/client/component.
  • Full TypeScript Support: Seamless integration with TypeScript projects.
  • Works with All Build Systems/Tools/Frameworks for React 18: Enjoy compatibility across various development environments.
  • Perfect Dark Mode in 2 Lines of Code: Effortlessly implement dark mode with minimal code.
  • System Setting with Prefers-color-scheme: Respect user preferences for a cohesive user experience.
  • Themed Browser UI with Color-scheme: Elevate your app’s aesthetics with themed browser UI.
  • Support for Next.js 13 and 14 appDir: Stay up-to-date with the latest Next.js features.
  • Sync Theme Across Tabs and Windows: Provide a consistent theme experience across multiple user sessions.
  • Theme in Sync with Server Component: Ensure your theme is synchronized seamlessly with server components.
  • Disable Flashing When Changing Themes: Enhance user experience by eliminating theme change flashes.
  • Force Pages to Specific Themes: Take control of individual page themes for a customized experience.
  • Class or Data Attribute Selector: Flexibility in styling based on your preferred selector.
  • Manipulate Theme via useTheme Hook: Empower your components to interact with and manipulate the theme dynamically.

Installation

$ pnpm add react18-themes
# or
$ npm install react18-themes
# or
$ yarn add react18-themes

Lite Version Available

Lite Version Installation:

$ pnpm add react18-themes-lite
# or
$ npm install react18-themes-lite
# or
$ yarn add react18-themes-lite

Note: Zustand is required as a peer dependency.

Usage

Single Page Applications (SPA) and Next.js Pages Directory (No Server Components)

For SPA projects and Next.js pages without server components, enhance your _app file:

import { ThemeSwitcher } from "react18-themes";

function MyApp({ Component, pageProps }) {
return (
<>
<ThemeSwitcher forcedTheme={Component.theme} />
<Component {...pageProps} />
</>
);
}

export default MyApp;

Enjoy dark mode support with just two lines of code!

Explore advanced usage examples.

With Next.js app Router (Server Components)

Prefer Static Generation over SSR — No Wrapper Component

Modify your app/layout.jsx to include NextJsSSGThemeSwitcher and ThemeSwitcher:

// app/layout.jsx
import { ThemeSwitcher } from "react18-themes";
import { NextJsSSGThemeSwitcher } from "react18-themes/server/nextjs";

export default function Layout({ children }) {
return (
<html lang="en">
<head />
<body>
{/* Use NextJsSSGThemeSwitcher as the first element inside the body */}
<NextJsSSGThemeSwitcher />
<ThemeSwitcher />
{children}
</body>
</html>
);
}

Prefer SSR over SSG — Use Wrapper Component

For dynamic content with SSR, continue using ServerSideWrapper:

// app/layout.jsx
import { ThemeSwitcher } from "react18-themes";
import { ServerSideWrapper } from "react18-themes/server/nextjs";

export default function Layout({ children }) {
return (
<ServerSideWrapper tag="html" lang="en">
<head />
<body>
<ThemeSwitcher />
{children}
</body>
</ServerSideWrapper>
);
}

HTML & CSS

For Next.js apps supporting dark mode, use the data-theme attribute on the html element:

:root {
/* Your default theme */
--background: white;
--foreground: black;
}

[data-theme="dark"] {
--background: black;
--foreground: white;
}

/* v2 onwards when using NextJsSSGThemeSwitcher, use CSS Combinators */
[data-theme="dark"] ~ * {
--background: black;
--foreground: white;
}

useTheme Hook

Components needing theme information can utilize the useTheme hook:

import { useTheme } from "react18-themes";

const ThemeChanger = () => {
const { theme, setTheme } = useTheme();

return (
<div>
The current theme is:
{theme}
<button onClick={() => setTheme("light")}>Light Mode</button>
<button onClick={() => setTheme("dark")}>Dark Mode</button>
</div>
);
};

Force Per Page Theme and Color-scheme

Next.js App Router

import { ForceTheme } from "react18-themes";

function MyPage() {
return (
<>
<ForceTheme theme={"my-theme"} />
{/* ... */}
</>
);
}

export default MyPage;

Next.js Pages Router

For pages router, either use the app router approach or the theme property:

function MyPage() {
return <>{/* ... */}</>;
}

MyPage.theme = "my-theme";

export default MyPage;

Similarly, you can force the color scheme.

Migrating from v1 to v2

Motivation:

For server-side syncing, we now use cookies and headers, rendering the component and its children server-side for each request. The NextJsSSGThemeSwitcher replaces the wrapper component, enabling server-side rendering for this specific component.

Migration Steps:

  • No changes needed for projects not using Next.js app router or server components, except for updating the cookies' policy if needed.
  • Persistent storage now uses cookies instead of localStorage. Update your cookies' policy accordingly.
  • Introducing NextJsSSGThemeSwitcher - no need for a wrapper component that disrupted static generation and forced SSR.

Visit the migration guide for detailed steps.

Migrating from v0 to v1

  • defaultDarkTheme is renamed to darkTheme
  • setDefaultDarkTheme is renamed to setDarkTheme
  • defaultLightTheme is renamed to lightTheme
  • setDefaultLightTheme is renamed to setLightTheme

Documentation

Start Exploring!

Don’t forget to check out the live example to witness the power of React18-Themes in action!

License

Licensed under MIT open source.

🤩 Don’t Forget to Star This Repo!

Ready to embark on a hands-on course for getting started with Turborepo? Dive into React and Next.js with TypeScript.

🌟 with 💖 by Mayank Kumar Chaudhari

Ready to revolutionize your React applications? Upgrade to React18-Themes v2 today and unleash the true power of React Server Components! 🚀🎉

--

--

Mayank Chaudhari

Technical Writer | Developer | Researcher | Freelancer | Open Source Contributor