After 176 commits, memorizing the Vercel docs, searching through the Nuxt, Sveltekit, Vercel, and Next GitHub packages, browsing stackoverflow, and pulling my hair out, I finally got this thing to work. Then I didn't; then I did; then I simplified it, I found problems, and I came to a general solution.
Thanks to this guy's overly complicated monorepo, I found the missing pieces. It was not easy.
Here is the final working example:
Solution
- Create a
vercel.json
file at the root of your Angular Universal project with YOUR_PROJECT_NAME:
vercel.json
{
"version": 2,
"public": true,
"name": "test-universal",
"rewrites": [
{ "source": "/(.*)", "destination": "/api" }
],
"functions": {
"api/index.js": {
"includeFiles": "dist/YOUR_PROJECT_NAME/browser/**"
}
}
}
All we are doing is pointing all requests to the api/
folder. You must also select which files to give your script access to with includeFiles
.
2. Rename scripts.build
to scripts.build-dev
in package.json
. Vercel runs npm run build
automatically, with only access for the browser. We do not need that in this case.
3. Add scripts.vercel-build
with the value npm run build:ssr
. This is run specifically within the serverless function to give you access to all your files and scripts.
package.json
{
"name": "test",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build-dev": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"dev:ssr": "ng run test:serve-ssr",
"serve:ssr": "node dist/test/server/main.js",
"build:ssr": "ng build && ng run test:server",
"prerender": "ng run test:prerender",
"vercel-build": "npm run build:ssr"
},
...
4. Create the file api/index.js
. All scripts in the api
directory are automatically used as serverless functions.
api/index.js
const server = require('../dist/YOUR_PROJECT_NAME/server/main');
module.exports = server.app();
5. Push to GitHub. An existing Vercel project will automatically deploy, or you can click New Project
, and select your GitHub Repository.
That's it!
This took me a week to do, and it is so simple.
Vercel Team, please add this to your existing templates!
Now, I can use Angular and Vercel with their CDN and Edge Functions. There is similar functionality in Google Cloud, just a pain to configure.
FWI - There is a plugin for Netlify if you prefer a different provider. Either way, Angular Universal is now available on all major servers.
Until next time...
J
Update: If you have the Service Worker enabled, it will look like it is only loading the static version. Disable cookies temporarily, and you can see it works as expected.
Note: I should also tell you Vercel's Serverless functions have a 50mb limit. If you have a giant app, this is not the best server. NextJS is built to use Vercel so that each page uses its own Serverless function. I suspect SvelteKit will follow this pattern now that Rich Harris is on board with Vercel. That being said, Svelte is a baby, and I personally hate React. Better use Cloud Run for bigger apps.
Top comments (5)
Thanks for this! I made a few changes to my setup so I'm not always running production environments when I want to hit say staging backend.
Strip out
"vercel-build": "npm run build:ssr"
from package.jsonUpdate
"build:ssr"
to"ng build --configuration production && ng run project-name-here:server"
Create vercel.sh in your root directory of the project
The above is just looking at what branch is being deployed, if it's main/master build:ssr will run if its any other branch my staging-environment deployment script will run.
Settings on Vercel for the project add custom build command of

sh vercel.sh
Thanks man for this!! It has saved me, rsss. Thanks 4 share!
Thanks for sharing this man! this is helpful
but one problem I am facing is my app is not server-rendered.
the home url is working but only the static version (with cookies disabled)
but any other url is taking more than 10 seconds to respond, resulting in 504 function timeout error.
could you please help my out?
Thanks
You may have a loop in your code. Make sure to test it with
npm run dev:ssr
first. Usually it is a login code that should only be ran on the frontend.Thanks for this, How can i used with i18n ?