Single-page applications like ReactJS are pretty popular, and you can get them to work with static sites too. But because the JAMstack is serverless, you'll need to do a few URL rewrites to keep your SPA routes working and avoid the dreaded "404 - Page Not Found" error.
Here's how I set things up on Cloudflare Pages.
If your whole static site is a SPA
If your entire Cloudflare Pages static site is a SPA, you are good to go out of the box. Seriously, you are done - there's no need to go any further!
If you've put a ReactJS app or another SPA on Netlify before, you will probably have done something like this in your
/* /index.html 200
This is a documented rewrite rule for handling single-page apps in Netlify.
But you don't need this rule in Cloudflare Pages.
That's pretty cool if your whole website is a SPA. Nothing to do, just deploy your site as-is. But what if it's not?
The beauty of the rewrite rule in Netlify is that your entire site doesn't need to be a SPA for it to work. And that's not the case for Cloudflare Pages (yet).
If part of your static site is a SPA
Let's imagine you have a website with a bunch of static pages, and a ReactJS app running from app.html.
├── css/ 📁 ├── js/ 📁 ├── about.html 📄 ├── app.html 📄 <--- SPA ├── contact.html 📄 ├── index.html 📄 └── pricing.html 📄
If you visit
/app and start navigating around your ReactJS application, you might be fooled into thinking everything is working.
🚨 News flash - it isn't.
If you hit refresh in your browser on a client-side route, like
/app/dashboard, you'll get a "404 - Page Not Found" error.
So what's happening?
Well when you go to
/app, your ReactJS (or other SPA) loads up and takes care of the routing. But when you hit refresh, the static site tries to find
/app/dashboard.html- and that doesn't exist as a static page.
You need to pass that URL request back to
app.html (your SPA) to handle it.
Remember that rewrite rule we created earlier in
_redirects? We need another version of that!
You can create a rewrite proxy so that any routes starting with
/app/register etc) get shown
app.html so that React Router (or your other front-end router of choice) can handle the routing.
/app/* /app.html 200
And this works... in Netlify.
But we're not talking about Netlify today, we are supposed to be talking about Cloudflare Pages.
And this should work in Cloudflare too. And it will do soon - according to the docs. So if you're reading this blog a few weeks/month in the future, by all means, give it a go!
For a while, Cloudflare Pages
_redirects didn’t support proxying. And while it does now (according to the docs), at the time of writing this post - it wasn't working in production yet. At least, not with dynamic routes. So I couldn't handle a partial SPA static site in Cloudflare Pages
That doesn't mean you can't get a partial SPA to work in Cloudflare, you absolutely can. And here's how...
SPA routing with transform rules
Until the rewrites start working in Cloudflare Pages (which should be soon), you can use transform rules to handle the rewrite instead.
Cloudflare has some pretty flexible route handling, and URL rewrite is exactly what we need.
Don't worry if you are on the free plan, you get 10 transform rules included, and you are only going to need to use one to get this to work!
Here's what you need to do:
- In Cloudflare, head to Rules > Transform Rules
- Click Create rule
- Create the transform rule
☑️ Custom filter expression
☑️ Rewrite to...
This would be if your ReactJS/SPA is at the route
/app in your static site. If it's somewhere else, like
user in the settings above.
Ta-da! Now your SPA works on Cloudflare Pages.