After a successful deploy, I run a curl command to see the headers. I am also checking the headers in Postman and in my browser developer tools. This is what I see:
I don’t see any of my top-level /* header rules applied. When I curl assets in the /_next/static/* subdirectory, I do see some header rules applied, like my cache-control header, but a seemingly different strict-transport-security header value.
I am using Next.js as an SSG, so I don’t currently use the Next.js runtime. I don’t think the Next.js middleware solution will resolve my issues. Shouldn’t Netlify _headers apply regardless of using a framework middleware?
Interesting discovery, not sure what to do about it. The _headers rules work at the Netlify subdomain: https://development--chimerical-basbousa-4d9dac.netlify.app/
Is this documented anywhere? How can I verify that my _headers rules are going to work on the primary domain if I can’t test them in a branch with a similar deploy context?
development--chimerical-basbousa-4d9dac.netlify.app and development.playco.org are not serving the same content.
For instance /_next/static/chunks/main-1f3a77ac1a40912e.js exists on the Netlify branch deploy
$ curl -I https://development--chimerical-basbousa-4d9dac.netlify.app/_next/static/chunks/main-1f3a77ac1a40912e.js
HTTP/2 200
# Rest of output
but not on the custom subdomain
$ curl -I https://development.playco.org/_next/static/chunks/main-1f3a77ac1a40912e.js
HTTP/2 404
# Rest of output
The difference in content is evident in the output you posted in the Content-Length
vs
You can also see the content is different in the browser by looking at the Network tab of Developer Tools and seeing the files that are requests (e.g. main-1f3a77ac1a40912e.js vs main-77f242bcb709711e.js)
So what’s going on here? Why are they not serving the same code? I have a CNAME pointing to the development branch, and when I run dig they seem like they should be getting served the same content?
$ dig development--chimerical-basbousa-4d9dac.netlify.app.
; <<>> DiG 9.10.6 <<>> development--chimerical-basbousa-4d9dac.netlify.app.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4763
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;development--chimerical-basbousa-4d9dac.netlify.app. IN A
;; ANSWER SECTION:
development--chimerical-basbousa-4d9dac.netlify.app. 20 IN A 52.9.166.110
development--chimerical-basbousa-4d9dac.netlify.app. 20 IN A 50.18.215.94
;; Query time: 25 msec
;; SERVER: 192.168.0.35#53(192.168.0.35)
;; WHEN: Fri May 24 18:03:29 PDT 2024
;; MSG SIZE rcvd: 112
$ dig development.playco.org
; <<>> DiG 9.10.6 <<>> development.playco.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10502
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;development.playco.org. IN A
;; ANSWER SECTION:
development.playco.org. 300 IN CNAME development--chimerical-basbousa-4d9dac.netlify.app.
development--chimerical-basbousa-4d9dac.netlify.app. 20 IN A 50.18.142.31
development--chimerical-basbousa-4d9dac.netlify.app. 20 IN A 13.57.148.141
;; Query time: 90 msec
;; SERVER: 192.168.0.35#53(192.168.0.35)
;; WHEN: Fri May 24 18:04:00 PDT 2024
;; MSG SIZE rcvd: 148
Why is it doing this? Because using branch subdomains is a feature of Netlify DNS. If you wish to use branch subdomains without using Netlify DNS read the following support guide
Custom headers apply only to files Netlify serves from our own backing store. If you are proxying content to your site or dealing with a URL handled by a function or edge function such as a server-side rendered (SSR) page, custom headers won’t be applied to that content. In those cases, the site being proxied to or the function should return any required headers instead. Visit our docs on edge functions to learn how to configure cache-control headers for edge functions.
Regarding the missing headers, I think @dig has advised correctly.
Thanks for all the help! For some reason I had created an alias pointing the development subdomain to the primary URL.
I had correctly set up my external CNAME DNS (through Cloudflare) to point to the Netlify deploy subdomain. Misunderstanding and misconfiguration on my part between what I expected to happen and what Netlify does. Removing the alias fixed everything immediately.
I’m still not totally sure why the domain alias from the Netlify admin slurped up the traffic that should have been going to the netlify.app subdomain, but I don’t really need to know!
I misspoke — what I meant was shouldn’t the Netlify headers apply to files generated by a framework? Even if you’re also using framework middleware for other headers?
If I use Next.js and deploy to Netlify, I’d expect the the _headers file would work in addition to using the Next.js’s headers middleware convention. I do think there’d be some weirdness doing the same thing in 2 different places. Maybe I’ll deploy some tester website to experiment.