How to deploy an SSR angular app on Vercel
To deploy an SSR angular app on Vercel you need to use server less functions.
Each request will invoke the serverless function, which will render the page and send it back to the client.
First you need to create a vercel.json
file in the root of your project.
It should look like this:
{
"version": 2,
"public": true,
"rewrites": [
{
"source": "/(.*)",
"destination": "/api"
}
],
"functions": {
"api/index.js": {
"includeFiles": "dist/<your project>/server/**/*"
}
}
}
The first part (rewrites) is used to redirect all the requests to the serverless function which will be placed in /api
.
The second part (functions) is used to include the files needed for the serverless function to work. You need to replace <your project>
with the name of your project.
Then you need to create a api/index.js
file in the root of your project.
Depending on the version of angular you are using, the content of the file will be different.
On older versions of angular the content of the file should look like this:
export default import('../dist/<your project>)/server/server.mjs').then(
(module) => module.app(),
);
On newer versions of angular the content of the file should look like this:
export default import('../dist/<your project>/server/server.mjs').then(
(module) => module.reqHandler,
);
As I said before, each request will invoke this file, and it pass the request to the module server.mjs
which will render the page and send it back to the client.
With that it should work. But you might have one issue where the home route /
is not rendered server side, but client side.
The reason is the way vercel work to send a response to the client.
First it will check if a file exists in the path for the requested url. When you request the home page /
, it will look for a file named index.html, which usually exist.
To fix it you can rename the src/index.html
file to src/default.html
and update the path inside angular.json
file:
{
"projects": {
"<your project>": {
"architect": {
"build": {
"options": {
"index": "src/default.html"
}
}
}
}
}
}