Skip to content

Clarify header merging and overwrites in firebase.json #9467

@rscotten

Description

@rscotten

As far as I can tell, the Firebase Hosting documentation does not specify how headers are merged and overwritten in firebase.json. I'm referring to these documentation pages:

https://firebase.google.com/docs/hosting/full-config#headers
https://firebase.google.com/docs/hosting/manage-cache
https://firebase.google.com/docs/hosting/frameworks/nextjs

The docs make it clear that the rewrite rules and redirects use a "first rule wins" matching strategy.

But this "first rule wins" strategy does not appear to be used with the header rules. Rather, Firebase Hosting appears to adopt a "last rule wins" strategy, and if so, that's a pretty serious gotcha / footgun and should be clarified in the documentation.

Here's my firebase.json file for my NextJS web app that is statically generated using their SSG rendering strategy.

{
  "hosting": [
    {
      ...,
      "headers": [
        {
          "source": "/**",
          "headers": [
            { "key": "Cache-Control", "value": "no-cache, must-revalidate" }
          ]
        },
        {
          "source": "/_next/static/**",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "public, max-age=31536000, immutable"
            }
          ]
        },
        {
          "source": "/_next/static/BUILD_ID",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "no-cache, must-revalidate"
            }
          ]
        }
      ]
    }
  ]
}

In this case, I get the caching values that I expect, where all everything is not cached (first rule), except for all static files in /_next/static/** which has a one year cache, except the /_next/static/BUILD_ID" file, which is not cached.

In adopting the reverse order (where the source "/**" is the last rule), all files get the "no-cache, must-revalidate" value, even the "/_next/static/**" files.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions