Adding a Dark Theme to Next.js with Stitches

If you enjoy writing performant CSS with styled-components and need type-safety from Typescript when interfacing with design tokens then Stitches might be the solution right up your alley.

Stitches is a CSS-in-JS library that provides awesome DX and …


This content originally appeared on DEV Community and was authored by DEV Community

If you enjoy writing performant CSS with styled-components and need type-safety from Typescript when interfacing with design tokens then Stitches might be the solution right up your alley.

Stitches is a CSS-in-JS library that provides awesome DX and support for SSR frameworks like Next.js out of the box. In this tutorial, we will use Stitches to add a basic dark theme to a Next.js app with Typescript.

Initial Setup

Setting up Stitches with Next.js is easy and it works even better with the Typescript example from Vercel.

yarn create next-app --typescript nextjs-stitches-dark-theme

//then followed by
yarn add @stitches/react

Now we can create a config file that will export all of our API functions from the library, this can be created anywhere in your project, such as the root.

// stitches.config.ts
import { createStitches } from "@stitches/react";

export const { 
  styled, 
  getCssText, 
  createTheme, 
  globalCss 
} = createStitches({ 
  theme: {
    /* ... other tokens */
    colors: {
      text: "black",
      background: "white",
    }
  }
 });

// define the dark theme using the de-constructed function
export const darkTheme = createTheme({ 
  colors: { 
    text: "white",
    background: "black"
  } 
});

For a basic dark theme, we would want to use these theme tokens at a global level in the CSS specification, so we can use the globalCss function in the same config file to declare these styles.

// stitches.config.ts

/* ...previous code */

const GlobalStyles = globalCss({
  body: {
    //we can call the color token values with the
    //$ prefix in a string
    background: "$background", 
    color: "$text"
  }
})

//we can declare the styles here or in pages/_app.tsx
GlobalStyles();

While that is all for configuring Stitches, you might be wondering where is the ThemeProvider that most CSS-in-JS libraries like emotion or styled-components provides. Actually, a basic installation of Stitches does not need it, you can start using the styled function by exporting it from this config file and start styling components.

Creating a Theme Toggle

But for managing multiple themes, it is highly recommended to install an additional packaged called next-themes which will allow us to toggle between themes and override the theme-specific tokens, such as colours in this case.

yarn install next-themes

After adding the package, we can add the familiar theme provider component into our Next.js application.

// pages/_app.tsx
import type { AppProps } from "next/app";
import { ThemeProvider } from "next-themes";
import { darkTheme } from "../stitches.config";

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThemeProvider
      attribute="class"
      defaultTheme="system"
      value={{
        light: "light",
        dark: darkTheme.className
      }}
    >
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

And now we can create a toggle button to switch between the themes with the useTheme hook from next-themes;

// pages/index.tsx
import { styled } from "../stitches.config";
import { useTheme } from "next-themes";

const Button = styled("button", {});

export default function IndexPage() {
  const { theme, setTheme } = useTheme();
  const toggleTheme = () =>
    setTheme(theme === "light" ? "dark" : "light");

  return (
    <div>
      <h1>The current theme is {theme === "dark" ? "dark" : "light"}</h1>
      <Button onClick={toggleTheme}>Change Theme</Button>
    </div>
  );
}

And that is pretty much everything we need to have a dark mode theme with Stitches! 🎉

Additional Notes

Theming with Stitches, especially with a dark theme, requires a bit of forethought into the selection of the colour tokens since we would need to define our palettes with the same key name i.e. text is the same colour token key, but has a different value in the light and dark theme.

Luckily, the wonderful folks over at Modulz also provide a variety of colour palettes to choose from through their Radix-UI/colors package.

If this tutorial with Stitches suits your theming needs, then feel free to check out the full Codesandbox below:

Happy theming! ✨


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2022-03-14T02:59:48+00:00) Adding a Dark Theme to Next.js with Stitches. Retrieved from https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/

MLA
" » Adding a Dark Theme to Next.js with Stitches." DEV Community | Sciencx - Monday March 14, 2022, https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/
HARVARD
DEV Community | Sciencx Monday March 14, 2022 » Adding a Dark Theme to Next.js with Stitches., viewed ,<https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/>
VANCOUVER
DEV Community | Sciencx - » Adding a Dark Theme to Next.js with Stitches. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/
CHICAGO
" » Adding a Dark Theme to Next.js with Stitches." DEV Community | Sciencx - Accessed . https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/
IEEE
" » Adding a Dark Theme to Next.js with Stitches." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/. [Accessed: ]
rf:citation
» Adding a Dark Theme to Next.js with Stitches | DEV Community | Sciencx | https://www.scien.cx/2022/03/14/adding-a-dark-theme-to-next-js-with-stitches/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.