I’ve implemented a hero form where user will enter the username and click on claim link, user will be taken to authentication page, and the username will be saved in mongodb database, But it is not working.
app/api/claim-username/route.ts
import { MongoClient } from 'mongodb';
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { getAuth } from '@clerk/nextjs/server';
const client = new MongoClient(`${process.env.MONGODB_URI}}`);
export async function GET(request: NextRequest) {
try {
const { userId } = getAuth(request);
const { searchParams } = new URL(request.url);
const username = searchParams.get('username') as string;
if (!userId || !username) {
return NextResponse.json({ error: 'Invalid request' }, { status: 400 });
}
await client.connect();
const db = client.db('endorsedBy');
const users = db.collection('users');
const existingUser = await users.findOne({ username });
if (existingUser) {
return NextResponse.json({ error: 'Username already taken' }, { status: 400 });
}
await users.updateOne(
{ userId },
{ $set: { username } },
{ upsert: true }
);
return NextResponse.redirect('/profile');
} catch (error) {
console.error('Error in claim-username API:', error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
} finally {
await client.close();
}
}
Inside hero form, I’ve used AuthenticateWithRedirectCallback, and have passed the parameters. But I think there might be mistake in logical implementation. Kindly help me resolve the error.
components/forms/heroform.tsx
"use client";
import React, { useState } from "react";
import { Button } from "../ui/button";
import { useRouter } from "next/navigation";
import { useSignIn } from "@clerk/nextjs";
const HeroForm = () => {
const [username, setUsername] = useState("");
const [error, setError] = useState("");
const { signIn } = useSignIn();
const router = useRouter();
const handleClaimUsername = async () => {
if (!signIn) {
console.error("SignIn object is undefined");
setError("SignIn object is undefined");
return;
}
try {
await signIn.authenticateWithRedirect({
strategy: "oauth_google",
redirectUrl: `${window.location.origin}/api/claim-username?username=${username}`,
redirectUrlComplete: "/profile",
});
} catch (err) {
console.error("Error during sign-in:", err);
setError("Failed to sign in. Please try again.");
}
};
return (
<form
onSubmit={(e) => {
e.preventDefault();
handleClaimUsername();
}}
>
<div className="flex overflow-hidden rounded-md z-10 xs:text-14 border space-x-1 ">
<div className="flex flex-col justify-center ">
<div className="pl-4 my-2 xs:pl-32 font-semibold text-lg text-left leading-8 xs:text-14">
endorsed.by/
</div>
</div>
<input
value={username}
onChange={(e) => setUsername(e.target.value)}
className="w-full placeholder-gray focus:outline-none"
placeholder="yourname"
/>
</div>
<div className="my-4 flex justify-center">
<Button
type="submit"
className="px-4 bg-black py-2 max-w-fit rounded-md text-gray-300 font-medium text-[14px] grow"
>
Claim my link
</Button>
</div>
{error && <div className="text-red-500">{error}</div>}
</form>
);
};
export default HeroForm;
When I click claim username
button, it is not taking me to sign in page, but I’m getting the error that I’ve implemented inside the handleClaimUsername
function