web: adopt Cache Components, Partial Prefetching and ensureStatic
web / ci (push) Successful in 2m2s

This commit is contained in:
ponas committed 2026-10-13 23:59:14 +02:00
1 parent 3a0c2fd82b
commit db286434ba
70 files changed
+1285 -316

No files matched your search

+52 -5
View File
@@ -1,9 +1,16 @@
import "server-only";
import { cacheExchange, createClient, fetchExchange } from "@urql/core";
import {
type AnyVariables,
type TypedDocumentNode,
cacheExchange,
createClient,
fetchExchange,
stringifyDocument,
} from "@urql/core";
import { registerUrql } from "@urql/next/rsc";
import { CMS_CACHE_TAG } from "@/lib/revalidation";
import { cmsCache, cmsCacheForToday } from "@/lib/cmsCache";
const wagtailBaseUrl = process.env.WAGTAIL_BASE_URL;
if (!wagtailBaseUrl) {
@@ -15,10 +22,50 @@ const makeClient = () => {
return createClient({
url: graphqlEndpoint,
exchanges: [cacheExchange, fetchExchange],
// Cache all queries in the Data Cache until revalidateTag(CMS_CACHE_TAG);
// override per operation with the contexts in @/lib/revalidation
fetchOptions: { cache: "force-cache", next: { tags: [CMS_CACHE_TAG] } },
});
};
// Uncached. Only for per-user (search) and token-scoped (preview) queries,
// together with the `uncached` context; everything else goes through cmsQuery
export const { getClient } = registerUrql(makeClient);
// Throws on GraphQL and network errors, which keeps them out of the cache
async function runQuery(query: string, variables: AnyVariables) {
const { data, error } = await getClient().query(query, variables);
if (error) throw new Error(error.message);
return data;
}
// The cached functions take the query as text: their arguments are the cache
// key, and urql adds bookkeeping properties to document objects it has seen
async function cachedQuery(query: string, variables: AnyVariables) {
"use cache";
cmsCache();
return runQuery(query, variables);
}
async function cachedQueryForToday(query: string, variables: AnyVariables) {
"use cache";
cmsCacheForToday();
return runQuery(query, variables);
}
// Every cacheable CMS read goes through one of the two functions below, so
// all of them carry the tag the CMS webhook purges
// Cached until the content is edited in the CMS
export function cmsQuery<Data, Variables extends AnyVariables>(
document: TypedDocumentNode<Data, Variables>,
variables: Variables
): Promise<Data | undefined> {
return cachedQuery(stringifyDocument(document), variables);
}
// For queries where the CMS decides by today's date what to return
// (futureEvents): also purged at Oslo midnight
export function cmsQueryForToday<Data, Variables extends AnyVariables>(
document: TypedDocumentNode<Data, Variables>,
variables: Variables
): Promise<Data | undefined> {
return cachedQueryForToday(stringifyDocument(document), variables);
}