Angular SSR on Vercel: The Configuration You Need

Modern web development puts a premium on speed, user experience, and smooth deployment workflows. Angular has stepped up to meet these expectations with built-in Server-Side Rendering (SSR) support, which brings quicker initial page loads and better search engine visibility.

Yet, getting Angular SSR to cooperate with a platform like Vercel involves some fine-tuning beyond the defaults.

Generating a fresh Angular project is straightforward. By passing the --ssr flag, you enable server-side rendering right from the start.

Running ng new your-project-name-here --ssr kicks off the scaffolding process. The setup wizard asks for a few preferences that shape the project:

  • Stylesheet Format: Options include plain CSS, Tailwind CSS, Sass (SCSS), and similar systems.
  • Zoneless Mode: Choosing to build without zone.js is a deliberate move toward better performance. While zone.js simplifies change detection, it can create unwanted overhead. Without it, you gain finer control and typically see smaller bundles and faster runtime behavior.
  • AI Tooling: The exact smart features weren't specified in the source material, but wiring them into the project following Angular conventions points to a practical approach for adding intelligence to the app.

Setting Up an API Endpoint

Once the foundational Angular SSR app is up and running, a simple API endpoint comes next. A "ping" route is a common way to verify backend connectivity.

app.get('/api/ping', (req, res) => { 
  res.json({ message: 'pong' })
});

This minimal API returns a JSON payload containing a "pong" message, acting as a quick sanity check for server communication.

Using the normal Vercel deployment pipeline for this setup produced an unexpected outcome.

Locally, both the app and its API behaved as expected. On Vercel, however, the API route did not respond correctly. This is a typical snag with serverless platforms, where routing rules and server-side execution differ from a traditional server environment.

Custom Vercel Configuration

To resolve this, two files need to be added: api/index.js and vercel.json. These are the keys to making Angular SSR work with Vercel's serverless functions while ensuring every route, including custom APIs, is routed properly.

The api/index.js file serves as the entry point for Vercel's serverless execution.

export default async (req, res) => {
  const { reqHandler } = await import('../dist/angular-SSR-vercel/server/server.mjs');
  return reqHandler(req, res);
};

Inside this file, the compiled Angular SSR server handler — reqHandler — is loaded asynchronously from dist/angular-SSR-vercel/server/server.mjs. This handler processes every incoming request, covering both the Angular app's routes and any API endpoints defined inside the Angular server.

By making this handler the default export, Vercel knows exactly how to handle traffic aimed at this serverless function.

The vercel.json file is just as critical. It lays out explicit build and routing instructions for Vercel:

{
  "version": 2,
  "public": true,
  "name": "your-project-name-here",
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/api"
    }
  ],
  "functions": {
    "api/index.js": {
      "includeFiles": "dist/your-project-name-here/**"
    }
  }
}

The important bits are:

  • "rewrites": This is where routing logic comes together. The pattern "source": "/(.*)" captures all incoming requests. The "destination": "/api" value points each of those requests to the /api path, which is serviced by the api/index.js serverless function. As a result, static assets, Angular routes, and custom API calls all pass through the Angular SSR server.
  • "functions": This block configures the serverless functions themselves. "api/index.js" marks our entry file. The "includeFiles": "dist/angular-SSR-vercel/" setting is particularly important — it tells Vercel to bundle the full compiled Angular SSR output directory into the serverless function.

Without that include directive, the api/index.js file would be unable to locate and import server.mjs, causing the deployment to break.


With these settings applied, the Angular SSR application, including its custom /api/ping route, deployed cleanly on Vercel. The rewrite rule in vercel.json channels all traffic to the api/index.js serverless function, which in turn uses the Angular SSR reqHandler to deliver both the rendered app and any API responses.

This setup provides a solid model for pairing Angular SSR with Vercel, offering search-engine-friendly output alongside seamless API functionality.


You can find me on GitHub, where I build interesting projects. Thanks for reading — feel free to show some love with a few claps. See you soon.

gioboa image

Giorgio Boa is a full-stack developer with a passion for the front-end ecosystem. He also speaks at international events, contributes to open-source projects, and enjoys learning new technologies.