Skip to content

Commit db14e4b

Browse files
authored
feat: add short-lived cache for prefetch requests (#46)
which avoids a second request when loading the prefetched route data on actual navigation. This should speed up the UI quite a bit because one request is better than two requests, haha :D Fixes #39 ## Type of change Please mark relevant options with an `x` in the brackets. - [x] New feature (non-breaking change which adds functionality) # How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration - [x] Manual tests
1 parent 5dde691 commit db14e4b

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

app/entry.server.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createInstance } from "i18next"
44
import { isbot } from "isbot"
55
import { renderToPipeableStream } from "react-dom/server"
66
import { I18nextProvider, initReactI18next } from "react-i18next"
7-
import { type AppLoadContext, type EntryContext, ServerRouter } from "react-router"
7+
import { type AppLoadContext, type EntryContext, type HandleDataRequestFunction, ServerRouter } from "react-router"
88
import i18n from "./localization/i18n" // your i18n configuration file
99
import i18nextOpts from "./localization/i18n.server"
1010
import { resources } from "./localization/resource"
@@ -71,3 +71,27 @@ export default async function handleRequest(
7171
setTimeout(abort, streamTimeout + 1000)
7272
})
7373
}
74+
75+
/**
76+
* This adds a cache header to the response for prefetch requests
77+
* to avoid double requests as suggested here:
78+
* https://sergiodxa.com/tutorials/fix-double-data-request-when-prefetching-in-remix
79+
*/
80+
export const handleDataRequest: HandleDataRequestFunction = async (response: Response, { request }) => {
81+
const isGet = request.method.toLowerCase() === "get"
82+
const purpose =
83+
request.headers.get("Purpose") ||
84+
request.headers.get("X-Purpose") ||
85+
request.headers.get("Sec-Purpose") ||
86+
request.headers.get("Sec-Fetch-Purpose") ||
87+
request.headers.get("Moz-Purpose")
88+
const isPrefetch = purpose === "prefetch"
89+
90+
// If it's a GET request and it's a prefetch request and it doesn't have a Cache-Control header
91+
if (isGet && isPrefetch && !response.headers.has("Cache-Control")) {
92+
// we will cache for 10 seconds only on the browser
93+
response.headers.set("Cache-Control", "private, max-age=10")
94+
}
95+
96+
return response
97+
}

0 commit comments

Comments
 (0)