How to Deploy Angular 17 to Vercel

Angular 17 features built-in SSR support; however, deployment is not as straightforward as it might seem, or is it?

Avatar

Kasperi Pohtinen

3 min read · Jan 16, 2024 · 0 likes

Inspiration from

This post was inpired by jdgamble555, who wrote blogpost on dev.to. You should read it first :) I thought I have some additional insights of the issue so I though writing my own.

Brief Introduction to How Angular SSR Works

Angular's server-side rendering (SSR) can be categorized into two main approaches: SSR and SSG.

SSG (Build-Time Prerendering)

SSG, which stands for build-time prerendering, involves rendering pages during the build process. These pages are then hydrated on the client side. This process allows for the initial page to be rerendered on the client. Subsequently, any changes are handled by the client, ensuring an up-to-date rendering of the content.

SSR (On-Demand Rendering)

Conversely, SSR operates on an on-demand basis. Each time a request is made, the server renders the complete page and delivers it. This method is especially useful for dynamic content that changes frequently.

Angular 17's Default Setting

In Angular 17, the default setting is SSG (pre-rendering), as specified in the angular.json file:

"prerender": true,
"ssr": {
    "entry": "server.ts"
}

Angular automatically prerenders all unparameterized routes within your application. However, for prerendering parameterized or dynamic routes, you need to manually specify these routes. This is done by using a routes.txt file, where you define the required parameterized routes. This approach allows for the targeted prerendering of dynamic content in your Angular application. Check SSR-documentation

Behavior with SSR Enabled

When SSR is enabled and a page is pre-rendered, users receive the pre-generated HTML directly, eliminating the need to make a server request. If no pre-generated HTML is available, Angular falls back to on-demand rendering, where the server is engaged to render the page.

Use Cases

Pre-rendering is ideal for static pages where the content remains constant. For pages with dynamic and frequently changing content, on-demand rendering is preferred to ensure the delivery of the most current content without requiring the client to update outdated HTML.

Issue with Vercel

When using Vercel's default Angular-framework preset, SSR is not working, meaning pages requiring on-demand rendering won't be rendered on server side. Vercel is only capable of serving SSG (pre-rendered) pages.

To fix this issue you need to create Vercel serverless function that actually is capable of rendering your pages. You can do this by doing following:

1. Create API-route

Create API-folder to your project's root containing following index.js-file. Replace YOUR_PROJECT_NAME with your project's name.

import * as server from '../dist/YOUR_PROJECT_NAME/server/server.mjs';

export default server.app();

2. Add Vercel config

Add vercel.json to your project's root. Replace YOUR_PROJECT_NAME with your project's name.

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "version": 2,
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/api"
    }
  ],
  "functions": {
    "api/index.js": {
      "includeFiles": "dist/YOUR_PROJECT_NAME/**"
    }
  }
}

3. Add type module

Add "type": "module" to bottom of your package.json

Example repository

You can check this website's source code which is utilizing Angular 17 SSR and is deployed on Vercel :) https://github.com/KasperiP/til-frontend

I have utilized pre-rendeing and also on-demand SSR. Feed page is rendered on demand because it has dynamic content and other pages are pre-rendered.