Skip to content

Commit c78fecd

Browse files
authored
[admin] only set no-store for nextjs 13 and 14 (#1056)
1 parent c13fbbe commit c78fecd

File tree

2 files changed

+26
-23
lines changed
  • client
    • packages/admin/src
    • sandbox/react-nextjs/app/play/check-admin-cache

2 files changed

+26
-23
lines changed

client/packages/admin/src/index.ts

+19-18
Original file line numberDiff line numberDiff line change
@@ -139,38 +139,39 @@ function authorizedHeaders(
139139
: headers;
140140
}
141141

142-
function isCloudflareWorkerRuntime() {
142+
// NextJS 13 and 14 cache fetch requests by default.
143+
//
144+
// Since adminDB.query uses fetch, this means that it would also cache by default.
145+
//
146+
// We don't want this behavior. `adminDB.query` should return the latest result by default.
147+
//
148+
// To get around this, we set an explicit `cache` header for NextJS 13 and 14.
149+
// This is no longer needed in NextJS 15 onwards, as the default is `no-store` again.
150+
// Once NextJS 13 and 14 are no longer common, we can remove this code.
151+
function isNextJSVersionThatCachesFetchByDefault() {
143152
return (
144-
// @ts-ignore
145-
typeof WebSocketPair !== 'undefined' ||
146-
// @ts-ignore
147-
(typeof navigator !== 'undefined' &&
148-
navigator.userAgent === 'Cloudflare-Workers') ||
149-
// @ts-ignore
150-
(typeof EdgeRuntime !== 'undefined' && EdgeRuntime === 'vercel')
153+
// NextJS 13 onwards added a `__nextPatched` property to the fetch function
154+
fetch['__nextPatched'] &&
155+
// NextJS 15 onwards _also_ added a global `next-patch` symbol.
156+
!globalThis[Symbol.for('next-patch')]
151157
);
152158
}
153159

154-
// (XXX): Cloudflare Workers don't support cache: "no-store"
155-
// We need to set `cache: "no-store"` so Next.js doesn't cache the fetch
156-
// To keep Cloudflare Workers working, we need to conditionally set the fetch options
157-
// Once Cloudflare Workers support `cache: "no-store"`, we can remove this conditional
158-
// https://github.com/cloudflare/workerd/issues/698
159-
160-
const FETCH_OPTS: RequestInit = isCloudflareWorkerRuntime()
161-
? {}
162-
: { cache: 'no-store' };
160+
function getDefaultFetchOpts(): RequestInit {
161+
return isNextJSVersionThatCachesFetchByDefault() ? { cache: 'no-store' } : {};
162+
}
163163

164164
async function jsonFetch(
165165
input: RequestInfo,
166166
init: RequestInit | undefined,
167167
): Promise<any> {
168+
const defaultFetchOpts = getDefaultFetchOpts();
168169
const headers = {
169170
...(init.headers || {}),
170171
'Instant-Admin-Version': version,
171172
'Instant-Core-Version': coreVersion,
172173
};
173-
const res = await fetch(input, { ...FETCH_OPTS, ...init, headers });
174+
const res = await fetch(input, { ...defaultFetchOpts, ...init, headers });
174175
const json = await res.json();
175176
return res.status === 200
176177
? Promise.resolve(json)

client/sandbox/react-nextjs/app/play/check-admin-cache/page.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { init } from '@instantdb/admin';
2-
const APP_ID = '137ace7a-efdd-490f-b0dc-a3c73a14f892';
3-
const ADMIN_TOKEN = '82900c15-faac-495b-b385-9f9e7743b629';
2+
3+
import config from '../../../config';
4+
45
const db = init({
5-
appId: APP_ID,
6-
adminToken: ADMIN_TOKEN,
7-
apiURI: 'http://localhost:8888',
6+
...config,
7+
adminToken: process.env.INSTANT_ADMIN_TOKEN!,
88
});
99

10+
export const dynamic = 'force-dynamic';
11+
1012
export default async function Page() {
1113
const query = await db.query({
1214
goals: {},

0 commit comments

Comments
 (0)