How to deploy Angular App with Node.js and Express backend to Netlify

Orly Knop
Web Development Ideas
4 min readAug 13, 2020

--

Recently I wanted to host my project built with Angular on the frontend and Node.js with Express on the backend. I have already been using Heroku for several years but I didn’t want the app to sleep, so I needed to find something else. Sometime later I was told that there is Netlify that allows hosting for free.

Site deployment

Netlify sites page
Sites page on Netlify

Netlify supports deployment projects from GitHub, GitLab, and Bitbucket. After selecting the repository you need to set some configuration options.

Netlify deploy settings form
Deploy settings form

Build settings such as build command and publish directory could be defined also in the netlify.toml file in the project:

// netlify.toml[build]command = "CI='' npm run build"publish = "dist/theme-customization"

The Environment variables could be defined in the “Advance build settings” section.

Required changes to the project

In order for the deployment to work both the front end and the back end require some changes.

Changes to the back end

Netlify does not support backend per se, but it supports Lambda functions that let developers run server-side code. By making some modifications to backend built with Nodejs and Express, it is possible to “convert” API endpoints to Lambda functions.

This is a tree structure of the test project:

.gitignore
LICENSE
README.md
express
|-- server.js
netlify.toml
package-lock.json
package.json
server.js
theme-customization
|-- .editorconfig
|-- .gitignore
|-- LICENSE
|-- README.md
|-- angular.json
|-- browserslist
|-- e2e
| |-- protractor.conf.js
| |-- src
| | |-- app.e2e-spec.ts
| | |-- app.po.ts
| |-- tsconfig.json
|-- karma.conf.js
|-- package-lock.json
|-- package.json
|-- src
| |-- _palette.scss
| |-- _theme.scss
| |-- _typography.scss
| |-- app
| | |-- app-routing.module.ts
| | |-- app.component.html
| | |-- app.component.scss
| | |-- app.component.spec.ts
| | |-- app.component.ts
| | |-- app.module.ts
| | |-- color-palette-card
| | | |-- color-palette-card.component.html
| | | |-- color-palette-card.component.scss
| | | |-- color-palette-card.component.spec.ts
| | | |-- color-palette-card.component.ts
| | |-- color-palette
| | | |-- color-palette.component.html
| | | |-- color-palette.component.scss
| | | |-- color-palette.component.spec.ts
| | | |-- color-palette.component.ts
| | |-- main-navigation
| | | |-- main-navigation.component.html
| | | |-- main-navigation.component.scss
| | | |-- main-navigation.component.spec.ts
| | | |-- main-navigation.component.ts
| | |-- page-layout
| | | |-- page-layout.component.html
| | | |-- page-layout.component.scss
| | | |-- page-layout.component.spec.ts
| | | |-- page-layout.component.ts
| | |-- typography
| | | |-- typography.component.html
| | | |-- typography.component.scss
| | | |-- typography.component.spec.ts
| | | |-- typography.component.ts
| |-- assets
| | |-- .gitkeep
| | |-- angular-logo.png
| | |-- logo.png
| |-- environments
| | |-- environment.prod.ts
| | |-- environment.ts
| |-- favicon.ico
| |-- index.html
| |-- main.ts
| |-- polyfills.ts
| |-- styles.scss
| |-- test.ts
|-- tsconfig.app.json
|-- tsconfig.json
|-- tsconfig.spec.json
|-- tslint.json

The backend has only one endpoint /api/test.

We need to install the serverless-http package and use it to update exported modules by adding this code to the end of the file:

module.exports.handler = serverless(app);

We also should update the apiRoute variable:

const apiRoute = "/.netlify/functions/server/api";

To create Lambda functions from the server endpoints we need to install netlify-lambda package. We will use it in the project build script:

"build": "cd theme-customization && npm install && ng build --prod && cd ../ && netlify-lambda build express"

The first part of the build command:

cd theme-customization && npm install && ng build --prod

is used to build the Angular project for production. The rest of the command is used to create afunction folder with lambda functions. Since this folder will be generated during the build process, I have added it to .gitignore file.

Update netlify.toml file build configurations by setting folder with lambda functions:

[build]...functions = "functions"

Changes to the front end

  1. Update dist folder for the build by changing outputPath for build in angular.json file to ../dist/{projectName}. Doing that we are setting folder for the built project to be dist/{projectName} folder, which is specified in netlify.toml file under publish. If we need to change it, this change should be reflected in netlify.toml file as well.
  2. Change routes to API from /api to /.netlify/functions/server/api since we have changed the API routes in the back end.
  3. Allow browser refresh to work by setting redirect and rewrite rule. It is possible to be done in two ways.

Method 1:

Create a _redirects file with this content:

/*  /index.html 200

Specify the file in angular.json file in build assets:

{"glob": "_redirects","input": "src","output": "/"}

Method 2:

Add this code snippet to netlify.toml file:

[[redirects]]from = "/*"to = "/index.html"status = 200

Read more on this topic here.

Summary

In this article, we covered how to prepare both Angular app and Node.js with Express project for deployment on Netlify. This changes still will apply if you need to host only front end or back end. I have created a boilerplate on GitHub with all the changes described in this article. The demo is available at https://blissful-villani-d09933.netlify.app/.

--

--