File-based headers

Type

Product improvement

Description

Fine control over headers for Cloudflare Pages

Benefit

Fine-grained and correct control over headers for sites using Cloudflare Pages. Currently, Pages supports setting custom headers using paths and the _headers file. While this works reasonably well, it is from the perspective of the request being made, which means that it’s an imperfect solution to return headers in certain situations.

For example, let’s say that I want all JavaScript files to be cached. I could write a rule like:

/*.js
  cache-control: public, max-age=12345, immutable

However, the problem with this rule is that it’ll match all paths that end in *.js, even if that path doesn’t exist.

Similarly, let’s say that I want to define a custom content-type for files with the .example extension:

/*.example
  content-type: example/example

Again, a request to https://example.com/doesnotexist.example will say that the content-type is example/example, even though the actual response could be HTML.

I think that this could easily be addressed in two ways (or both ways):

  1. Add an optional parameter to the rule, to mean that it should only apply for successful responses.
  2. Allow a per-file headers file to be used to define that file’s headers.

Option 1: Optional parameter

That could look something like this:

/*.example [ok]
  content-type: example/example

In this case, the header is applied only for successful responses, instead of the default behaviour of applying to the request.

Option 2: Per-file headers

This option is the most powerful and I believe that it could be implemented with minimal overhead (as it’s only one additional file to read). For example, the file example.example could have an example.example:_headers file, which in this case would have a single line with content-type: example/example.

Conclusion

I know that this could easily be done using Workers or Functions. However, I also think that this is a common enough use-case that would benefit from not having to do this, since things can be defined declaratively.