Deploy an Angular App: Netlify, Firebase and Nginx

Angular Tutorial: Beginner to Advanced · 12. Projects and deployment · 3 min read · Updated

Your app is finished and tested. Deployment means putting the built files where anyone can open them. An Angular app is a set of static files, so almost any web host works.

What you will learn

  • How to create the production build
  • Why refreshing a route shows 404 and how to fix it
  • Three ways to publish: Netlify, Firebase Hosting and Nginx

1. Build

ng build

The files are created in dist/<project-name>/browser. That folder is what you upload. Check that it contains index.html.

2. The refresh problem

Your app has one real HTML file. Routes such as /about only exist inside the browser. If someone refreshes at /about, the server looks for a file called about, finds none and returns 404.

The fix is a fallback: for any URL that is not a real file, the server returns index.html and Angular shows the right page. Every host below has a setting for it.

3. Option A: Netlify

  1. Push your code to GitHub.
  2. In Netlify choose "Add new site", then import your repository.
  3. Build command: ng build (or npm run build). Publish directory: dist/<project-name>/browser.
  4. Add a file named public/_redirects to your project with this single line, so it is copied into the build:
/*    /index.html   200

4. Option B: Firebase Hosting

npm install -g firebase-tools
firebase login
firebase init hosting

Answer the questions: public directory dist/<project-name>/browser, configure as a single-page app: Yes. That adds the rewrite for you. Then:

ng build
firebase deploy

5. Option C: your own server with Nginx

Copy the contents of the browser folder to the server, for example /var/www/my-app, and create a site configuration:

server {
  listen 80;
  server_name example.com;
  root /var/www/my-app;
  index index.html;

  # Cache hashed build files for a long time
  location ~* \.(js|css|woff2|png|jpg|svg|ico)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
  }

  # Never cache index.html, so users get new releases
  location = /index.html {
    add_header Cache-Control "no-cache";
  }

  # SPA fallback
  location / {
    try_files $uri $uri/ /index.html;
  }
}

Test the file with sudo nginx -t, then reload with sudo systemctl reload nginx. Add HTTPS with a free certificate from Let's Encrypt (certbot).

6. After deployment

  • Open the live site and refresh on a deep link such as /about.
  • Open DevTools and check for failed requests or CORS errors. Your API must allow your site's origin.
  • Make sure the API URL points to production, not localhost.
  • Run Lighthouse on the live URL.
  • Add a unique title and meta description per page. For public pages that must rank in search, consider server-side rendering or pre-rendering.

Common problems

  • Blank page and console errors about files: the app is served from a sub-folder. Build with ng build --base-href /my-folder/.
  • 404 on refresh: the fallback is missing.
  • Old version after a release: index.html is cached. Use the no-cache header above.
  • API calls fail only in production: check the API URL, HTTPS (mixed content) and CORS.

Try it yourself

  1. Deploy one of your projects to a free host.
  2. Test a refresh on a nested route.
  3. Add the live link and a screenshot to your README.

Quick check

  1. Which folder do you upload?
  2. Why does refreshing a route return 404 without a fallback?
  3. Why should index.html not be cached for long?

Congratulations, you have finished the beginner and intermediate stages. If you want to go further, the advanced stage starts with effect() and linkedSignal() and ends with a production-ready capstone. You can also revisit what Angular is at any time. The official deployment guide lists more hosts.

Frequently asked questions

Do I need Node.js on the server?

Not for a client-side Angular app. It is only static files. You need Node on the server only if you add server-side rendering.

Is a free host enough for a real project?

For learning and small projects, yes. For business sites, check limits, uptime guarantees and custom domain support.