S
SolidJS3mo ago
hannus

Why does "use server" not prevent console logs from appearing in the browser console?

Question: According to the documentation, there are two ways to create a server function. One is to add the "use server" directive at the top of the file, which makes all functions in that file execute only on the server and prevents them from being bundled into the client. The other is to add "use server" at the beginning of a specific function, which ensures that only that function executes on the server and is not bundled into the client. Here is my code:
export const signInWithWechatAction = action(
async (code: string, state: string): Promise<ActionResult<WeChatUserInfo>> => {
try {
const {user, tokenData} = await signInWithWechat(code, state);
logger.info("WeChat profile: ", user);
console.log("WeChat profile: ", user);

const weChatProfile = await getUserInfoFromWechat(tokenData.access_token, user.id);
logger.info("WeChat profile: ", weChatProfile);
return {success: true, data: weChatProfile}
} catch (error) {
return {success: false, error: error instanceof Error
? error.message
: "An unknown error occurred in action."}
}
}
);
export const signInWithWechatAction = action(
async (code: string, state: string): Promise<ActionResult<WeChatUserInfo>> => {
try {
const {user, tokenData} = await signInWithWechat(code, state);
logger.info("WeChat profile: ", user);
console.log("WeChat profile: ", user);

const weChatProfile = await getUserInfoFromWechat(tokenData.access_token, user.id);
logger.info("WeChat profile: ", weChatProfile);
return {success: true, data: weChatProfile}
} catch (error) {
return {success: false, error: error instanceof Error
? error.message
: "An unknown error occurred in action."}
}
}
);
I tried adding "use server" both at the top of the file and at the beginning of the function, but the logs (e.g., console.log and logger.info) are not appearing in the terminal where I ran pnpm dev as expected. Instead, they are showing up in the browser's console. Is this behavior normal? Am I misunderstanding something? Thank you!
10 Replies
Madaxen86
Madaxen863mo ago
if you use "use server" at the top level you can't export action or query from that file as queries and actions need to be available on the client. So with toplevel you need to export the "inner" function an have a separete file where you export the actions and queries.
hannus
hannusOP3mo ago
Does the console.log in the action show in client console or terminal that running pnpm dev?
Madaxen86
Madaxen863mo ago
No. Not with "use server" Also not when using the Action with useAction
exercise
exercise3mo ago
if the body of the action is a "use server" function then the function returned by useAction will run on the server obviously
Madaxen86
Madaxen863mo ago
@hannus any chance you are running a vscode extension that logs node logs to the browser console?
hannus
hannusOP3mo ago
I added "use server" on the top of the action function as following:
export const signInWithWechatAction = action(
async (
code: string,
state: string
): Promise<ActionResult<WeChatUserInfo>> => {
"use server";
try {
const { user, tokenData } = await signInWithWechat(code, state);
logger.info("WeChat profile: ", user);
console.log("WeChat profile: ", user);

const weChatProfile = await getUserInfoFromWechat(
tokenData.access_token,
user.id
);
logger.info("WeChat profile: ", weChatProfile);
console.log("gender", user.user_metadata.gender);
if (!user.user_metadata.gender) {
console.log("update profile");
await initProfileToUserFromWechat(user, weChatProfile);
}

throw redirect("/");
} catch (error) {
return {
success: false,
error:
error instanceof Error
? error.message
: "An unknown error occurred in action.",
};
}
}
);
export const signInWithWechatAction = action(
async (
code: string,
state: string
): Promise<ActionResult<WeChatUserInfo>> => {
"use server";
try {
const { user, tokenData } = await signInWithWechat(code, state);
logger.info("WeChat profile: ", user);
console.log("WeChat profile: ", user);

const weChatProfile = await getUserInfoFromWechat(
tokenData.access_token,
user.id
);
logger.info("WeChat profile: ", weChatProfile);
console.log("gender", user.user_metadata.gender);
if (!user.user_metadata.gender) {
console.log("update profile");
await initProfileToUserFromWechat(user, weChatProfile);
}

throw redirect("/");
} catch (error) {
return {
success: false,
error:
error instanceof Error
? error.message
: "An unknown error occurred in action.",
};
}
}
);
console.log("WeChat profile: ", user) is always displayed in the console of chrome. However, the functions called in the action display logs in the terminal. BTW , I used useAction in the createEffect. Is the reason of displaying log in console of chrome?
Madaxen86
Madaxen863mo ago
No, also only logs in the terminal. the redirect without any revalidation keys will revalidate all queries. Is there maybe a query that gets triggered which has by chance the same console.log but runs on the client or loggin in createEffect outside of the action? Just to clarify. You are running a SolidStart app, not just a vite template right? Because "use server" part of the "@solidjs/start" package not of the "@solidjs/router"
hannus
hannusOP3mo ago
yes. it is a soildstart project. There is only one query in the route which trigger the action.Even if I removed this query, action logs in console of chrome as well. I am going to try to set up a new action in a new route to find the reason. On the another hand, in the chrome console, I can see the _server info in the Network tab. Does it mean the action run in the server? I think I found the reason. After I removed "use server" on the top of the file including actions and only keep "use server" in the function , the logs only show in the terminal as expectation.
I will write it in details later.
hannus
hannusOP3mo ago
Conclusions from Testing 1. When use server is placed at the top of a file, the entire file is bundled for server execution, but any functions called within an action will not be automatically treated as server-only unless they are also explicitly marked. Therefore, if an action contains any client-side code (e.g., console.log), it may cause hydration mismatch errors. 2. To prevent the mismatch error described in (1), it is possible to retain the file-level use server and add an optional string parameter to the action. This parameter helps the hydration system match client and server versions of the action. 3. In scenarios where (1) and (2) are combined, actions may trigger extra _server requests when they invoke non-server-only functions. Interestingly, this can lead to a beneficial side effect: since a new server request is made, the context (including cookies) is refreshed. This means that cookies set within the action can be read by other functions even before the action finishes. 4. To avoid complexity and unintended side effects, I recommend placing "use server" at the beginning of each server function (including actions), and not using the file-level directive. This ensures consistent server-only execution and prevents hydration issues or subtle runtime mismatches.

Did you find this page helpful?