Skip to content

Commit df142d9

Browse files
authored
[Website] Fix Safari loading stale index.html after deployments (#3208)
## Summary Safari doesn't respect `cache: 'no-cache'` the same way Chrome and Firefox do. When fetching /index.html with no-cache, Safari would still serve the response from its HTTP cache. This caused problems after new Playground deployments—the stale cached index.html contained references to assets that no longer existed on the server, breaking the site. This PR switches to `cache: 'no-store'` in all fetch operations, which makes Safari behave consistently with other browsers by always going to the network without checking the HTTP cache first. ## Changes - Replace `cache: 'no-cache'` with `cache: 'no-store'` in `networkFirstFetch()` - Apply the same fix to `cacheOfflineModeAssetsForCurrentRelease()` and `fetchFresh()` - Add detailed comment explaining the Safari-specific behavior and why no-store is required ## Test plan - [ ] Deploy to staging and verify Safari loads the latest version after deployment - [ ] Test that offline mode still works correctly in Safari - [ ] Verify behavior is unchanged in Chrome and Firefox
1 parent bc5007b commit df142d9

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

packages/playground/remote/src/lib/offline-mode-cache.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,22 @@ export async function networkFirstFetch(request: Request): Promise<Response> {
6060

6161
let response: Response | undefined = undefined;
6262
try {
63+
/**
64+
* Only use either `no-store` or `reload` here or else Playground won't
65+
* load in Safari after a new version is deployed.
66+
*
67+
* Initially, we used `no-cache` here:
68+
* * Chrome and Firefox did not source the /index.html file from the HTTP cache.
69+
* * Safari still sourced the /index.html file from the HTTP cache.
70+
*
71+
* After a new Playground deployment, the stale cached index.html contained
72+
* references to assets that were no longer available on the server.
73+
*
74+
* The `cache: no-store` option actually makes Safari behave as expected, that is
75+
* go to the network without loading the stale HTTP cache response.
76+
*/
6377
response = await fetch(request, {
64-
cache: 'no-cache',
78+
cache: 'no-store',
6579
});
6680
} catch (e) {
6781
if (cachedResponse) {
@@ -108,7 +122,11 @@ export async function cacheOfflineModeAssetsForCurrentRelease(): Promise<any> {
108122
*
109123
* See service-worker.ts for more details.
110124
*/
111-
(url: string) => new Request(url, { cache: 'no-cache' })
125+
(url: string) =>
126+
new Request(url, {
127+
// Do not use no-cache here. See the comment in networkFirstFetch() for more details.
128+
cache: 'no-store',
129+
})
112130
);
113131
const offlineModeCache = await promisedOfflineModeCache;
114132
await offlineModeCache.addAll(websiteRequests);
@@ -216,7 +234,8 @@ function stripRangeHeader(request: Request): Request {
216234
function fetchFresh(resource: RequestInfo | URL, init?: RequestInit) {
217235
return fetch(resource, {
218236
...init,
219-
cache: 'no-cache',
237+
// Do not use no-cache here. See the comment in networkFirstFetch() for more details.
238+
cache: 'no-store',
220239
});
221240
}
222241

0 commit comments

Comments
 (0)