NextJS server action error
Unanswered
Schweizer Laufhund posted this in #help-forum
Schweizer LaufhundOP
Error: Failed to find Server Action "null". This request might be from an older or newer deployment. Original error: Invariant: Missing 'next-action' header.Im implementing authentication into my page using Lucia so Im making a call to a server action but I just get a hydration error on my browser and next gives me the above error. I am calling my server action from a client component and the server action is in another file
42 Replies
Schweizer LaufhundOP
Heres my server action
/registration, login, reset
"use server";
import { PrismaClient } from "@prisma/client";
import { generateId } from "lucia";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { Argon2id } from "oslo/password";
import lucia from "../actions/auth";
const prisma = new PrismaClient();
interface ActionResult {
error: string;
}
export const register = async (e: React.MouseEvent<HTMLButtonElement>, form: FormData): Promise<ActionResult> => {
let email: FormDataEntryValue | null = form.get("email");
let username: FormDataEntryValue | null = form.get("username");
let password: FormDataEntryValue | null = form.get("password");
e.preventDefault();
const hashedPassword = await new Argon2id().hash(password as string);
const userId = generateId(15);
///check if username/email is already used
const checkEmail = await prisma.user.findFirst({
where: {
email: email as string,
},
});
const checkUsername = await prisma.user.findFirst({
where: {
username: username as string,
},
});
if (!checkEmail) {
return { error: "Email already in use" };
}
if (!checkUsername) {
return { error: "Username already in use" };
}
await prisma.user.create({
data: {
id: userId,
email: email as string,
username: username as string,
hashed_password: hashedPassword,
},
});
const session = await lucia.createSession(userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes
);
return redirect("/");
};Schweizer LaufhundOP
this only happens when i submit my form for logging in which calls the server action
i also get a hydration error
Asiatic Lion
Can you show your client components code?
@Schweizer Laufhund Heres my server action /registration, login, reset
"use server";
import { PrismaClient } from "@prisma/client";
import { generateId } from "lucia";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { Argon2id } from "oslo/password";
import lucia from "../actions/auth";
const prisma = new PrismaClient();
interface ActionResult {
error: string;
}
export const register = async (e: React.MouseEvent<HTMLButtonElement>, form: FormData): Promise<ActionResult> => {
let email: FormDataEntryValue | null = form.get("email");
let username: FormDataEntryValue | null = form.get("username");
let password: FormDataEntryValue | null = form.get("password");
e.preventDefault();
const hashedPassword = await new Argon2id().hash(password as string);
const userId = generateId(15);
///check if username/email is already used
const checkEmail = await prisma.user.findFirst({
where: {
email: email as string,
},
});
const checkUsername = await prisma.user.findFirst({
where: {
username: username as string,
},
});
if (!checkEmail) {
return { error: "Email already in use" };
}
if (!checkUsername) {
return { error: "Username already in use" };
}
await prisma.user.create({
data: {
id: userId,
email: email as string,
username: username as string,
hashed_password: hashedPassword,
},
});
const session = await lucia.createSession(userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes
);
return redirect("/");
};
Asiatic Lion
the problem is probably the mouse event parameter. this is not possible liek this. the server action runs on the server, so it can't prevent the event. you will have to do that from within your client component
@Asiatic Lion Can you show your client components code?
Schweizer LaufhundOP
the stuff i commented out is the stuff im not sure works
actually nvm i know whats causing the hydration issue
it was unrelated to my form, not sure whats causing the server action issue though
@Asiatic Lion did you change the event handler?
Schweizer LaufhundOP
yeah
i got rid of it
Schweizer LaufhundOP
ok so i think the server action error is gone when i submit but im still getting the hydration error on form submit...
this is my navbar i dont think theres anything wrong with it?
Himalayan
I think you should suppress the hydration error
@Himalayan I think you should suppress the hydration error
Schweizer LaufhundOP
Is it an error with my code or just something the dev server brings up?
Like would it impact production
@Schweizer Laufhund Is it an error with my code or just something the dev server brings up?
Himalayan
It happen when you’re using improper jsx like div inside h1 etc
Check your navbar component
But if you’re sure that’s how you want to render it….. you can suppress the hydration error from your layout
@Himalayan It happen when you’re using improper jsx like div inside h1 etc
Schweizer LaufhundOP
yea it should be right i posted my component above, i only get the hydration error when i submit my form and the page reloads. when i browse my site normally i get nothing
Schweizer LaufhundOP
yeah it seems like reloading my page is the issue...
@Schweizer Laufhund yea it should be right i posted my component above, i only get the hydration error when i submit my form and the page reloads. when i browse my site normally i get nothing
Himalayan
Yeah whenever you reload it’ll show and after a couple of minute it’ll stop showing
Schweizer LaufhundOP
alright i will just suppress it
Himalayan
And @Schweizer Laufhund consider using react state instead of accessing the Dom element directly
@Himalayan And <@671454109819207711> consider using react state instead of accessing the Dom element directly
Schweizer LaufhundOP
wym by that?
like instead of using setcustomvalidity?
@Schweizer Laufhund like instead of using setcustomvalidity?
Himalayan
Instead of using queryselector
@Himalayan Instead of using queryselector
Schweizer LaufhundOP
what should i use? useRef?
Himalayan
onChange={() => {
(
document.querySelector(
'input[name="email"]'
) as HTMLFormElement
).setCustomValidity("");
}}
(
document.querySelector(
'input[name="email"]'
) as HTMLFormElement
).setCustomValidity("");
}}
Like here you could just use something like :
UseState
Just a suggestion though
Schweizer LaufhundOP
what would my state be though since i need to set the validity of the html element
Himalayan
Something like this const [email, setEmail] = useState(“â€)
Are you using any library or you’re just building from scratch
@Himalayan Are you using any library or you’re just building from scratch
Schweizer LaufhundOP
for authentication I'm using Lucia otherwise its all react/next
@Schweizer Laufhund for authentication I'm using Lucia otherwise its all react/next
Himalayan
Oh! Am a clerk fan lol 😆
@Schweizer Laufhund for authentication I'm using Lucia otherwise its all react/next
Himalayan
Is it working now ?
@Himalayan Is it working now ?
Schweizer LaufhundOP
For now yes the server action works and I got rid of hydration