cache queries and revalidate with incremental static regeneration
This commit is contained in:
22 files changed
+381
-114
No files matched your search
@@ -8,8 +8,6 @@ import {
|
||||
} from "@/components/general/GenericPageView";
|
||||
import { getSeoMetadata } from "@/lib/seo";
|
||||
|
||||
export const dynamicParams = false;
|
||||
|
||||
function getWagtailUrlPath(url: string[]): string {
|
||||
// for the page /foo/bar we need to look for `/home/foo/bar/`
|
||||
return `/home/${url.join("/")}/`;
|
||||
|
||||
@@ -1,36 +1,14 @@
|
||||
import { Metadata, ResolvingMetadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { getClient } from "@/app/client";
|
||||
import {
|
||||
NewsPageView,
|
||||
loadNewsPageProps,
|
||||
} from "@/components/news/NewsPageView";
|
||||
import { graphql } from "@/gql";
|
||||
import { getSeoMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const allNewsSlugsQuery = graphql(`
|
||||
query allNewsSlugs {
|
||||
pages(contentType: "news.NewsPage") {
|
||||
id
|
||||
slug
|
||||
}
|
||||
}
|
||||
`);
|
||||
const { data, error } = await getClient().query(allNewsSlugsQuery, {});
|
||||
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
if (!data?.pages) {
|
||||
throw new Error(
|
||||
"Failed to generate static params for subpages of /aktuelt"
|
||||
);
|
||||
}
|
||||
|
||||
return data.pages.map((page: any) => ({
|
||||
slug: page.slug,
|
||||
}));
|
||||
// Prerender nothing at build time; render and cache on first request
|
||||
return [];
|
||||
}
|
||||
|
||||
type Params = Promise<{ slug: string }>;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { timingSafeEqual } from "node:crypto";
|
||||
import { revalidateTag } from "next/cache";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
import { CMS_CACHE_TAG } from "@/lib/revalidation";
|
||||
|
||||
function secretMatches(provided: string, expected: string): boolean {
|
||||
const a = Buffer.from(provided);
|
||||
const b = Buffer.from(expected);
|
||||
return a.length === b.length && timingSafeEqual(a, b);
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const secret = process.env.REVALIDATE_WEBHOOK_SECRET;
|
||||
if (!secret) {
|
||||
return NextResponse.json(
|
||||
{ error: "revalidation is not configured" },
|
||||
{ status: 503 }
|
||||
);
|
||||
}
|
||||
const provided = req.headers.get("x-revalidate-secret") ?? "";
|
||||
if (!secretMatches(provided, secret)) {
|
||||
return NextResponse.json({ error: "invalid secret" }, { status: 401 });
|
||||
}
|
||||
// expire: 0 purges immediately; the next request renders fresh
|
||||
revalidateTag(CMS_CACHE_TAG, { expire: 0 });
|
||||
return NextResponse.json({ revalidated: true, tag: CMS_CACHE_TAG });
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getClient } from "@/app/client";
|
||||
import { cachedUntilOsloMidnight } from "@/lib/revalidation";
|
||||
import {
|
||||
eventsOverviewQuery,
|
||||
getSingularEvents,
|
||||
@@ -45,7 +46,11 @@ export async function GET(req: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
const { data, error } = await getClient().query(eventsOverviewQuery, {});
|
||||
const { data, error } = await getClient().query(
|
||||
eventsOverviewQuery,
|
||||
{},
|
||||
cachedUntilOsloMidnight()
|
||||
);
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,14 @@
|
||||
import { Metadata, ResolvingMetadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { getClient } from "@/app/client";
|
||||
import {
|
||||
EventPageView,
|
||||
loadEventPageProps,
|
||||
} from "@/components/events/EventPageView";
|
||||
import { graphql } from "@/gql";
|
||||
import { getSeoMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const allEventSlugsQuery = graphql(`
|
||||
query allEventSlugs {
|
||||
pages(contentType: "events.EventPage") {
|
||||
id
|
||||
slug
|
||||
}
|
||||
}
|
||||
`);
|
||||
const { data, error } = await getClient().query(allEventSlugsQuery, {});
|
||||
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
if (!data?.pages) {
|
||||
throw new Error(
|
||||
"Failed to generate static params for subpages of /arrangementer"
|
||||
);
|
||||
}
|
||||
|
||||
return data.pages.map((page: any) => ({
|
||||
slug: page.slug,
|
||||
}));
|
||||
// Prerender nothing at build time; render and cache on first request
|
||||
return [];
|
||||
}
|
||||
|
||||
type Params = Promise<{ slug: string }>;
|
||||
|
||||
@@ -3,6 +3,8 @@ import "server-only";
|
||||
import { cacheExchange, createClient, fetchExchange } from "@urql/core";
|
||||
import { registerUrql } from "@urql/next/rsc";
|
||||
|
||||
import { CMS_CACHE_TAG } from "@/lib/revalidation";
|
||||
|
||||
const wagtailBaseUrl = process.env.WAGTAIL_BASE_URL;
|
||||
if (!wagtailBaseUrl) {
|
||||
throw new Error("WAGTAIL_BASE_URL is not set");
|
||||
@@ -13,8 +15,9 @@ const makeClient = () => {
|
||||
return createClient({
|
||||
url: graphqlEndpoint,
|
||||
exchanges: [cacheExchange, fetchExchange],
|
||||
// requestPolicy: "network-only",
|
||||
fetchOptions: { next: { revalidate: 0 } },
|
||||
// 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] } },
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getClient } from "@/app/client";
|
||||
import { uncached } from "@/lib/revalidation";
|
||||
import { PreviewBanner } from "@/components/general/PreviewBanner";
|
||||
import {
|
||||
AssociationIndexView,
|
||||
@@ -149,7 +150,11 @@ export default async function PreviewRender() {
|
||||
return <ExpiredPreview />;
|
||||
}
|
||||
|
||||
const { data, error } = await getClient().query(previewPageQuery, { token });
|
||||
const { data, error } = await getClient().query(
|
||||
previewPageQuery,
|
||||
{ token },
|
||||
uncached
|
||||
);
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getClient } from "@/app/client";
|
||||
import { uncached } from "@/lib/revalidation";
|
||||
import {
|
||||
type SearchResult,
|
||||
SearchResults,
|
||||
@@ -65,7 +66,7 @@ export default async function Page({
|
||||
}
|
||||
`);
|
||||
|
||||
const { data } = await getClient().query(searchQuery, { query });
|
||||
const { data } = await getClient().query(searchQuery, { query }, uncached);
|
||||
const all = (data?.results ?? []) as SearchResult[];
|
||||
totalCount = all.length;
|
||||
results = all.slice(0, RESULT_LIMIT);
|
||||
|
||||
Reference in new issue
Block a user