Eric
Howey.

There is a hidden page you can visit at /you-are-awesome. Didn't want you to miss out on the fun!
Content has not been updated for more than 2 years, proceed with caution.

Using Theme UI with RedwoodJS

This is current as of Redwood v0.28 and Theme-UI v0.6

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

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.

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

Wrap ThemeProvider around App.js

RedwoodJS has an App.js component which manages wrapping context providers and other global APIs/state around your root app - very similar to NextJS’s _app.js component.

Here is an example of how to set that up:

import { FatalErrorBoundary } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'
import './index.css'
 
import { ThemeProvider } from 'theme-ui' // highlight-line
import theme from './theme' // highlight-line
 
const App = () => (
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodApolloProvider>
      <ThemeProvider theme={theme}>
        <Routes />
      </ThemeProvider>
    </RedwoodApolloProvider>
  </FatalErrorBoundary>
)
 
export default App

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 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 Themed 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 (
    <>
      <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>
    </>
  )
}
 
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!