Skip to content

Using Theme-UI with RedwoodJS

Eric Howey May 21, 2020

RedwoodJS is a new javascript framework bringing the frontend and the backend together in one incredible fullstack package. They have a great tutorial that gives you a good feel for what is possible with Redwood.

While I was completing the tutorial I got curious about using Theme-UI with Redwood. Theme UI is a frontend library for creating themeable user interfaces with constraint-based design principles. Under the hood it extends Emotion for css-in-js styling. It has a great developer experience and is my favorite way to write css-in-js!

Turns out it is pretty straightforward to use Theme-UI with RedwoodJS projects.

Install Theme-UI and theme presets

npm install theme-ui @theme-ui/presets

or

yarn add theme-ui @theme-ui/presets

Wrap theme provider around your layout component

RedwoodJS has a concept called ‘layouts’ which controls the visual presentation of various pages in your project. Theme-UI has a theme provider component which enables Theme-UI styling changes on all child components.

Here is an example using the blog layout from the tutorial:

/** @jsx jsx */
import { jsx, Styled } from "theme-ui"
import { Link, routes } from "@redwoodjs/router"
import { ThemeProvider } from "theme-ui"
import theme from "./theme"
const BlogLayout = ({ children }) => {
return (
<ThemeProvider theme={theme}>
<header>
<h1>
<Link to={routes.home()}>Redwood Blog</Link>
</h1>
<nav>
<ul>
<li>
<Link to={routes.about()}>About</Link>
</li>
<li>
<Link to={routes.contact()}>Contact</Link>
</li>
</ul>
</nav>
</header>
<main>{children}</main>
</ThemeProvider>
)
}
export default BlogLayout

Create a theme specification file

The theme specification is what defines your projects visual appearance. This ensures consistent spacing, font sizes, colors, line heights, etc. Imagine it like an interior designer for your home - they come in and provide a unified visual design.

In this theme file we use a theme preset based on TailwindCSS to provide a default set of styles that can be extended and customized.

import { tailwind } from "@theme-ui/presets"
export default {
...tailwind,
colors: {
background: "pink",
text: "orange",
},
}

Save and checkout the results!

Save your files and look at the browser. Checkout that awful color combination! You can quickly swap colors across the entire site. This same principal can be used to customize all visual areas of a project with Theme-UI; spacing, fonts, line heights, breakpoints, etc. Theme-UI becomes like a command center for your CSS.

Experiment with what is possible

To start enabling the full power out of Theme-UI you can experiment with the sx prop and the Styled component. It is also worth reading about how media queries and breakpoints are handled in Theme-UI - the syntax and developer experience for this is great!

Try this in your Redwood layout file:

/** @jsx jsx */
import { jsx, Styled } from "theme-ui"
import { Link, routes } from "@redwoodjs/router"
import { ThemeProvider } from "theme-ui"
import theme from "./theme"
const BlogLayout = ({ children }) => {
return (
<ThemeProvider theme={theme}>
<header>
<Styled.h1 sx={{ fontFamily: "sans-serif" }}>
<Link to={routes.home()} sx={{ textDecoration: "none" }}>
Redwood Blog
</Link>
</Styled.h1>
<nav>
<ul>
<li>
<Link to={routes.about()}>About</Link>
</li>
<li>
<Link to={routes.contact()}>Contact</Link>
</li>
</ul>
</nav>
</header>
<main>{children}</main>
</ThemeProvider>
)
}
export default BlogLayout

Add this to your theme file:

import { tailwind } from "@theme-ui/presets"
export default {
...tailwind,
colors: {
primary: "green",
background: "pink",
text: "orange",
},
styles: {
h1: {
backgroundColor: "primary",
fontStyle: "italic",
fontSize: "8rem",
},
},
}

Hopefully this has given you a taste of what is possible when combining Theme-UI and RedwoodJS!

Happy coding!


Illustrations by Diana Valeanu
Design inspired by Gatsby-Absurd
© 2020 eric howey