"use server" file vs "use server" function

Hi all, I just have a question about the behaviour of "use server" for a single function vs "use server" for a whole file.. I have a sign-up component that imports an action from my api:
import { userSignUp } from "~/api/server";


export function SignUp() {
return (
<div class="flex flex-col items-center justify-center h-screen">
<h1 class="text-2xl font-bold">Sign Up</h1>
<form action={userSignUp} method="post">
<input class="border-2 border-gray-300 rounded-md p-2" type="email" name="email" />
<input class="border-2 border-gray-300 rounded-md p-2" type="password" name="password" />
<button class="bg-blue-500 text-white rounded-md p-2" type="submit">Sign Up</button>
</form>
</div>
);
}
import { userSignUp } from "~/api/server";


export function SignUp() {
return (
<div class="flex flex-col items-center justify-center h-screen">
<h1 class="text-2xl font-bold">Sign Up</h1>
<form action={userSignUp} method="post">
<input class="border-2 border-gray-300 rounded-md p-2" type="email" name="email" />
<input class="border-2 border-gray-300 rounded-md p-2" type="password" name="password" />
<button class="bg-blue-500 text-white rounded-md p-2" type="submit">Sign Up</button>
</form>
</div>
);
}
Here is a working version of said action (note that this is the entire contents of the file) :
import { action } from "@solidjs/router";
import { supabase } from "~/supabase/client";

export const userSignUp = action(async (formData: FormData) => {
"use server";
const email = formData.get("email");
const password = formData.get("password");

if (!email || !password) {
throw new Error("Email and password are required");
}

const { data, error } = await supabase.auth.signUp({
email: email as string,
password: password as string,
});

if (error) {
throw new Error(error.message);
}

return data;
}, "userSignUp");
import { action } from "@solidjs/router";
import { supabase } from "~/supabase/client";

export const userSignUp = action(async (formData: FormData) => {
"use server";
const email = formData.get("email");
const password = formData.get("password");

if (!email || !password) {
throw new Error("Email and password are required");
}

const { data, error } = await supabase.auth.signUp({
email: email as string,
password: password as string,
});

if (error) {
throw new Error(error.message);
}

return data;
}, "userSignUp");
What doesn't work, is when I move the "use server" directive to the top of the file instead of for just the function. When I do this, I'm redirected to https://action/userSignUp (see attached image). The "use server" documentation page doesn't seem to answer why this would be happening. Is this expected behaviour? And if so, could someone please explain to me why this is happening so I can better understand it?
No description
2 Replies
Madaxen86
Madaxen862mo ago
The thing is that the action itself (its function) gets called on the client. This also applies to functions wrapped in query. you may use the "use server" directive only for the functions inside those helpers
MALEV0L3NT
MALEV0L3NTOP2mo ago
Ahh, yes ok that makes sense. Thanks for the explanation

Did you find this page helpful?