Deploy to Zeit Vercel with a simple command.
Current 'build' structure works for platforms like Heroku but not on Zeit Vercel, as we can't push the .next folder. Like this we miss all the cool features this hosting platform gives like static hosting to CDN!
Zeit Vercel is very strict on how to deploy a next js project since it needs to accomodate for many factors (paths/api routes/deps/env variables etcs), therefore prefers building on their hosting provider. It also ignores .next folders (there's a trick to push this by using a .vercelignore file, but doesn't help anyway)
The current implementation of next js plugin for nx dev is great, it can easily create a .next folder and copy assets to dist/myApp, it also generates a basic package.json (to which we have to manually add deps).
This structure is ready for platforms like Heroku, where we can push over the .next folder (build artifacts which include shared libs and typescript related compilation), have heroku install node_modules then run the project.
The only solution I have found is to avoid building altogether. What I do:
Please provide detailed steps for reproducing the issue.
Thank you for submitting this!
So just to summarise the problem here:
next.js directory - this is so it can do smart things around creating serverless functions for each one of your SSRd routes. Important here is that when you push your sources, it doesn't just do next build, it does its own custom build commandnext.js app where ALL of your source files are needed to build and serve the appnext.js app: you can't push your whole monorepo everytime you want to deploy just your next.js app, it's not scaleable Ideally:
next.js app locally - we have all the monorepo source code locally and we can traverse the dependency graph and grab what's necesary, be it a lib or an npm dependency. This all bundled into distdist to Vercel, it would skip the build step, and serve it directly (this is not possible at the moment, you need to let Vercel build your app with a special command, that it doesn't expose publicly - hence why it requires your source files). This is also why deploying to platforms like Heroku works great - because they allow you to next build locally, and then next start on their platform.
Getting around this problem would involve creating a "simplified monorepo", which contains just the libs and dependencies in package.json that your next.js app needs, and putting that into dist so it can be sent to Vercel. This is a complex process, a bit counter-intuitive (in the sense that we're putting source files in dist, where you'd expect a deployable artifact), and will only exist to work around a limitation of the Vercel platform.
Vercel knows about this, so I'd say to wait on them for a bit. As monorepos become more and more popular this will be a more and more requested feature.
Great stuff and well explained. Let's keep this for reference...it might help people stuck on this case.
As far as I can tell there are no plans of supporting pre-built next.js apps, this comment is 8 days old in response to another nx user trying to do this.
At the moment, we don't plan to support "pre-built" Next.js apps since we do need to control the generated output and underlying routing. So no, it is not possible, and we don't envision a future where this would be implemented.
source
Couldn't this be resolved by a vercel specific deploy script within @nrwl/next? These two are so tightly coupled due to being developed by the same company. I agree it sounds a little weird copying source files to the dist folder, but it could be done similarly to storybook, creating something like dist/vercel/appname. My reasoning is mostly that this is what I (and others that want to deploy next apps to vercel) will end up having to do this anyway, unless there's a better way to achieve this right now?
As far as I can tell there are no plans of supporting pre-built next.js apps, this comment is 8 days old in response to another nx user trying to do this.
At the moment, we don't plan to support "pre-built" Next.js apps since we do need to control the generated output and underlying routing. So no, it is not possible, and we don't envision a future where this would be implemented.
sourceCouldn't this be resolved by a vercel specific deploy script within
@nrwl/next? These two are so tightly coupled due to being developed by the same company. I agree it sounds a little weird copying source files to the dist folder, but it could be done similarly to storybook, creating something likedist/vercel/appname. My reasoning is mostly that this is what I (and others that want to deploy next apps to vercel) will end up having to do this anyway, unless there's a better way to achieve this right now?
I agree, if this becomes the only option, it will definitely be something we'll look at. Vercel are working on monorepo support though, and they'll launch something soon hopefully (based on the comment you linked to as well), so let's wait and see how that will work, as it might help with this story.
I agree, if this becomes the only option, it will definitely be something we'll look at. Vercel are working on monorepo support though, and they'll launch something soon hopefully (based on the comment you linked to as well), so let's wait and see how that will work, as it might help with this story.
That's fair enough. My understanding was that their monorepo support was mainly about being able to support multiple apps being deployed to the same app, or connecting multiple apps to the same repo. That said, they probably have some plans to have some support for configuring the repo.
I guess we'll wait and see 馃槉
Correct, they're concept of monorepo is what they call multizones:
https://nextjs.org/docs/advanced-features/multi-zones
I'm still not totally sold to the concept, I'm trying to understand how this would impact things like SEO.
Nevertheless I don't see how this feature would be helping with our problem, if anything making it even harder.
Let's give it some time and come back to it when they expose their full plan.
Thanks everyone!
Hey y'all, I have a nx Next.js app deploying to Vercel just fine.
.next build foldertarget set to "serverless" or "experimental-serverless-trace"Vercel will automatically configure all of those items if you have a plain Next.js repo. But with NX, you need to configure all of them yourself.
I have a Next.js app configured as the web app in my nx repo at apps/web/
package.json
"scripts": {
"build:web": "nx build web",
apps/web/next.config.js
module.exports = {
target: 'experimental-serverless-trace',
}
.vercelignore
apps/otherapp1
apps/otherapp2
dist
tmp
Project settings in Vercel

Vercel doesn't yet support deploying multiple different apps from the same project. This is their "monorepo" support that is currently in development.
@flybayer This looks super interesting. Thanks for sharing your setup.
I should have never used the word "magic", I'm sorry for that - what I was referring to was how "Vercel" needs to build your next.js app, instead of letting you build it locally, because it needs to perform some extra setup. Even though you can specify what build command to run, like you said, running next build locally and only uploading the output will not have the same effect (it will not work) as letting Vercel run it for you.
Even though we can ignore other apps in .vercelignore, we do not know which libs/ to ignore - you could have 30 libs, but only 3 of them used by the app you're trying to deploy. I'd like to avoid recommending people push their whole "libs" folder on each deployment of a single app, as it's not very scalable (but you can definitely do it if it works for your repo). This problem would be easily solved if we could build locally, as the generated bundle only contains the code that app needs - nothing extra, regardless of how many libraries we have. And it's not just libs/ that introduce this complexity: in your root package.json you might have dozens of dependencies, but only a subset of them needed by your app. Building locally would again only pull what's needed by your app.
Nx currently doesn't allow you to easily copy only the source code needed by a specific app into dist, and I believe this would be the only use-case for such a feature. Which is why I was suggesting we wait to see what is announced for Vercel's monorepo support, in case it changes our outlook on this. It's not such a trivial thing to implement and brings along some complexity.
Please point out if you think I got any of the above wrong. If you have an example repo where you've managed to deploy only a specific app, the libs that it needs (and maybe only its specific package.json) dependencies, I'd be super interested to look at it, as I definitely might have missed something when I was initially testing this.
Hey y'all, I have a nx Next.js app deploying to Vercel just fine.
First a few clarifications:
- Vercel does not use a custom magic build command. It uses whatever you define
Vercel only requires four configuration items for a Next.js deployment:
- Project framework set to "Next.js"
- The command to build your Next app
- The path to your
.nextbuild folder- Next build
targetset to"serverless"or"experimental-serverless-trace"Vercel will automatically configure all of those items if you have a plain Next.js repo. But with NX, you need to configure all of them yourself.
Working Setup
I have a Next.js app configured as the
webapp in my nx repo atapps/web/package.json
"scripts": { "build:web": "nx build web",apps/web/next.config.js
module.exports = { target: 'experimental-serverless-trace', }.vercelignore
apps/otherapp1 apps/otherapp2 dist tmpProject settings in Vercel
Multiple apps
Vercel doesn't yet support deploying multiple different apps from the same project. This is their "monorepo" support that is currently in development.
How do you manage the files in the public folder @flybayer ?
I currently have the same configuration as you but none of my public files are available.
After much trial and error. I finally found my solution.
With @flybayer's solution, if you have files in the public folder, they are not deployed on vercel because Vercel expects the public folder to be at the root where the deployment is done. In an nx folder it should be at the same level as the workspace.json file.
The temporary solution I found is to set the root directory to apps/<app> on vercel and copy the package.json in this folder, the build command simply next build
@rarmatei ah yeah we only have one main app in our repo at the moment, so the libs folder is not a problem.
@bluebeel I'm not using the public directory currently, but that's a good point. Probably will at some point.
Here's a discussion I had with Vercel:

As a general solution, wouldn't it be possible to copy the public folder to root when nx/next has finished building? @rarmatei
By doing this, Vercel sees the public folder at root when it deploys and we maintains the configuration of the ouput directory @flybayer did
Yes that would work. Also Vercel is looking into the public folder and nx.
EDIT - For now, with just one website, i figured it out by following @flybayer setup. It works, and thats what matters. Multiple websites thats going to be a different ball game that i guess they dont have it yet. :)
Okay, as a super new user of the monorepos, let alone nx, how would this work?
If I have a lib folder with multiple components and varibales, how would you deploy something to vercel? Be it git initiated or cli based (i like the idea of cli based better, but its okay)
I am completely lost on how to even send the components and variables that needs to get sent to vercel.
Is it a metter of adding some scripts? I dont get it
Any help would be super welcome
Thanks
I got it working w/ @flybayer's setup. The first time I skipped over the next.config.js part but I needed that to get it to work. I will also note that I get this message:
17:53:12.934 | > NX WARNING Nx Cloud Problems
-- | --
17:53:12.934 | - Cannot connect to remote cache (scope: api, code: ECONNABORTED).
17:53:12.940 | Done in 44.49s.
Apparently vercel blocks outgoing http requests including to nx-cloud, limiting its usefulness. Thankfully, it doesn't slow down the build noticeably. In the future I would probably want to configure it not to run on Vercel. It would be nice if it could run on Vercel though, if I could allow specific hosts.
I managed to deploy a nextJS (SSG) application from a nx monorepo context.

"app:build": "nx run app:build && nx run app:export && yarn app:postbuild",
"app:postbuild": "mv dist/apps/app/exported apps/app/dist",
Selecting the other config did the trick. Using nextJS plugin failed because the route-manifest.json was never found.
Just in case anyone else comes across this thread and doesn't read #4032 (like me). I was able to get this working by adjusting the outputPath that nx builds next into.
I had followed what @flybayer did, and was able to confirm that files weren't serving from the public directory. Simply adjusting the outputPath, and removing the Output Directory override in the Vercel setting fixed it for me.
Note: My build command is simply: "build": "nx build",. So yarn nx build <app> --outputPath . is equivalent.

Hi Folks,
Employee number 5 of Nrwl and long time Nx contributor (as well as long time Zeit/Vercel) user here 馃憢
Some of the suggestions on this thread so far are really not ideal in my opinion. They are giving up certain features of the Vercel + Next.js integration in some cases - sometimes subtly. Believe me I've banged my head against this problem a lot.
I hope sharing what I've learned will be useful to you!
This is the best possible setup I have managed to figure out with Nx + Next.js + Vercel, and I am currently running it in production across multiple projects. It is not perfect, but I believe it is the closest we can get with the current constraints on Vercel, and I have provided them with the product feedback on how to make this work perfectly with Nx. Read on to find out what I mean.
Let's say we have a Next.js app, generated by standard Nx schematics, called website (and it therefore lives in apps/website).
We want to create a project on Vercel by importing our Nx monorepo, and then calling the project website as well (NOT the name of the monorepo itself, which is what Vercel will pick by default).
What's important here is that we want to pick the Next.js preset (NOT Other or anything else)
You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

We want to set the Root Directory to the apps/website directory. That's right, NOT to the root of the monorepo.
You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

Notice that checked box? That's also really important, but it's the default behaviour these days so you don't need to worry about it during initial setup.
We have already picked one of these above, the Next.js preset. Now we need to override the build command as well.
Remember, our root directory is apps/website, so this is the starting context for our build.
I personally have created a reusable shell script that handles traversing up from my app's directory to the root and then doing the necessary Nx install and build. It looks like this:
tools/utils/build-nextjs-app-on-vercel.sh
# THIS SCRIPT IS INTENDED TO BE INVOKED FROM WITHIN THE ROOT OF THE PROJEECT BEING BUILT
# E.g. From within apps/foo -> ../../tools/utils/build-nextjs-app-on-vercel.sh foo apps/foo
if [ "$1" = "" ]
then
echo "\nError: Missing required projectName as first argument"
echo "\n Example usage: $0 <projectName>"
exit
fi
if [ "$2" = "" ]
then
echo "\nError: Missing required outputPath as second argument"
echo "\n Example usage: $0 <projectName> <outputPath>"
exit
fi
# Clean up the node_modules we had to install just to keep Vercel happy within the project root.
# If we don't remove them they will cause issues with the build from the root.
rm -rf node_modules
# Change to root (dynamically determined based on where we are executing the script from
# because there could be nesting within the apps/ directory)
SCRIPT_LOCATION=$0
DOT_DOT_SLASH=../
s=${SCRIPT_LOCATION//"$DOT_DOT_SLASH"}
NUMBER_OF_DOT_DOT_SLASHES="$(((${#SCRIPT_LOCATION} - ${#s}) / ${#DOT_DOT_SLASH}))"
for i in $(seq 1 $NUMBER_OF_DOT_DOT_SLASHES)
do
cd ../
done
# Install full monorepo dependencies
yarn install
NODE_ENV=production npx nx build $1 --prod --outputPath=$2
(If you use this, or any other, shell script don't forget to make it executable in the usual way, e.g. chmod +x tools/utils/build-nextjs-app-on-vercel.sh)
NOTE: Vercel expects our Next.js build output to be in the Vercel Root Directory we chose (i.e. apps/website) so that is why we set the outputPath option to our Nx builder to be just that. This means we don't need to update our Nx workspace.json and we can serve and build the app locally how we always have. Zero config changes FTW!
The usage for our apps/website project therefore looks like this:
../../tools/utils/build-nextjs-app-on-vercel.sh website apps/website
And that's exactly what we override our build command on Vercel to be!
You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

Now because we are handling the monorepo install in our custom build command (which is kind of the only place we can handle it), we don't want Vercel to waste time running an install in the nested location in apps/website.
Unfortunately, however, we do not seem to be able to skip the install command. If we override the install command to be empty - as is suggested - it will throw an error.
You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

SUPER DUPER IMPORTANT NOTE and the only real caveat of this setup...
Vercel will look for a package.json in your Vercel Root Directory, so for us that is apps/website.
This needs to exist, and it needs to be valid JSON otherwise the Vercel build silently fails. Unfortunately it does also need to contain a dependency on Next.js as well, which was briefly not the case on Vercel, but they seem to have added an explicit check for it now.
Remember above when I said this:
It is not perfect, but I believe it is the closest we can get with the current constraints on Vercel, and I have provided them with the product feedback on how to make this work perfectly with Nx
This is what I was referring to! I have passed on this exact feedback to Vercel. If they could make it so that this package.json check does not happen, the setup would be pretty great and all OOTB Nx!
So, all we need to do to work around this check and complete our setup is add a basic package.json file in the right location. I personally went for this:
apps/website/package.json
{
"private": true,
"description": "This file (and next dep) has to be here to get the Vercel build to run at all",
"dependencies": {
"next": "9.5.2"
}
}
The next version here doesn't matter at all, it is never going to be used (and our custom build script above cleaned it up post-install anyway).
And that's it!
We only needed to add one file (and change ZERO config) for our OOTB Nx Next.js app to work and all the most killer automatic optimizations of Vercel + Next.js are fully available to us, such as Incremental Static Generation 馃帀
Tangentially related for anyone that is interested:
The other big win that Vercel could make available to us Nx users would be to open up their Skip Build feature to the Nx dependency graph. Right now the Skip Build piece only does a very shallow checkout, so it is not possible to let Nx figure out what is affected for a particular commit.
Thanks to any Vercel folks who read this and let me know if I can help provide further feedback to make the Nx + Vercel story the best it can be 馃檹
@JamesHenry Any idea why the route-manifest.json isn't found with nextJS plugin?
@dbrrt If you are still approaching it based on the config in your comment above: https://github.com/nrwl/nx/issues/3051#issuecomment-718202172
...then that is the reason why.
My explanation covers that you should not choose Other, you should configure it using the Next.js Framework Preset, and follow all the other steps I outline.
All the steps I outline work together to create the final effect, including the Root Directory, Framework Preset, Custom Build Command etc
PS. Hopefully you are not changing anything about your next.config.js to try and "fix" the Vercel issues? Again the steps I outline above are how to make it work. If you are doing anything differently/in addition, then you risk it not working as expected. Hope that helps!
@JamesHenry Thanks for your tips, that'll be helpful, my approach worked somehow but would've preferred having the nextJS preset working indeed.
@JamesHenry I tried the above provided solution. But it says access denied on build-nextjs-app-on-vercel.sh file.
What could be the possible solution?
@sskhokhar Perhaps you forgot to make the shell script executable after creating it?
chmod +x tools/utils/build-nextjs-app-on-vercel.sh
I'll add that as a note in my description to remind folks
Thanks @JamesHenry
Hey, everyone!
Leo from Vercel here.
I'm scheduling a call with @JamesHenry to gain more insight into how we can make deploying NX to Vercel ideal. Afterwards, we'll get back to you here with an improved system!
Thank you for your patience!
@leo @JamesHenry Been using NX for a while and started looking into Next.js + Vercel + NX only yesterday, so imagine how thrilled I was reading the above! NX is awesome, everything should work with NX.
We had a great call with @leo and have learned about some new improvements that have gone into Vercel that will allow us to simplify the recommendations.
I will be updating the Next.js guide on nx.dev to reflect this, and we can close this issue once that update goes live!
Anyone know why I might be getting the following:

The configuration has been checked over multiple times by multiple people to ensure it matches the above.
Hey @JamesHenry . I saw on Nx's version 11 blog that they mention the contact with Vercel.
Do you know when said conversation / writings will be added? Or if they already are added to nx's website - the guides I mean?
Thanks!
Happy holidays 馃帀
Most helpful comment
We had a great call with @leo and have learned about some new improvements that have gone into Vercel that will allow us to simplify the recommendations.
I will be updating the Next.js guide on nx.dev to reflect this, and we can close this issue once that update goes live!