Moti + Next.js
There are 3 quick steps to getting Moti setup in a Next.js app.
#
Step 1Add moti
to transpile modules.
Your next.config.js
file should look something like this:
#
Step 2Add the raf
polyfill.
yarn add raf
Then add this in pages/_app.js
We're going to use requestAnimationFrame
with Reanimated web, so that polyfill makes it usable with server-side rendering frameworks.
#
Step 3tip
If you're using Reanimated 2.0.0-rc.3
or higher, you can skip this step, you're done.
Alright, here goes a little hack to get Reanimated 2 working in Next.js. It's a simple copy-paste, so don't worry.
- Install
patch-package
and follow its instructions - Create a folder called
patches
in your app root
Add this file: patches/react-native-reanimated+2.0.0-rc.0.patch
^ replace 2.0.0-rc.0
with whatever version of Reanimated you're using.
Paste this in the file you created:
Then run yarn install
. That should be enough 😅
#
Some background on this hackWe need to change Reanimated's use of setImmediate
on web to requestAnimationFrame
. Long-story short, Reanimated uses a function called setImmediate
, and Next.js doesn't support this. There are some hacks, and if you google "Expo + Next.js setimmediate", you'll find many posts of me complaining about it.
I've found the best solution is to replace setImmediate
with requestAnimationFrame
altogether, and that's what the patch above does.
#
This is temporaryThe patch will fix the problems for apps using Reanimated version 2.0.0-rc.0
(the version supported by Expo SDK 40). For later versions of Reanimated, this should already be fixed. You can track the issue here: https://github.com/software-mansion/react-native-reanimated/pull/1521
If you don't want to use patch-package, you can read the alternative solution below. It's buggier in my experience, though, since I haven't had good experiences with setImmediate
polyfills with Next.js.
#
UmmmIf this step made no sense to you, don't worry. Maybe you haven't even heard of patch-package
before and you're like, what am I doing? I thought this was just an animation library? Trust me, I know; it's confusing and not necessary to understand to use Moti. Just copy and paste the steps and move on with your day.
As I mentioned, you'll be able to get rid of this hack once you upgrade Reanimated to 2.0.0-rc.3
or higher (or upgrade to Expo SDK 41 when it's out.)
#
Alternative solution (without patch package)If you don't want to use patch-package
, as I recommend, your alternative is to try to polyfill setImmediate
. This is a hack for versions of Reanimated 2 that still use setImmediate
.
yarn add setimmediate
Your pages/_app.js
should have these imports at the very top:
This is a constant source of bugs with Reanimated and Next.js. You may need to import these polyfills at the top of other files that use reanimated/moti if it persists. Please run yarn next build
and run locally before deploying to make sure it works on your app.
I typically deploy to Vercel on a branch to make sure it works. It's random, but sometimes your page will error and get "unexpected error occurred", and the console logs will have an error that reads setImmediate is not defined
. If you see this, you aren't alone.
You might also want to install the setimmediate
package, and put it at the top with the other polyfills.
A newer version of Reanimated (not yet supported by Expo) changes setImmediate
to requestAnimationFrame
. This should fix the problem. Once you upgrade to that version, you should only need to add the the raf/polyfill
in pages/_app.js
, and ideally the bugs will disappear.
For the record, you might need to add those imports into any file that uses Moti. It's really unpredictable, which is why I recommend the patch-package fix instead.