You made a great app based on Angular and NestJS but now you wonder how to host it without getting a headache and above all: for free. Then Heroku might be a right choice ! Let’s see how to make all these folks work together.
What we want to achieve here is to “package” our front-end and our back-end apps as one in order to deploy it to a single Heroku app. Yes we can !
So we’re going to build our Angular app for production and put the build result (I mean files) into our NestJS app at a specific location. Then, we will tell NestJS to serve those files as soon as the requested URL doesn’t match any API route. And of course, NestJS must be still able to serve API responses after that.
What you need to know before we start
If you ended up here, I assume you already know Angular, NestJS and Heroku. I won’t tell you how to create a project with those frameworks, how they work or other basic stuff like that.
I will just show you what is inside my basic Angular and NestJS apps and how to deploy them as a single one to Heroku with few tips.
Our demonstration app is going to be a basic user list. It will be splitted in two parts: user-list-front and user-list-back, each one in a separate folder.
Ok so first things first, I’m gonna show you what’s inside my Angular app.
Our main component will only contain our basic app layout, title and a mandatory
Its only purpose is to show a clickable button leading to another page. This won’t be very useful, I agree, but it’s just to show you that routing will be working well on our front app once deployed on Heroku.
This component will call
UserService to fetch users list and display it.
Will fetch users from back-end.
Two routes will be registered: one “by default” to display
HomeComponent and another one to load
A little something you have to change before going any further is the environment files. We’re actually going to declare the URL of our back-end inside those files because it won’t be the same wether we are in development mode or in production mode.
Now that we have a very basic but still working Angular app, let’s work on the back side of the Force.
A simple controller with one endpoint allowing us to get all users. I suggest you to prefix all your controller routes with
/api like I did here, so you make sure all your endpoints serving datas are located behind the same path.
To keep things simple, our app won’t be linked to any database but of course, you’ll want to fetch data dynamically from a source in a “real” app.
Last but not least, you have to modify the
main.ts file for two things:
- To make your app start on a dynamic port (Heroku won’t let you choose the port on which your app will be reacheable, so it stores it inside
- To activate CORS (otherwise your front-end won’t reach your back-end)
At this point, you should have a working app, with a front-end fetching and displaying datas provided by the back-end, which is nice ! But now let’s dive into the serious business !
Building Angular App and put it into NestJS
As said earlier, NestJS will be the place where all the magic will occur. So there will go our built Angular application.
We have two choices here:
- Launch the build command on our Angular app manually, wait for it to finish and then move Angular’s
distfolder into NestJS by drag and drop or cut/paste
- Or create a script inside NestJS
package.jsonand make it work for us
Feel free to choose the option you prefer, anyway I’m gonna show you how to implement the second one :)
Angular’s package.json script
Our script will:
- Remove previous folder that might already exist from a previous build
- Build our Angular app
- Move the Angular build result (files and folders) into a “front” folder in NestJS app
As this script will call native functions on the OS you are using in order to move files or delete a repository, I give you a Windows version and a Mac OS one. Both of them are supposed to go to the “script” section of your Angular’s
"build:win": "(if exist ..\\user-list-back\\front rmdir ..\\user-list-back\\front /s /q) && ng build --prod && move dist/user-list-front ..\\user-list-back\\front"
"build:mac": "rm -rf ../user-list-back/front && mkdir ../user-list-back/front && ng build --prod && mv dist/user-list-front/* ../user-list-back/front/"
Ask NestJS to serve static files
At this point, a new folder called “front” should be present inside your NestJS app. It contains our built Angular app. Now we want to tell NestJS to serve those Angular files.
First, install the
ServeStatic NestJS module:
npm install --save @nestjs/serve-static
Then import and configure the
ServeStaticModule inside your
AppModule like so:
Important notice: from now, absolutely none of your controllers should respond and serve data to the root route
Why ? Because static files have to be served at this specific URL. If one of your controller responds to that route, files will never be served. This acts like a fallback: if no route matches, then serve static files.
So what now ? Try to navigate in your web browser to http://localhost:3000 and you will be amazed to see that we’ve got our front-end showing and our datas from back-end displayed as well !
Now you saw that our app is working well behind http://localhost:3000. It’s time to put everything on Heroku and make it available to the world !
Create Heroku app
First, install the Heroku CLI to make things easier:
Then, create a new app on your Heroku account and name it the way you want. Mine will be called “angular-nestjs-demo”.
Heroku needs a tiny bit of configuration before it can deploy our app.
Go to your Heroku app, then Settings and find the “Config Vars” section and click on “Reveal Vars” button.
Here you have to enter this key-value:
This will skip pruning our dev dependencies, which are needed to run the app correctly once deployed.
Push your project on Heroku
Once created, you can go to your back-end project and run this command to link your repository to Heroku:
heroku git:remote -a <your-heroku-app-name>
Now create your first commit. It should include all your project, obviously. Then you will be able to push your commit directly to Heroku and it will take care of the deployment for you. Just run:
git push heroku master
Once pushing and deploy is done, go to your Heroku app by URL, in my case it will be https://angular-nestjs-demo.herokuapp.com
And voilà ! Here’s what you should see:
And if you navigate to
/users by clicking on the button:
As you can see, Angular routing is working fine, as well as the API call because the user list is nicely displayed.
Here you go, you know how to deploy Angular & NestJS project to Heroku :)
You can find this project at this location: