Update - Angular 17.2 - 3/2/24
While you still can't get Vercel Edge deployments to work until the nodejs dependencies problem is resolved, you can now deploy @angular/ssr to Vercel serverless functions with a few changes:
- Create
api/index.js
file: ```js
export default import('../dist/YOUR-PROJECT/server/server.mjs')
.then(module => module.app());
2\. Add `vercel.json` file:
```json
{
"version": 2,
"public": true,
"name": "YOUR-PROJECT",
"rewrites": [
{
"source": "/(.*)",
"destination": "/api"
}
],
"functions": {
"api/index.js": {
"includeFiles": "dist/YOUR-PROJECT/**"
}
}
}
3. Comment out run()
in server.ts
as you will be running the server on Vercel functions.
4. If you don't want prerendering:
- Rename
index.html
toindex1.html
, and update the path inangular.json
atprojects.architect.build.index
tosrc/index1.html
. - Also set
projects.architect.build.options.prerender
tofalse
. This will ensure your code is dynamically rendered.
That's it! Thanks to @mickl, @trongthuong96, and @wolfsoko for the updates in the comments for figuring all this out. I have simplified what you said.
Demo: https://angular-vercel-ssr.vercel.app/
GitHub: https://github.com/jdgamble555/angular-vercel-ssr
Original Post
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.