Theme UI is a React styling library “based on constraint-based design principles”, where we can centralize our design tokens in a regular JavaScript theme object . Although there’s no Theme UI plugin specifically for NextJS like for Gatsby, we can add Theme UI to our NextJS web app/site in three straightforward steps.
1. Install theme-ui
npm i -D theme-ui
# or yarn add theme-ui
2. Create and export the theme object
// src/utils/theme.js
export default {
colors: {
text: "#111",
background: "#fff",
primary: "tomato",
secondary: "#3f3f3f",
muted: "#e0e0e0",
highlight: "#9f9f9f",
gray: "#6c6c6c",
accent: "#3f3f3f",
},
fonts: {
body: "Comic Sans MS",
},
};
You can use any filename and directory, just make sure you import it correctly in the next step. See more theming references and demo in the Theme UI docs.
3. Wrap our NextJS app with Theme UI’s ThemeProvider
We achieve this by making use of NextJS’s custom App
.
// src/pages/_app.js
import * as React from "react";
import NextApp from "next/app";
import { ThemeProvider } from "theme-ui";
import theme from "../utils/theme"; // theme object from step 2
export default class App extends NextApp {
render() {
const { Component, pageProps } = this.props;
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
);
}
}
We also add Theme UI’s InitializeColorMode
to NextJS’s custom Document
to prevent flash of colour.
// src/pages/_document.js
import Document, { Main, NextScript } from "next/document";
import { InitializeColorMode } from "theme-ui";
export default class extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
// Replace html lang attribute value with your language.
return (
<html lang="en">
<body>
<InitializeColorMode />
<Main />
<NextScript />
</body>
</html>
);
}
}
Learn more:
- https://theme-ui.com/api/#initializecolormode
- https://nextjs.org/docs/advanced-features/custom-app
- https://nextjs.org/docs/advanced-features/custom-document
Does it work?
We should be able to use the sx
property in our components. Remember to use the @jsx
pragma and import jsx
in order to use it.
// src/any-component.js
/** @jsx jsx */
import { jsx } from "theme-ui";
export default function SomeComponent() {
return (
<>
<div sx={{ backgroundColor: "primary", color: "#fff", p: 4 }}>
tomato
</div>
</>
);
}
Run npm run dev
(or yarn dev
) to check if the theme styles have been applied.
That’s it, we have added Theme UI in our NextJS site!
Top comments (2)
A nice solution, but theme-ui should be included in dependencies rather than devDependencies
Hi Eka - This was quite insightful. Would love to connect. Thanks.