I had both https://resolv.it.com/ and https://www.resolv.it.com/ pointing at the same Azure Container App, so the site worked on both but browsers saw two separate sites. This is how I made www the one true host, in code, without touching UAT.
Two things go wrong when both hosts serve the site:
- Cookies and saved passwords are per host, so a user who signs in on one host is signed out on the other.
- Search engines see two copies of the same site and rank each lower.
1. Pick one host
Either is fine, the point is picking one. I went with www because it works with a CNAME (the host can move without a DNS change) while the apex needs a fixed A record. The DNS side is in Azure Container App With External DNS.
2. Add the redirect in Program.cs
1 | using Microsoft.AspNetCore.Rewrite; |
AddRedirectToWwwPermanent ships with the framework (Microsoft.AspNetCore.Rewrite), so there is no package to add. The domain you pass is the important bit: without it every host without a www. prefix would be redirected, including my UAT *.azurecontainerapps.io host. With it, only resolv.it.com is redirected.
I read the domain from config (Environments:ProdHost is www.resolv.it.com, so I strip the www.), but a hard-coded <your-apex-domain> works just as well.
Put it before UseHttpsRedirection() so http://resolv.it.com is sorted out in the same pipeline.
Docs: URL Rewriting Middleware
3. Test it
You can fake the host with curl, no DNS needed:
1 | curl -i -H "Host: resolv.it.com" "http://localhost:5000/a/b?x=1" |
The first returns 308 Permanent Redirect with Location: http://www.resolv.it.com/a/b?x=1, so the path and query string survive. The second returns 200, so UAT is untouched.
Things to know
- The status is 308, not 301. Both are permanent and search engines treat them the same, 308 just keeps the HTTP method (a
POSTstays aPOST). - The redirect keeps the scheme of the request, so plain
http://resolv.it.comtakes two hops (tohttp://www...then up tohttps://www...via the HTTPS redirect). Only http requests to the apex pay for this. - It only works if the app sees the original
Hostheader. Azure Container Apps ingress passes it through, check withcurl -I https://resolv.it.com/after deploying. - If you would rather not do this in the app, the standard place is the edge (Front Door, Cloudflare, your registrar’s forwarding). I could not get the GoDaddy redirect working, which is why this lives in the app.