How to Deploy Angular Universal to Vercel

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.

Solution

  1. 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.

109