loading...
Cover image for Next.js, Expo, and React Native for Web! 🀩

Next.js, Expo, and React Native for Web! 🀩

evanbacon profile image Evan Bacon ・Updated on ・4 min read

TL;DR: 🎳 Example πŸ“š Docs

Using Next.js with Expo will enable you to server side render your universal Expo app when it's running in the browser.
This guide will show you the recommended way for using modules from the Expo SDK with the Next.js tool-chain! (The banner is just for funsies, this is not a retro-runner tutorial)

🚨 SSR is an experimental feature with Expo so modules might not be fully optimized for Next.js. If you find bugs please report them on the Expo repo or expo-cli repo with the [nextjs] tag in the title.

πŸ€” Why use Next.js with Expo?

Here are the main benefits of using Zeit's Next.js with Expo for web:

  • Mobile App: If you're already using Next.js, now you can add a native iOS and Android app that'll share most of your code from your website!
  • Ultimate PWA: 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!
  • You can very simply layout your routes and navigation by using the file system.
  • Next.js is considered by many, to be the best way to build a website.

πŸƒπŸΌβ€β™€οΈ Up and Running

For the most updated guide you should refer to the Expo docs: Using Next.js. Here are the latest docs on master.

In this approach you will be using SSR for web in your universal project. This is the recommended path because it gives you full access to the features of Expo and Next.js.

  • Bootstrap your project with Expo
    • Install the CLI: npm i -g expo-cli
    • Create a project: expo init --template blank
    • cd into the project
  • Install the adapter:
    • yarn: yarn add @expo/next-adapter
    • npm: npm i --save @expo/next-adapter
  • Add Next.js support: yarn next-expo
    • Always commit your changes first!
    • You can optionally choose which customizations you want to do with --customize or -c
    • Force reload changes with --force or -f
  • Start the project with yarn next dev
    • Go to http://localhost:3000/ to see your project!

Alt Text

Opening in the browser will render the default template:

Alt Text

You can now start editing it and using the Expo SDK. Here is the example code I used to generate the header image: Retro Expo Text (copy/pasta into your project since snack uses a different Webpack config 😁)

Alt Text

Starting with Next.js

This approach is useful if you only want to use Expo components in your web-only project. If you chose to start with this flow I'd love to hear about why in the comments below :)

  • Bootstrap your project with Next.js
    • Create a project: npx create-next-app
  • Install the adapter:
    • yarn: yarn add @expo/next-adapter
    • npm: npm i --save @expo/next-adapter
  • Add Next.js support: yarn next-expo
    • Always commit your changes first!
    • You can optionally choose which customizations you want to do with --customize or -c
    • Force reload changes with --force or -f
  • Start the project with yarn next dev
    • Go to http://localhost:3000/ to see your project!

🏁 New Commands

  • Starting web

    • 🚫 expo start:web
    • βœ… yarn next dev
  • Building web

    • 🚫 expo build:web
    • βœ… yarn next build

πŸ“ File Structure

Here is the recommended file structure for an Expo project with Next.js support.

Expo Next.js
β”œβ”€β”€ pages ➑️ Routes
β”‚    └── index.tsx ➑️ Entry Point for Next.js
β”‚    └── _document.js ➑️ The wrapper element for a page, used for normalizing styles like React Native.
β”œβ”€β”€ .next ➑️ Generated Next.js files (should be ignored)
β”œβ”€β”€ assets ➑️ All static assets for your project
β”œβ”€β”€ App.tsx ➑️ Entry Point for Mobile apps
β”œβ”€β”€ app.json ➑️ Expo config file
β”œβ”€β”€ next.config.js ➑️ Next.js config file
└── babel.config.js ➑️ Babel config (should be using `@expo/next-adapter/babel`)

Let me know in the comments if you think there's a more optimal structure for Next.js + Expo files.

πŸ‘‹ 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 :]

You should also check out some of the other adapters like Electron and Gatsby.

πŸ“š More Info

Discussion

pic
Editor guide
Collapse
5ervant profile image
Mark Anthony B. Dungo

yarn next dev is not working for a web-only project.

I'm getting the following:

The static directory has been deprecated in favor of the public directory. err.sh/zeit/next.js/static-dir-dep...
Error: The project entry file could not be resolved. Please either define it in the package.json (main), app.json (expo.entryPoint), create an index.js, or install the expo package.
...

Collapse
dabit3 profile image
Nader Dabit

😍😍😍😍😍😍😍

Collapse
evanbacon profile image
Evan Bacon Author

πŸ₯³πŸŽ‰πŸ₯³πŸŽ‰πŸ₯³πŸŽ‰πŸ₯³πŸŽ‰

Collapse
mdhesari profile image
Mohammad Fazel

That seems exciting, thank you for introducing.

Collapse
evanbacon profile image
Evan Bacon Author

Thanks so much! 😁 I'm pretty hyped with how easy it is!

Collapse
nkzn profile image
Yukiya Nakagawa

The normal expo-for-web dev server ( expo start:web ) uses metro bundler & webpack-dev-server collaboration. On the other hand, does next-expo's dev server (next dev) use the dev server managed only by next.js? (expo-cli's build system is not used?)

Collapse
drk profile image
Derek Reynolds

Awesome article! Done React Native without expo and Next.js projects and am now excited to bridge that gap.

How did you go about generating the file structure code block for this article?

Collapse
hems profile image
hems.io

you can try using this command called "tree" sourabhbajaj.com/mac-setup/iTerm/t...

Collapse
evanbacon profile image
Evan Bacon Author

Hah I did it manually πŸ˜…

Collapse
ankeetmaini profile image
Ankeet Maini

This looks awesome! Does nextjs work work react-navigation? How will the routing work in native and web?

Collapse
5ervant profile image
Mark Anthony B. Dungo

Currently, I'm writing a separate navigation bar for the web. It only supports the Next.js default page-based routing for the web. docs.expo.io/versions/latest/guide...

Collapse
5ervant profile image
Mark Anthony B. Dungo

Any example how will react-navigation work with next-expo web project?

Collapse
johhansantana profile image
Johhan Santana

Does this work even without react-native-web?

Collapse
evanbacon profile image
Evan Bacon Author

This is a web only feature as Next.js doesn’t support native platforms

Collapse
maraescalante profile image
mara-escalante

Hi Evan, I was wondering if this would work with a custom next App using _app.js?

Collapse
hems profile image
hems.io

I'm really excited about this approach, already got some butterflies in my stomach in anticipation of the surprises it might hold down the road