Skip to main content

Katie Fujihara

Lover of making beautiful UI. Portland tech community organizer.

7 min read · February 26th 2019

Getting Started with Gatsby Themes and MDX

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.

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.

package.json
{
  "name": "gatsby-site",
  "private": true,
  "version": "1.0.0",
  "workspaces": ["site", "packages/*"]
}

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.

mkdir site
mkdir packages
cd packages
mkdir theme
cd theme
yarn init -y
touch index.js
cd ../../site/
yarn init -y

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).

packages/theme/package.json
{
  "name": "theme",
  "version": "1.0.0",
  "description": "Practicing making a Gatsby theme",
  "main": "index.js",
  "license": "MIT"
}

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.

packages/theme/package.json
 "devDependencies": {
    "gatsby": "^2.0.118",
    "react": "^16.8.1",
    "react-dom": "^16.8.1"
  },
  "peerDependencies": {
    "gatsby": "^2.0.118",
    "react": "^16.8.1",
    "react-dom": "^16.8.1"
  },

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-mdx and MDX as dependencies.

yarn workspace theme add gatsby-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-mdx’ and ‘gatsby-plugin-page-creator.’

packages/theme/gatsby-config.js
const path = require(`path`)

module.exports = {
  plugins: [
    {
      resolve: `gatsby-mdx`,
      options: {},
    },
    {
      resolve: `gatsby-plugin-page-creator`,
      options: {
        path: path.join(__dirname, `src/pages`),
      },
    },
  ],
}

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

site/gatsby-config.js
module.exports = {
  __experimentalThemes: [`theme`],
}

Setting up Site package.json

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

site/package.json
{
  "name": "site",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "develop": "gatsby develop",    "build": "gatsby build"  },
  "dependencies": {
    "gatsby": "^2.3.34",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "theme": "*"  }
}

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

yarn
yarn workspaces info

Your workspace info should look similar to this:

{
  "site": {
    "location": "site",
    "workspaceDependencies": ["theme"],
    "mismatchedWorkspaceDependencies": []
  },
  "theme": {
    "location": "packages/theme",
    "workspaceDependencies": [],
    "mismatchedWorkspaceDependencies": []
  }
}

Run the Site

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

yarn workspace site develop

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:

yarn workspace site develop

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.

packages/theme/src/components/layout.js
export default ({ children }) => (
  <div
    style={{
      // Layout styling
      margin: `10%`,
      backgroundColor: `#fafafa`,
    }}
  >
    {children}
  </div>
)

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.

packages/theme/gatsby-config.js
const path = require(`path`)

module.exports = {
  plugins: [
    {
      resolve: `gatsby-mdx`,
      options: {
        defaultLayouts: {          default: require.resolve(`./src/components/layout.js`),        },      },
    },
    {
      resolve: `gatsby-plugin-page-creator`,
      options: {
        path: path.join(__dirname, `src/pages`),
      },
    },
  ],
}

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.

header.js
export default ({ children }) => (
  <section
    style={{
      // Header Specific Styling //
      padding: "10px",
      backgroundColor: "blue",
    }}
  >
    {children}
  </section>
)

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

packages/theme/index.js
export { default as Header } from "./src/components/header"

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.

<Header>Header content goes here</Header>

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:

{
  "scripts": {
    "clean": "gatsby clean"
  }
}

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 @KatieofCode! I would love to see what kind of themes you build.

Tagged with themes, tutorialsView All Tags

Enjoyed this post? Receive the next one in your inbox!

Previous

Introducing useStaticQuery
Docs
Tutorial
Plugins
Blog
Showcase