Chakra UI and Gatsby - Getting Started
Ok, so this is another one of those “let’s use a new CSS-in-JS library on a Gatsby default starter project” post.
In this case it’s Chakra UI, it’s recently gone v1 and I’m keen to use it.
What I’m going to be doing is styling the Gatsby starter default using Chakra UI and chucking in a theme toggle as well.
This will involve swapping out the styles that come with the Gatsby starter default with Chakra UI ones.
The end result I’m aiming for is for it to look the same as before but using Chakra UI in place of the styling it comes with.
You can follow along too, or you can TL;DR for the video.
Pre requisites
The usual notes on development environment, this comes with the presumption you’ll already have a development environment set up and configured. If you don’t have a development environment then you can always use CodeSandbox.io to get up and running with an environment.
In the examples here I’m using Node version 14.13.0
.
Here’s some of the dependencies being used in this guide, they’re all latest versions at the time of writing this.
1"@chakra-ui/gatsby-plugin": "^1.0.0",2"@chakra-ui/icons": "^1.0.1",3"@chakra-ui/react": "^1.0.1",4"@emotion/react": "^11.1.1",5"@emotion/styled": "^11.0.0",6"framer-motion": "^2.9.4",7"gatsby": "^2.26.1",8"react": "^17.0.1",9"react-dom": "^17.0.1",
Create the thing
Spin up a new Gatsby project with npx
:
1npx gatsby new gatsby-chakra-ui
You can install and use the Gatsby CLI if you like, in this instance
I’m going npx
as I’m not going to need any of the Gatsby CLI
functionality.
Wait for that to finish doing it’s thing then change directory to the
freshly created gatsby project. Cool, cool, do a quick yarn develop
to make sure everything’s installed ok with no issues.
Install the things
Now to install the dependencies needed, there’s a few, the \
here is
so that I can display the items that need installing in a nice format:
1yarn add \2 @chakra-ui/react \3 @emotion/react \4 @emotion/styled \5 framer-motion \6 @chakra-ui/gatsby-plugin \7 @chakra-ui/icons
NOTE Don’t forget to add the Chakra UI Gatsby plugin to the Gatsby plugin array, I routinely do this! This note is for me just as much as you dear reader. 😊
I’ll add the plugin to the gatsby-config.js
, at the time of writing
this plugin name was what’s recommended in the Chakra UI
documentation and shouldn’t be confused with the Gatsby
documentation.
1plugins: [2 `@chakra-ui/gatsby-plugin`,3 // many more plugins 👇
Stop (Ctrl+c
) and restart the dev server you’ll notice all the
styles are gone, that’s the Chakra UI Gatsby plugin doing it’s thing.
Now that I have all the power of Chakra UI available to me now I’ll
remove the import "./layout.css"
from the layout.js
component. I
can also delete the layout.css
file as it’s not needed.
Root Wrapper time!
So that I can access the Chakra UI Theme provider throughout the
project I’m going to add the <ChakraProvider>
as high up in the
React component tree as possible.
I can do this by using the Gatsby wrapPageElement
API in both the
gatsby-browser.ja
and the gatsby-ssr.js
files.
So I’m not to repeating the same code in both of those files I’m going
to create another file, add that in there and import that file into
both the gatsby-browser.ja
and the gatsby-ssr.js
files.
The name and location of this file is unimportant, keep it at the root
of the project with the gatsby-browser.ja
and the gatsby-ssr.js
files or add it to the src
folder, doesn’t matter AFAIK.
Create the file, from my terminal I’ll do a touch:
1touch src/woot-wapper.tsx
Yes, I’m using a TypeScript (.tsx
) file in a predominantly
JavaScript project, you do you, make it a .js
file if you like. I’m
trying to get more used to using TS in my projects and Gatsby gives TS
support out of the box now.
In the root wrapper file I’ll add the Chakra provider and the Layout
component.
1import { ChakraProvider } from '@chakra-ui/react'2import React from 'react'3import Layout from './components/layout'4
5export const wrapPageElement = ({ element }) => {6 return (7 <ChakraProvider resetCSS>8 <Layout>{element}</Layout>9 </ChakraProvider>10 )11}
So now there’s no need to import the layout component into each page
that is created. I’ll need to remove the layout from component from
the 404.js
, index.js
,page-2.js
and using-typescript.tsx
pages.
Finally I’ll need to import the root wrapper into both the
gatsby-ssr.js
and the gatsby-browser.js
files.
1import { wrapPageElement as wrap } from './src/woot-wapper'2
3export const wrapPageElement = wrap
Theme Toggle
Using the Chakra UI theme provider means that I can use one of the provided hooks to toggle the theme.
I’m going to create a theme toggle component:
1touch src/components/toggle-theme.tsx
And add in some code to toggle the theme:
1import { MoonIcon, SunIcon } from '@chakra-ui/icons'2import {3 IconButton,4 useColorMode,5 useColorModeValue,6} from '@chakra-ui/react'7import React from 'react'8
9export default function ThemeToggle() {10 const { toggleColorMode: toggleMode } = useColorMode()11 const ToggleIcon = useColorModeValue(SunIcon, MoonIcon)12
13 return (14 <IconButton15 icon={<ToggleIcon />}16 variant="ghost"17 aria-label="Toggle Theme"18 onClick={toggleMode}19 />20 )21}
I’ll add this to the header component for now.
Style it with Chakra UI
Ok, now I’ve done the groundwork I can start removing the inline styles in this project, I’ll start with the header component.
I’ll straight up copy pasta the changed code in here, som of these may be a bit long, I’ll shorten them where I can so there’s no code walls.
Style the header
Here’s the component with the inline styles swapped out for Chakra UI styles.
I’ve left out the default export and prop types for brevity.
1import { Box, Heading, Link } from '@chakra-ui/react'2import { Link as GatsbyLink } from 'gatsby'3import React from 'react'4import ThemeToggle from './theme-toggle'5
6const Header = ({ siteTitle }) => (7 <Box as="header" background="rebeccapurple" marginBottom="1.45rem">8 <Box as="div" m="0 auto" maxW="960px" p="1.45rem 1.0875rem">9 <Heading margin="0">10 <Link11 as={GatsbyLink}12 to="/"13 color="white"14 _hover={{ textDecor: 'none' }}15 >16 {siteTitle}17 </Link>18 </Heading>19 </Box>20 <Box as="div" position="fixed" right="20px" top="20px">21 <ThemeToggle />22 </Box>23 </Box>24)
Notice that the <header>
tag and the <div>
tags are now both
Chakra UI <Box>
components?
They’re both using the Chakra UI as
prop, this is a feature that
allows you to pass an HTML tag or component to be rendered. Pretty
neat right?
You’ll also notice that the Chakra UI Link
component is being
rendered as
a Gatsby Link
component, I also removed the underline
on hover with the _hover
prop.
So with that being done it takes the 42 lines that was there previously down to 35 lines of code.
I’ve also added the theme toggle button, not the best way to position it mind you, just for funsies!
Style the layout
Onto the layout component now, same thing here with the <div>
,
<main>
and <footer>
tags here.
I’m going to forgo showing the imports export and prop types here again and I’ll add in what’s changes in the render of the component.
1return (2 <>3 <Header siteTitle={data.site.siteMetadata?.title || `Title`} />4 <Box as="div" m="0 auto" maxWidth="960px" p="0 1.0875rem 1.45rem">5 <Box as="main">{children}</Box>6 <Box as="footer" marginTop="2rem" fontSize="xl">7 © {new Date().getFullYear()}, Built with8 {` `}9 <Link10 isExternal11 textDecor="underline"12 color="purple.500"13 href="https://www.gatsbyjs.com"14 >15 Gatsby16 </Link>17 </Box>18 </Box>19 </>20)
You may notice the addition of the fontSize
prop added to the
footer, I’ll be using this a bit more when editing the pages.
There’s also additional props for the link component, I added the
isExternal
prop to indicate that the link is pointing to an external
link, textDecor
to add the link underline and color
to it.
Ok, that’s it for the components, onto the pages now.
Style the 404 page
On the 404 page, I’ve added in a Chakra UI <Heading>
and Text
components and added the fontSize
prop along with with some margin
top and bottom on the text component with the my
prop.
1import { Heading, Text } from '@chakra-ui/react'2import React from 'react'3import SEO from '../components/seo'4
5const NotFoundPage = () => (6 <>7 <SEO title="404: Not found" />8 <Heading>404: Not Found</Heading>9 <Text fontSize="xl" my={5}>10 You just hit a route that doesn't exist... the sadness.11 </Text>12 </>13)14
15export default NotFoundPage
Style the Index page
The index page you’ll notice is a bit larger due to the additional props needed for the link components.
1const IndexPage = () => (2 <>3 <SEO title="Home" />4 <Heading>Hi people</Heading>5 <Text fontSize="xl" my={5}>6 Welcome to your new Gatsby site.7 </Text>8 <Text fontSize="xl" my={5}>9 Now go build something great.10 </Text>11 <Box as="div" maxWidth="300px" marginBottom="1.45rem">12 <Image />13 </Box>14 <Link15 as={GatsbyLink}16 textDecor="underline"17 color="purple.500"18 fontSize="xl"19 to="/page-2/"20 >21 Go to page 222 </Link>23 <br />24 <Link25 as={GatsbyLink}26 textDecor="underline"27 color="purple.500"28 fontSize="xl"29 to="/using-typescript/"30 >31 Go to "Using TypeScript"32 </Link>33 </>34)
Additional props for the link components includes the text, underline and colour props I’ve already used.
Style the Page 2 page
Same as with the index page for styling the Gatsby links with Chakra UI here.
1const SecondPage = () => (2 <>3 <SEO title="Page two" />4 <Heading>Hi from the second page</Heading>5 <Text fontSize="xl" my={5}>6 Welcome to page 27 </Text>8 <Link9 as={GatsbyLink}10 to="/"11 color="purple.500"12 fontSize="xl"13 textDecor="underline"14 >15 Go back to the homepage16 </Link>17 </>18)
Style the Using TypeScript page
Same again with the TypeScript file here, I’ve added in the as
prop
to refer to the link as a Gatsby link along with the textDecor
,
color
and fontSize
props.
I’ve removed the text from this example to reduce the overall size of the code block.
1const UsingTypescript: React.FC<PageProps<DataProps>> = ({2 data,3 path,4}) => (5 <>6 <SEO title="Using TypeScript" />7 <Heading>Gatsby supports TypeScript by default!</Heading>8 <Text fontSize="xl" my={6}>9 This means that you can create and write <em>.ts/.tsx</em> files10 ...11 </Text>12 <Link13 isExternal14 textDecor="underline"15 color="purple.500"16 href="https://www.gatsbyjs.com/docs/typescript/"17 >18 documentation about TypeScript19 </Link>20 <Link21 as={GatsbyLink}22 textDecor="underline"23 color="purple.500"24 fontSize="xl"25 to="/"26 >27 Go back to the homepage28 </Link>29 </>30)
Here’s a video detailing the process
Recap and wrap up!
That’s it for this one! To recap what I did:
- Create a Gatsby starter using npx
- Add Chakra UI packages
- Created a theme toggle using the Chakra UI
useColorMode
hook - Swap out inline styles with Chakra UI components
If you want to use the code here I made a starter you can use with the Gatsby CLI or straight up clone and install the dependencies.
Done!
I’m only beginning to get familiar with Chakra UI so I’ll be writing more about it as I continue to use it.
Thanks for reading 🙏
Please take a look at my other content if you enjoyed this.
Follow me on Twitter or Ask Me Anything on GitHub.
Resources
These are literally all linking to the Chakra UI documentation:
Back to Top