Getting Started with Gatsby Themes and MDX

Katie Fujihara
Katie Fujihara
February 26th, 2019

Updated July 9, 2019 to reflect using the gatsby-plugin-mdx package instead of the (now deprecated) gatsby-mdx package.

What is a Gatsby theme?

Gatsby themes allow you to focus only on the parts of the site and app building process that you need to care about by abstracting the rest away into a package.

Jason Lengstorf

Getting Started

Create a new directory

mkdir gatsby-themes

Navigate to the directory

cd gatsby-themes

Create a package.json file

yarn init -y

Tidy up your package.json file and create workspaces which includes the project name, site, and your packages. Both of these directories will include their own package.json files.

Next, you want to create your site directory and your packages directory within your gatsby-theme project directory. Make sure the names that you choose for your directories are the same as what you put in your workspaces. You will also want to go into your packages directory and make another directory with the name of your theme. For the purpose of this tutorial, we will call it theme. Then you will want to yarn init the theme directory and the site directory.

The -y in yarn init automatically adds defaults to your package.json. If you opt to run yarn init without -y you will be asked a few questions. The main thing you will want to pay attention to is the entry point (index.js). For the theme directory, you can leave the entry point as index.js (just make sure you have an index.js file).

You will want to add Gatsby, React, and ReactDOM to as dev dependencies for site.

yarn workspace site add gatsby react react-dom

Then you will navigate out of the site directory and add Gatsby, React, and ReactDOM as dev dependencies for theme.

yarn workspace theme add gatsby react react-dom -D

You will want to make Gatsby, React, and ReactDom peer dependencies in the theme directory.

Installing MDX and gatsby-plugin-page-creator

What is MDX?

MDX is markdown for the component era. It lets you write JSX embedded inside markdown. That's a great combination because it allows you to use markdown's often terse syntax (such as # heading) for the little things and JSX for more advanced components.

Read more about Gatsby+MDX here.

In your theme directory, add src/pages/index.mdx

Then you need to add gatsby-plugin-mdx and MDX as dependencies.

yarn workspace theme add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react

Next, you will want to add gatsby-plugin-page-creator

yarn workspace theme add gatsby-plugin-page-creator

Gatsby plugin that automatically creates pages from React components in specified directories. Gatsby includes this plugin automatically in all sites for creating pages from components in src/pages. With this plugin, any file that lives in the src/pages folder (or subfolders) will be expected to export a React Component to generate a Page.

In the future, Gatsby will automatically handle adding the page-creator plugin.

Read more about the page-creator plugin here.

Next, you will want to create your gatsby-config.js file under your theme directory. Make sure to include 'gatsby-plugin-mdx' and 'gatsby-plugin-page-creator.'

Lastly, you're going to want to add a gatsby-config.js file to your site directory.

Setting up Site package.json

You will need to add gatsby CLI scripts and specify your newly created theme as a dependency.

Now, you can make sure site is linked to theme.

Your workspace info should look similar to this:

Run the Site

Now that we've set up the site's package.json we can run the workspace:

Customizing the Index Page

You can override the index page from your theme by creating one in site. To do so, change directory into the site directory, and create an index.mdx file in the pages folder.

site/src/pages/index.mdx

Your website content goes in index.mdx.

Now, rerun the development server and see your new content:

Styling Layout and Components

Next, you will navigate to the theme directory. You will then create a components folder under src, and in components you create a layout.js file.

packages/theme/src/components/layout.js

Inside of your layout.js file, you can add your styling.

To make sure your layout.js file is connected to your theme you will navigate to your gatsby-config.js file in your theme directory. You will add defaultLayouts under options and make sure that the layout.js is required.

If you want to reuse a specific style, you can create styled components. In your components directory, you will create a new file (for example: header.js).

Here is an example of how you can set-up your styled component in header.js. Please make sure you write css-in-javascript when styling your div.

To import your styled components, go to index.js and export your component.

If you want to use this component in your site, you will then go to your page (index.mdx) and import the specific components.

import { Header } from 'theme'; You can then use it to style specific things in your file.

Using Your Theme

It's finally time to use and share your theme! You can push your whole directory (gatsby-themes) to GitHub.

If you ever want to use your theme, you will do:

gatsby new name-of-project theme-url

Once you have cloned this theme into your new project, you can make edits to the files in your pages folder.

If you want to check your progress, go to the site directory and

gatsby develop

Once your server is up you should see your beautiful theme applied to your files!

Troubleshooting Plugin Errors

If you run into an error that your theme plugin can't be found, try clearing your cache. You can either use rm -rf .cache in your terminal, or you can add:

to your package.json file. Then you can use npm run clean in your terminal.

If you happen to find this tutorial helpful, please feel free to let me know on Twitter @KatieFujihara! I would love to see what kind of themes you build.

Katie Fujihara
Written by
Katie Fujihara

Lover of making beautiful UI. Portland tech community organizer.

Follow Katie Fujihara on Twitter

Talk to our team of Gatsby Experts to supercharge your website performance.