Clarification needed on `unstable_update` and required adapter methods
What is the improvement or update you wish to see?
I'm trying to use the unstable_update method. And despite appearing on the documentation, it has 0 information on how it's used.
Is there any context that might help us understand?
I tried:
const newSession = await unstable_update({
user: { username: newUsername },
});
But it does not update the session.
Since I'm using a custom adapter I thought that the updateSession may be relevant, but after creating it and adding console.log's to it I saw nothing printed on the console, so the unstable_update is not invoking updateSession nor is working by default.
So I'm wondering how is that meant to work.
Does the docs page already exist? Please link to it.
https://authjs.dev/reference/nextjs#unstable_update
UPDATE: I managed to make it work:
jwt: async ({ token, user, trigger, session }) => {
if (user) {
if (!user.id) {
throw new Error("User ID is required");
}
token.user = {
id: user.id,
username: user.username,
};
}
if (trigger === "update") {
token.user = {
...token.user,
username: session.user.username,
};
}
return token;
},
But I'm guessing it should work without needing this, not sure how.
UPDATE: I managed to make it work:
jwt: async ({ token, user, trigger, session }) => { if (user) { if (!user.id) { throw new Error("User ID is required"); } token.user = { id: user.id, username: user.username, }; } if (trigger === "update") { token.user = { ...token.user, username: session.user.username, }; } return token; },But I'm guessing it should work without needing this, not sure how.
This worked for me. I was able to call unstable_update from a server action and the updated session persists on refresh. Thank you!
The above is the correct solution for now. It's unatable/undocumented because the current DX isn't desirable and would like to polish it more first
UPDATE: I managed to make it work:
jwt: async ({ token, user, trigger, session }) => { if (user) { if (!user.id) { throw new Error("User ID is required"); } token.user = { id: user.id, username: user.username, }; } if (trigger === "update") { token.user = { ...token.user, username: session.user.username, }; } return token; },But I'm guessing it should work without needing this, not sure how.
This worked for me. I was able to call
unstable_updatefrom a server action and the updated session persists on refresh. Thank you!
so how would you pass the session.user.username is it via update ? from useSession()
I am using this in a server action
unstable_update({
user: {
email: updatedUser.email,
name: updatedUser.name,
},
});
inside of JWT callback
if (trigger === "update" && session) {
const updatedUser = await getUserById(token.sub);
if (updatedUser) {
token.email = updatedUser.email;
token.name = updatedUser.name;
token.role = updatedUser.role;
token.isTwoFactorEnabled = updatedUser.isTwoFactorEnabled;
token.lastUpdate = Date.now();
}
}
EDIT:
using update with trigger updates the client-side session but failed to update server-side session data for that I have used unstable_update()
any update please?
You can use unstable_update for the server side. It works, but you need some more steps.
- Make sure you receive an update in callbacks jwt:
if (trigger === 'update' && session?.user) {
token.user = session?.user;
return token;
}
- By default, unstable_update only receive User model, you can declare new model when using this:
declare module 'next-auth' {
interface Session {
user: {
id?: string;
email?: string | null;
userName?: string | null;
fullName?: string | null;
accessToken?: string | null;
refreshToken?: string | null;
} & DefaultSession['user'];
}
}
After completing all the steps above, you still won’t see any changes on the client side because it is only for the server. You need to call something to trigger a session update after using unstable_update.
For me, I'm using NextAuth v5. After running unstable_update on the server side, I call await getSession() to trigger the session update on the client side. By default, await getSession() already triggers a session update internally.
Docs: https://next-auth.js.org/getting-started/client#getsession
Using unstable_update in NextAuth Beta
You can use the unstable_update helper from NextAuth to update the session server-side.
1. Import unstable_update
export const { handlers, signIn, signOut, auth, unstable_update } = NextAuth({
// your config
});
2. Create a server function to update the session
Inside a "use server" file, define a helper like this:
"use server";
import { auth, unstable_update } from "@/auth"; // adjust path accordingly
import type { Session } from "next-auth";
export const updateSession = async ({
data,
}: {
data: Partial<Session["user"]>;
}) => {
const session = await auth();
if (session) {
await unstable_update({
...session,
user: {
...session.user,
...data,
},
});
}
};
3. Call updateSession wherever you need to refresh/update session data
For example, after refreshing access tokens:
const newToken = await arvasitAuth.refreshAccessToken({
token: refreshToken,
});
if (newToken.accessToken) {
setCookie("accessToken", newToken.accessToken);
setCookie("refreshToken", newToken.refreshToken);
await updateSession({
data: {
accessToken: newToken.accessToken,
refreshToken: newToken.refreshToken,
},
});
}