Angular apps built with the CLI compile to static HTML, CSS, and JavaScript that can be served from a CDN with no Node process running. The default deployment gives you a subdomain like angular-app-abc123.pandastack.app, which works for testing but looks unprofessional in production. Real apps need a custom domain, and HTTPS is mandatory for any site handling user input or authentication.
PandaStack automates the entire process: add your domain in the project settings, point a CNAME record at the target, wait for DNS to propagate, and the platform provisions a Let's Encrypt certificate automatically. The certificate renews before expiration, so there is no manual work after the initial setup. The only thing that can break this is misconfigured DNS, which is easy to debug.
Build the Angular app for production
Angular's dev server (ng serve) is for local development and cannot be deployed. The production build is ng build, which outputs static files to dist/your-app-name/browser/ by default.
Run the build locally to confirm the output directory:
ng build --configuration production
ls dist/angular-app/browserYou should see index.html, main.*.js, styles.*.css, and other hashed assets. This is what gets deployed to the CDN.
The build output directory changed in Angular 17+. Older versions output to dist/your-app-name/; newer versions output to dist/your-app-name/browser/. Check angular.json under projects.your-app-name.architect.build.options.outputPath to confirm the exact path.
Deploy the Angular app as a static site
Create the project via the API or dashboard. If using the API:
curl -X POST https://api.pandastack.io/v1/projects \
-H "Authorization: Bearer $PANDASTACK_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "static",
"name": "angular-app",
"repositoryName": "yourname/angular-app",
"branch": "main",
"autoDeploy": true,
"buildCommand": "npm run build -- --configuration production",
"outputDir": "dist/angular-app/browser"
}'The platform clones the repo, runs npm install, builds the app, and uploads the static files to CDN storage. The site is live at https://angular-app-abc123.pandastack.app.
If the build fails with "Could not find a production build," the outputDir is wrong. Check angular.json and update the outputDir parameter to match.
Add a custom domain in the project settings
In the dashboard, navigate to your project → Settings → Domains. Click Add Domain and enter your domain or subdomain:
app.example.com(subdomain)example.com(apex domain)
The platform generates a CNAME target like cname.pandastack.app and displays it in the UI. Do not click Save yet — you need to configure DNS first.
Point a CNAME record at the PandaStack target
Log in to your DNS provider (Cloudflare, Namecheap, Route 53, etc.) and add a CNAME record:
- Type: CNAME
- Name:
app(forapp.example.com) or@(for apex domain) - Target:
cname.pandastack.app(the value from the dashboard) - TTL: 300 (5 minutes for faster propagation during setup)
If you are using an apex domain (example.com with no subdomain), your DNS provider must support CNAME flattening or ALIAS records. Cloudflare, DNSimple, and most modern providers do. Legacy providers that require an A record for the apex will not work because the underlying CDN IP addresses can change.
For Cloudflare users: disable the orange cloud (set DNS-only mode) during initial setup. Once the certificate provisions, you can re-enable it if you want Cloudflare's WAF and caching on top of PandaStack's CDN.
Wait for DNS propagation and certificate provisioning
After adding the CNAME record, wait 5–30 minutes for DNS to propagate. Check propagation with:
dig app.example.comor use an online tool like [WhatsMyDNS](https://www.whatsmydns.net/). The CNAME should resolve to cname.pandastack.app.
Once DNS resolves, the platform detects the domain, provisions a Let's Encrypt certificate via ACME HTTP-01 challenge, and installs it. The site becomes accessible at https://app.example.com.
If the certificate does not provision after 30 minutes:
- 1Verify the CNAME resolves correctly
- 2Check that no firewall or proxy is blocking the ACME challenge on port 80
- 3If using Cloudflare, ensure the orange cloud is off (DNS-only mode)
Enforce HTTPS by redirecting HTTP requests
The platform serves both HTTP and HTTPS by default. Most apps should redirect HTTP → HTTPS to enforce encryption. This is configured automatically for custom domains: requests to http://app.example.com redirect to https://app.example.com.
The auto-generated subdomain (angular-app-abc123.pandastack.app) also enforces HTTPS, so all traffic is encrypted regardless of which domain the user visits.
Handle Angular routing with client-side fallback
Angular SPAs use client-side routing: when the user navigates from /home to /about, the router updates the URL without a server request. This works perfectly when the user starts at the root URL and clicks through the app, but breaks when they bookmark /about and visit it directly.
The server receives a request for /about, looks for a file named about, finds nothing, and returns a 404. The Angular router never gets a chance to run because the HTML never loads.
PandaStack's static hosting solves this automatically: any request that does not match a file serves index.html, which boots the Angular app. The router reads the URL, matches it to a route, and renders the correct component. This is the standard SPA fallback behavior and requires no configuration.
Update DNS TTL after the domain is live
During setup, you set the CNAME TTL to 300 seconds (5 minutes) for fast iteration. Once the domain is live and the certificate is provisioned, increase the TTL to 3600 (1 hour) or 86400 (1 day). This reduces DNS query volume and improves performance.
Add multiple domains to the same app
If you want both www.example.com and example.com to serve the app, add both as custom domains and point both to the CNAME target:
www.example.com→ CNAMEcname.pandastack.appexample.com→ ALIAS or CNAME (if supported) →cname.pandastack.app
The platform provisions separate certificates for each domain. You can designate one as the primary domain and redirect the other to it, or serve the app from both.
Redeploy when Angular routes or build config changes
Adding or renaming routes does not require DNS changes or certificate updates. The build output changes, but the domain and SSL setup remain the same. Push the commit, and the platform redeploys the new version.
If you change the build output directory in angular.json, update the outputDir parameter in your project settings to match. Otherwise, the platform uploads the wrong directory and the site breaks.
Monitor certificate expiration and renewal
Let's Encrypt certificates are valid for 90 days. The platform automatically renews them 30 days before expiration, so there is no manual intervention required. If renewal fails (usually due to DNS misconfiguration or the CNAME being removed), you will receive an email notification.
Check certificate status:
openssl s_client -connect app.example.com:443 -servername app.example.com < /dev/null 2>/dev/null | openssl x509 -noout -datesYou should see a notAfter date at least 60 days in the future. If the certificate expires soon and has not renewed, check the domain configuration and DNS records.
References
- [Angular deployment documentation](https://angular.dev/tools/cli/deployment)
- [Let's Encrypt documentation](https://letsencrypt.org/docs/)
- [PandaStack custom domains guide](https://docs.pandastack.io/projects/)