Make a Webflow site a full progressive web app
Webflow is the closest of the hosted builders to a proper PWA. Head code is a checkbox; the only gap is serving sw.js from your domain root, and there are two solid ways to close it. Once it's closed you get offline pages, push and a Google Play listing as a Trusted Web Activity.
What Webflow allows
| Question | Answer |
|---|---|
| Head code | Yes — Site settings → Custom code, on paid site plans. |
| Upload sw.js to yoursite.com/sw.js | Not directly. Asset uploads go to Webflow's CDN (cdn.prod.website-files.com), which is a different origin. |
| Same-origin manifest | Same limitation — but a cross-origin manifest with CORS works for installation. |
| Route A: proxy | Put a Cloudflare Worker (or any edge function) in front of your domain to serve /sw.js, /manifest.json and /offline.html while passing everything else to Webflow. |
| Route B: Webflow Cloud | Deploy a small app on Webflow Cloud mounted at a path, and serve the files from there. Newer, Webflow-native. |
| Result | Full PWA: install prompt, offline page, web push, and TWA for Google Play. |
Manifest and head code (both routes)
Generate the files with the builder. Upload the icons/ PNGs as Webflow assets and update the icon src values in manifest.json to the CDN URLs (cross-origin icons are fine). Then in Site settings → Custom code → Head:
<link rel="manifest" href="/manifest.json">
<link rel="apple-touch-icon" href="https://cdn.prod.website-files.com/…/icon-192x192.png">
<meta name="theme-color" content="#4F46E5">
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => navigator.serviceWorker.register('/sw.js'));
}
</script>Route A: a Cloudflare Worker serving the root files
Point your domain's DNS at Cloudflare (free plan is enough), keep the CNAME to Webflow, and add a Worker on the routes yoursite.com/sw.js, yoursite.com/manifest.json and yoursite.com/offline.html. The Worker returns the file contents with the right Content-Type; every other request never touches the Worker. Paste the generated files as strings, or bind them from KV. Set Cache-Control: max-age=0 on sw.js so updates propagate.
export default {
async fetch(request) {
const { pathname } = new URL(request.url);
const files = {
'/sw.js': [SW_SOURCE, 'application/javascript'],
'/manifest.json': [MANIFEST, 'application/manifest+json'],
'/offline.html': [OFFLINE, 'text/html; charset=utf-8'],
};
const hit = files[pathname];
if (!hit) return fetch(request); // everything else → Webflow
return new Response(hit[0], { headers: { 'content-type': hit[1], 'cache-control': 'max-age=0' } });
}
};This is a few lines, costs nothing at Webflow-site traffic levels, and is entirely reversible.
Route B: Webflow Cloud
Webflow Cloud lets you deploy a framework app to a mount path on your Webflow site. Mounting at / is not what you want (it would replace the site); instead mount at a path and configure a rewrite so /sw.js resolves to the app. Check Webflow's current docs for the rewrite mechanism — it has changed since launch. If that sentence made you hesitate, Route A is simpler.
Caching mode for Webflow sites
Webflow sites are static HTML with CMS content baked in at publish time, which makes them ideal for the Balanced mode: assets from cache, HTML from the network with the cached copy as fallback. Marketing sites that change weekly can use Aggressive. Avoid caching /api/ or form endpoints if you use Webflow forms or Logic.
From PWA to Google Play
With a real manifest and service worker in place, your Webflow site qualifies for a Trusted Web Activity: tick the Android option in the builder, host the generated assetlinks.json under /.well-known/ (add it to the Worker's file map), and follow the TWA checklist.
Frequently asked questions
Does Webflow's built-in "PWA" setting exist?
No. Webflow offers favicons and a webclip icon, which cover the Apple touch icon, but there is no manifest or service worker feature.
Will the Cloudflare proxy slow the site down?
No measurable effect. The Worker only runs for three paths; Webflow's own CDN serves everything else as before.
Does the CMS content update in the installed app?
Yes — the service worker fetches HTML from the network in Balanced mode. After you publish in Webflow, users see the new content on their next open; in Aggressive mode, within the refresh window.
Can I skip the proxy and still get installs?
Yes: a cross-origin manifest linked from head code gives add-to-home-screen on both platforms. You lose offline behaviour and push, and you cannot do a TWA.