🚀 Gatsby + React Native for Web + Expo 🥳
Tags: tutorial, react, gatsby, javascript
Published: 2019-11-27 21:37:18

**TL;DR:** 🎳 [Example](https://github.com/expo/examples/tree/master/with-gatsby) 📚 [Docs](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-gatsby.md)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/17si2f3o32qo6qd8yui1.png)

In this post I'll show you how to setup your (universal) Expo app to use [Gatsby](https://www.gatsbyjs.org/) when targeting web! 

> 🚨 If you find bugs please report them on the [expo-cli repo](https://github.com/expo/expo-cli/issues) with the `[gatsby]` tag in the title.

### Why use Gatsby with Expo?

Here are the main benefits of doing this:

- You can [prerender](https://www.netlify.com/blog/2016/11/22/prerendering-explained/) the web part of your [Expo](http://expo.io/) app.
- If you use Gatsby already, then now you can **share most of your code between web and mobile**.
- If you're new to Expo then this also means that you can use complex browser features from the Expo SDK like Camera, Gestures, Permissions, etc. whenever possible in the browser!

## ⚽️ Tutorial

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jv5tnc0p3nidvgoxb8pa.png)

- Install or update the Expo CLI: `npm i -g expo-cli`
- Create a new Expo project: `expo init`
- Install the Gatsby plugin: 
  ```
  # yarn
  yarn add gatsby gatsby-plugin-react-native-web

  # npm
  npm install --save gatsby gatsby-plugin-react-native-web
  ```

- Create a `gatsby-config.js` and use the plugin:
   [`gatsby-config.js`](https://github.com/expo/examples/blob/master/with-gatsby/gatsby-config.js)

   ```js
   module.exports = {
     plugins: [
       `gatsby-plugin-react-native-web`,
       /* ... */
     ],
   }
   ```
- Add `/.cache` and `/public` to your [`.gitignore`](https://github.com/expo/examples/blob/3b7e4e33be382c87534b9fa49981fb9c4d793b23/with-gatsby/.gitignore#L16-L18)
- Now create the first page of your Gatsby project: 
  - Create the pages folder: `mkdir -p src/pages` 
  - Create the file: 
  ```
  # JS
  cp App.js src/pages/index.js

  # TS
  cp App.tsx src/pages/index.tsx
  ```
- Run `yarn gatsby develop` to try it out!
  - Open the project in the browser `http://localhost:8000/`

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/j0c01d6ra9ylwomy2d1o.png)

### Trouble Shooting

If you started your project without the Expo CLI you may also need to do these things:

- If you started your project with Gatsby CLI then check out the guide I wrote in the docs: [Gatsby Project with Expo](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-gatsby.md#gatsby-projects-with-expo).

- Install React Native for Web: `yarn add react-native-web`
- Install the babel preset for React Native web: 
  ```
  # yarn
  yarn add --dev babel-preset-expo
  # npm
  npm install --save-dev babel-preset-expo
  ```
  - 💡 Even though the name has Expo in it, you can (and should) use it for any React Native project as it provides universal platform support.
- Create a `babel.config.js` and use the Babel preset:
   [`babel.config.js`](https://github.com/expo/examples/blob/master/with-gatsby/babel.config.js)

   ```js
   module.exports = { presets: ['babel-preset-expo'] }
   ```

## 🏁 New Commands

- **Starting web**
  - 🚫 `expo start:web`
  - ✅ `yarn gatsby develop`

- **Building web**
  - 🚫 `expo build:web`
  - ✅ `yarn gatsby build`

- **Serving your static project**
  - 🚫 `serve web-build`
  - ✅ `yarn gatsby serve`

### 📁 File Structure

Here is the recommended file structure for a Expo project with Gatsby support.

```
Expo Gatsby
├── src
│   └── pages ➡️ Routes
│       └── index.tsx ➡️ Entry Point for Gatsby
├── .cache ➡️ Generated Gatsby files (should be ignored)
├── public ➡️ Generated Gatsby files (should be ignored)
├── assets ➡️ All static assets for your project
├── App.tsx ➡️ Entry Point for Mobile apps
├── app.json ➡️ Expo config file
├── gatsby-config.js ➡️ Gatsby config file
└── babel.config.js ➡️ Babel config (should be using `babel-preset-expo`)
```

## 👋 Thanks for Reading

I hope you found this article helpful! If you do use this workflow I'd love to hear about how it worked for you 😁 If you didn't, I'd also love to hear! So go tweet some emojis at me :]

## 📚 More Info

- [Expo support PR](https://github.com/slorber/gatsby-plugin-react-native-web/pull/14)
- [Example](https://github.com/expo/examples/tree/master/with-gatsby)
- [Docs](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-gatsby.md)
- [Tips and Tricks for React Native web](https://baconbrix.gitbook.io/react-native-web/)
- [Video: PWA vs Native (ft. Kyle from Gatsby and me)](https://www.youtube.com/watch?v=qNym3q6zCXo)