What is Shadowing in Gatsby Themes?
Tags: gatsby, react, javascript
Published: 2019-07-24 02:28:11

This is the continuation of a series on Gatsby themes. In previous posts we covered how to start a Gatsby site from scratch, how to add a theme, and how to use theme options to customize our website.

We'll be picking up with Shadowing in Gatsby which is a powerful concept that allows you to use themes and customize only the parts that you want in a reliable, ergonomic way.

---

## What is Shadowing?

Shadowing is Gatsby's answer to customizing parts of a theme, without throwing the baby out of the bathwater. It would suck if you needed to re-wire `gatsby-theme-blog` from scratch if you wanted to change some of the styles, components, or content. 

It would also suck to have a giant object with theme options for everything you want a user to be able to override. It would also suck if some theme creator made some component, or style NOT overridable.

By making shadowing an inherent part of how Gatsby works, there is a consistent and simple way to override pretty much anything. 

## What can you Shadow?

With Gatsby themes you can shadow styles, components, and data requirements (GraphQL queries). Anything that lives in the `src` directory of a theme is fair game!

## How do you Shadow?

Let's quickly change something small like the main color of our blog. I love purple, but you know what's an even better color? Tomato. 

To shadow something from a theme we follow a simple convention. Inside of our `src` folder, we make a folder with the theme name, `gatsby-theme-blog`, and then we mimic the path to the file in the theme itself but we ignore the `src` inside of the theme. 

So `gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js` becomes `src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js`. 

Since we happen to want to change a color, and I happen to know that `gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js` is the exact file that we need to shadow, we need to create some folders, and a new file in our Gatsby website so we can shadow it.

```sh
mkdir -p src/gatsby-theme-blog/gatsby-plugin-theme-ui
touch src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js
```

Now pop open your favorite code editor and we are going to open up two files. File 1) `node_modules/gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js` and file 2) `src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js`.

When I'm shadowing, I find it easiest to look at the thing I'm going to shadow, while working on the new file. 

Your `node_modules/gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js` file should look something like this:

```javascript
const purple60 = `#663399`
const purple30 = `#D9BAE8`
const grey90 = `#232129`
const black80 = `#1B1F23`
const white = `#fff`
const lightWhite = `rgba(255, 255, 255, 0.86)`
const opaqueLightYellow = `rgba(255, 229, 100, 0.2)`
const opaqueLightWhite = `hsla(0, 0%, 100%, 0.2)`
const lightGray = `hsla(0, 0%, 0%, 0.2)`

export default {
  text: grey90,
  background: white,
  primary: purple60,
  secondary: black80,
  muted: lightGray,
  highlight: opaqueLightYellow,
  heading: grey90,
  prism: {
    background: `#011627`,
    comment: `#809393`,
    string: `#addb67`,
    var: `#d6deeb`,
    number: `#f78c6c`,
    constant: `#82aaff`,
    punctuation: `#c792ea`,
    className: `#ffc98b`,
    tag: `#ffa7c4`,
    boolean: `#ff5874`,
    property: `#80cbc4`,
    namespace: `#b2ccd6`,
    highlight: `hsla(207, 95%, 15%, 1)`,
  },
  modes: {
    dark: {
      text: lightWhite,
      background: grey90,
      primary: purple30,
      secondary: lightWhite,
      muted: opaqueLightWhite,
      highlight: purple60,
      heading: white,
    },
  },
}
```

The color that we want to change is the `primary` key in the object.

```javascript
export default {
  text: gray90,
  background: white,
  primary: purple60,
  //...
}
```

So what can we learn from this file? The first thing to take away is that we should have a default export in our shadowed `colors.js` file. The second is that, unless we want to change a bunch of these values, we will need some way to merge the `gatsby-theme-blog` colors, with our colors and just override the ones that we want to.

Before we get to figuring out how to merge our colors object, let's make an export default and set the primary key to 'tomato'.

```javascript
export default {
  primary: 'tomato',
}
```

Now the cool part...

```javascript
import colors from 'gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors'

export default {
  ...colors,
  primary: 'tomato',
  modes: {
    dark: {
      ...colors.modes.dark,
      primary: '#ff755e'
    }
  }
}

```

We can import the thing we are shadowing and use whatever JavaScript method we want to merge, and override whatever we want. It's that easy. At least updating styles is that easy.

## Why does Shadowing work this way?

When you are using a theme Gatsby first tries to resolve within your own projects `src` folder, looking in `src/{theme-name}/{any-sub-dirs}/{file}`, if it doesn't see anything there, it resolves to `node_modules/{theme-name}/src/{any-sub-dirs}/{file}`. 

When building a theme you don't have to do anything special to allow shadowing. It just works. When you're consuming a theme you can follow these conventions to shadow whatever you need to.

## BONUS

Want an even easier way to do partial/deep updates of an object in JavaScript? There's a really cool library called [immer](https://github.com/immerjs/immer) that is particularly good at this.

Just install immer to the project, import it into our file and let the magic happen.

```javascript
import produce from 'immer'
import colors from 'gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors'

export default produce(colors, draft => {
  draft.primary = 'tomato'
  draft.modes.dark.primary = '#ff755e'
})

```

--- 

## Conclusion

Shadowing is a concept in Gatsby that allows us to override and compose styles, components, and data from a Gatsby theme. It follows a simple convention of path resolution to allow shadowing. Anything in a theme's `src/` folder is open to shadowing.

### Next Up

Next time we will dive into shadowing `gatsby-theme-blog` and making it our own by shadowing styles and components.