Skip to content

Commit ff3b25b

Browse files
committed
feat(getPayloadSession): Cache getPayloadSession function
1 parent 6008b7f commit ff3b25b

File tree

2 files changed

+50
-25
lines changed

2 files changed

+50
-25
lines changed

packages/dev/src/app/components/auth/payload/PayloadSessionServer.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { revalidateTag } from "next/cache";
12
import { getPayloadSession } from "payload-authjs";
23
import Badge from "../../general/Badge";
34

@@ -10,7 +11,19 @@ export const PayloadSessionServer = async () => {
1011
<Badge variant={session ? "green" : "red"}>
1112
status: {session ? "authenticated" : "unauthenticated"}
1213
</Badge>
13-
{session?.expires && <Badge>Expires: {new Date(session.expires).toLocaleString()}</Badge>}
14+
{session?.expires && (
15+
<Badge
16+
onClick={async () => {
17+
"use server";
18+
19+
revalidateTag("payload-session");
20+
21+
return Promise.resolve();
22+
}}
23+
>
24+
Expires: {new Date(session.expires).toLocaleString()}
25+
</Badge>
26+
)}
1427
</div>
1528
<pre className="overflow-auto rounded-lg bg-gray-100 p-4">
1629
{JSON.stringify(session?.user ?? null, null, 2)}

packages/payload-authjs/src/payload/session/getPayloadSession.ts

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { cookies, headers } from "next/headers";
1+
import { headers } from "next/headers";
22
import type { CollectionSlug, DataFromCollectionSlug } from "payload";
3+
import { cache } from "react";
34

45
interface Options<TSlug extends CollectionSlug> {
56
/**
@@ -16,33 +17,44 @@ export interface PayloadSession<TSlug extends CollectionSlug> {
1617
}
1718

1819
/**
19-
* Get the payload session from the server side
20+
* Get the payload session from the server-side
21+
*
22+
* This function is cached to de-duplicate requests:
23+
* - using React 'cache' function to memorize within the same request (@see https://react.dev/reference/react/cache)
24+
* - and using Next.js 'data cache' to cache across multiple requests (@see https://nextjs.org/docs/app/building-your-application/caching#data-cache)
25+
*
26+
* You can manually invalidate the cache by calling `revalidateTag("payload-session")`
2027
*/
21-
export const getPayloadSession = async <TSlug extends CollectionSlug = "users">({
22-
userCollectionSlug = "users" as TSlug,
23-
}: Options<TSlug> = {}): Promise<PayloadSession<TSlug> | null> => {
24-
// Get the server URL
25-
const serverUrl = await getServerUrl();
28+
export const getPayloadSession = cache(
29+
async <TSlug extends CollectionSlug = "users">({
30+
userCollectionSlug = "users" as TSlug,
31+
}: Options<TSlug> = {}): Promise<PayloadSession<TSlug> | null> => {
32+
// Get the server URL
33+
const serverUrl = await getServerUrl();
2634

27-
// Fetch the session from the server
28-
const response = await fetch(`${serverUrl}/api/${userCollectionSlug}/me`, {
29-
headers: {
30-
Cookie: (await cookies()).toString(),
31-
},
32-
});
33-
const result: { user: DataFromCollectionSlug<TSlug>; exp: number } = await response.json();
35+
// Fetch the session from the server
36+
const response = await fetch(`${serverUrl}/api/${userCollectionSlug}/me`, {
37+
headers: await headers(),
38+
cache: "force-cache",
39+
next: {
40+
tags: ["payload-session"],
41+
},
42+
});
43+
const result: { user: DataFromCollectionSlug<TSlug> | null; exp: number } =
44+
await response.json();
3445

35-
// If the response is not ok or the user is not present, return null
36-
if (!response.ok || !result.user) {
37-
return null;
38-
}
46+
// If the response is not ok or the user is not present, return null
47+
if (!response.ok || !result.user) {
48+
return null;
49+
}
3950

40-
// Return the session
41-
return {
42-
user: result.user,
43-
expires: new Date(result.exp * 1000).toISOString(),
44-
};
45-
};
51+
// Return the session
52+
return {
53+
user: result.user,
54+
expires: new Date(result.exp * 1000).toISOString(),
55+
};
56+
},
57+
);
4658

4759
/**
4860
* Get the server URL from the environment variables or the request headers

0 commit comments

Comments
 (0)