S
SolidJS4mo ago
hannus

Inconsistent Behavior with `clearSession` in SolidStart's `vinxi/http` Compared to Expectations

I’ve noticed that the behavior of clearSession in vinxi/http in SolidStart doesn’t align with my expectations, and I’m unsure if I’m misremembering or if there was an update that changed the behavior. The specific issue is: after clearing the session, the revalidated data still reflects the session state before it was cleared (similar to the behavior of deleteCookie). However, I recall that clearing a session should take effect immediately upon revalidation, unlike deleteCookie. For testing, I have the following code:
interface TestSession {
username: string;
token: string;
}

async function auth() {
"use server"
const { data } = await useSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
});
return data ? data.username : null;
}

async function login() {
"use server"
const session = await updateSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
}, {
username: "test",
token: "test",
});
return revalidate("testauth");
}

async function logout() {
"use server"
const session = await clearSession({
password: process.env.SESSION_PASSWORD!,
});
return revalidate("testauth");
}

export const testloginAction = action(login);
export const testlogoutAction = action(logout);
export const testauthQuery = query(auth, "testauth");
interface TestSession {
username: string;
token: string;
}

async function auth() {
"use server"
const { data } = await useSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
});
return data ? data.username : null;
}

async function login() {
"use server"
const session = await updateSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
}, {
username: "test",
token: "test",
});
return revalidate("testauth");
}

async function logout() {
"use server"
const session = await clearSession({
password: process.env.SESSION_PASSWORD!,
});
return revalidate("testauth");
}

export const testloginAction = action(login);
export const testlogoutAction = action(logout);
export const testauthQuery = query(auth, "testauth");
In a route component, I preload testauthQuery(). When triggering testloginAction, the data in the route component (testauthQuery) updates in real-time. However, after triggering testlogoutAction to clear the session, the revalidated data from testauthQuery still reflects the session state before it was cleared.
5 Replies
hannus
hannusOP4mo ago
Is this behavior expected? I recall that previously, deleting a cookie required the next query or a page refresh to take effect, but clearing a session would result in the next request containing the updated session data. Am I misremembering, or has there been some change or improvement in the meantime? thanks
Madaxen86
Madaxen864mo ago
I‘m afk. But try reload({revalidate:"testauth"}) instead of revalidate in server functions.
hannus
hannusOP4mo ago
It doesn't work. I think the query to trigger the server function is sent before the cookie/session is cleared on the client. After some investigation, I believe I’ve figured out why a revalidate query in SolidStart still returns a deleted cookie after a cookie-deleting action completes — whereas a cookie-setting action followed by a revalidate query behaves as expected. The reason lies in SolidStart’s single flight mechanism. To avoid redundant network requests, a revalidate is usually executed entirely on the server. Instead of triggering a new fetch() from the browser, the router completes the entire lifecycle on the server and serializes the result back to the client. During this process, any required browser-specific information (like cookies) is injected via the server context, which is constructed by Solid Router. Here’s the key part: Deleting a cookie is an asynchronous operation performed by the browser. When building the server context during revalidation, Solid Router doesn’t have a way to know that the cookie has been deleted — it only sees the cookie values that were present at the time of the request. Therefore, after a cookie-deleting action, the server context still includes the stale cookie, and the revalidated query returns it. In contrast, setting a cookie is a server-side operation that updates the Set-Cookie header. This allows the updated cookie to be immediately visible to the server context, so a revalidated query will read the correct value. Eventually, once the browser performs a real request (like a fetch or a full page reload), the cookie state will be properly updated and reflected in the context used to build future server responses.
Madaxen86
Madaxen864mo ago
that means that instead of clearSession you are using
updateSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
}, null);
updateSession<TestSession>({
password: process.env.SESSION_PASSWORD!,
}, null);
??
//from the with-auth example in the SolidStart repo
///...
export async function logout() {
const session = await getSession(); // this is useSession(...)
await session.update(d => {
d.userId = undefined;
});
}
//...
//from the with-auth example in the SolidStart repo
///...
export async function logout() {
const session = await getSession(); // this is useSession(...)
await session.update(d => {
d.userId = undefined;
});
}
//...
hannus
hannusOP4mo ago
I think session.update will be worked.

Did you find this page helpful?