Cloudflare Pages - more configuration, less unchangeable opinionated defaults

Cloudflare Pages is a great solution for hosting websites and web apps quickly and easily. However, it suffers from two key issues today in my opinion:

  1. Unchangeable opinionated defaults

I’ll cover some of these in more detail shortly, but there are many defaults in Pages that are highly opinionated, and they can not be changed. I do not think opionated defaults themselves are problematic, but it’s when they can not be changed and users are left to struggle to make their apps work for one specific platform (Pages), instead of just being able to build their site, that it becomes a real problem.

  1. Lack of configuration options

This pairs with the item above, but also extends to other things that Pages’ competitors are eating Pages lunch on right now. SPA behaviour, trailing slashes, etc. This is made so especially problematic when new features or changes are rolled out to existing projects that can have dramatic, unknown, or even subtle and nuanced behavioural differences from before the update. Whenever there’s even a chance that an update will impact just ONE project, it should be made opt-in.

Some examples of opinionated defaults include:

  • Trailing slashes on paths. This one honestly feels like a bug to me. Trailing slashes really don’t seem to be the norm across the web, so let me configure my site how I’d like it. This is especially problematic for anyone wanting to migrate to Pages, because while you can of course setup redirects from the old URLs, you’re almost always going to incur some kind of SEO hit for a period of time.

    • No real workaround exists today.
  • SPA behaviour. The logic behind how Pages serves an index.html vs a 404.html confuses people all the time. It’s documented at Serving Pages · Cloudflare Pages docs, but should be user configurable. This is another barrier to entry and often, folks have to make changes to specifically to make their websites work on Pages, vs any other competitor.

    • No real workaround exists today outside of handling every request yourself manually via a Function.
  • Link header rewriting. This is a relatively new one, but Pages is now rewriting any link preload/preconnect tags in the HTML to Link headers. While in theory this could be great, and allows for Early Hints to do its magic, it can also cause weird behaviour when combined with media, crossorigin, fetchpriority, etc. and any number of additions to this specification in future. It should be opt-in, ESPECIALLY for existing projects.

    • One workaround is to write a Function to remove the Link header, or (once an update lands), add ! Link to _headers for where you want this removed. This makes it the user’s problem though, and should really just be configurable.
  • Default headers
    Headers like access-control-allow-origin: * and referrer-policy: strict-origin-when-cross-origin are automatically applied to all pages and assets for Pages projects. Why? Some people might not want this for their own security reasons, or just personal preference.

    • Once again the workaround here is via _headers or a Function to manually remove the headers - making it the user’s problem.

A fundamental principal when deploying to a cloud platform today is that you should be able to deploy something, and it basically never changes and runs forever. I’m not sure the same can be said for Pages today, and is why I’ve seen a lot of folks recently simply use another platform where their site works first time, or where they can configure things to their liking.

100% agree with everything. For SPA behavior I’d love to see some toggles such as:

  • Enable SPA mode
    This would allow us to configure if the app is SPA or not, instead of relying on whether there is 404.html in the root.
  • Return the closest index.html for 404 requests.
    Many frameworks such as GatsbyJS do code splitting on paths. Here’s an example, user visits /blogs/123 but at this time Pages will return /index.html from the root. Instead it should return the closest index.html which is /blogs/index.html.
    Perhaps this can be a radio select of several options:
    o Return the closest index.html
    o Return index.html from the root
    o Return the closest 404.html
    o Return 404.html from the root

Currently other cloud providers such as AWS handle this with “Custom error response”, where one can configure the behavior for 404, etc.


Removing .html extensions from URLs. This should be optional and off by default.


I agree that it would be nice to have support for URLS without trailing slashes.

Specifically, if /contact/index.html exists, then I would appreciate being able to have /contactdirectly serve the content from /contact/index.html, rather than redirecting the user to /contact/.


This feature is very important to me. Web crawlers are having issues with this and sometimes not indexing pages due to this automatic redirect! I would really like to this an option to turn this trailing slash off

1 Like

@cherryjimbo can I ask you to clarify what you mean by “No real workaround exists today.” I’ve been searching the forums to fix this trailing slash issue, but answers seem to be outdated or the platform has changed. Either way I’m not clear what would be the best way to tackle this atm. I 100% agree of course, that this shoudn’t be the default or at least very easy to change.

There’s not really a good solution for this unfortunately.

I’ve seen people come up with solutions like juggling their output to page.html instead of page/index.html like at Why We Switched CDNs: How Google's Core Web Vitals Led Us to Cloudflare Pages - Electric UI, but otherwise you don’t really have a choice but to deal with trailing slashes right now.

1 Like