From 67d629f72219b72936127bd12ae7721c4e7a33bb Mon Sep 17 00:00:00 2001 From: Rosa Gutierrez Date: Fri, 20 Feb 2026 20:48:01 +0100 Subject: [PATCH] Use CORS fetch mode for Active Storage to enable `maxEntrySize` checks Otherwise, for resources like images loaded via tags, the browser sets `mode: "no-cors"` (as these aren't CORS requests), so the service worker gets an opaque response even though the server sends CORS headers. We could upgrade all no-cors requests to cors mode, sending a `mode: "cors"` request to a server that doesn't send CORS headers will fail entirely: the `fetch` call throws a `TypeError` (network error), and the browser blocks the response. So the resource wouldn't load at all, not even as opaque. We wouldn't be able to cache it at all. By opting in via `fetchOptions`, we can do it only for rules where we know the server will send CORS headers. --- Gemfile.lock | 2 +- Gemfile.saas.lock | 2 +- app/views/pwa/service_worker.js.erb | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8a49b38a5..e811a1c2f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,7 +13,7 @@ GIT GIT remote: https://github.com/hotwired/turbo-rails.git - revision: 4104a353cfe728232dc0eed6d54c77466a9849f2 + revision: 43bc205155b0eb57e5e016ed0e87a12c29ba2ab2 branch: offline-cache specs: turbo-rails (2.0.23) diff --git a/Gemfile.saas.lock b/Gemfile.saas.lock index 751dc55fb..af3c102c1 100644 --- a/Gemfile.saas.lock +++ b/Gemfile.saas.lock @@ -62,7 +62,7 @@ GIT GIT remote: https://github.com/hotwired/turbo-rails.git - revision: 4104a353cfe728232dc0eed6d54c77466a9849f2 + revision: 43bc205155b0eb57e5e016ed0e87a12c29ba2ab2 branch: offline-cache specs: turbo-rails (2.0.23) diff --git a/app/views/pwa/service_worker.js.erb b/app/views/pwa/service_worker.js.erb index 095595f4e..5ab493e22 100644 --- a/app/views/pwa/service_worker.js.erb +++ b/app/views/pwa/service_worker.js.erb @@ -42,7 +42,8 @@ TurboOffline.addRule({ maxAge: 60 * 60 * 24 * 7, networkTimeout: 2, maxEntrySize: 2 * 1024 * 1024, // 2MB covers about 95% of all Fizzy blobs - maxEntries: 500 + maxEntries: 500, + fetchOptions: { mode: "cors", credentials: "omit" } }) })