Next.js Discord

Discord Forum

I am getting a 404 Error when attempting to create a new user account

Answered
Sun bear posted this in #help-forum
Open in Discord
Sun bearOP
const supabase = createClient();

type FormData = {
//...
};

type Step = keyof FormData;

const SignUpForm = ({ dictionary, lang }: { dictionary: Dictionary, lang: string }) => {
const mounted = useMounted();
//...
const router = useRouter();

useEffect(() => {
console.log("SignUpForm isStepValid: ", isStepValid);
}, [isStepValid]);

const [formData, setFormData] = useState<FormData>({
//...
});

const updateFormData = (step: Step, data: Partial<FormData[Step]> | string) => {
//...
};

const handleFormSubmit = async () => {
console.log("Form Submitted", formData);

try {
const response = await fetch(`/${lang}/signup/submit`, {
           method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(formData),
        });

        if (!response.ok) {
            const errorData = await response.json();
            console.error('Error submitting form data:', errorData.error);
        } else {
            const data = await response.json();
            console.log('Data submitted successfully:', data);
            if (formData.accountType.userType === 'Job Seeker') {
                router.push(`/${lang}/jobs/page`);
            } else if (formData.accountType.userType === 'Recruiter') {
                router.push(`/${lang}/my-jobs/page`);
            }
        }
    } catch (error) {
        console.error('Network error or unexpected issue:', error);
    }
};

    useEffect(() => {
        const scrollContainer = formContainerRef.current;
        if (scrollContainer && scrollContainer.scrollHeight > scrollContainer.clientHeight) {
            setTimeout(() => {
                scrollContainer.scrollTo({ top: scrollContainer.scrollHeight, behavior: 'smooth' });
            }, 300);
            setTimeout(() => {
                scrollContainer.scrollTo({ top: 0, behavior: 'smooth' });
            }, 600);
        }
    }, [formContainerRef.current]);

    if (!mounted) return null;
Answered by Hong
View full answer

45 Replies

Sun bearOP
I can offer more details if necessary.
Sun bearOP
UP
You can use /signup/submit/route.ts
@Sun bear Can you show the code of submit.tsx?
Sun bearOP
Of course, it's pretty small.

'use server'
import { createClient } from '@/utils/supabase/server';
import type { NextApiRequest, NextApiResponse } from 'next';
import type { SignupData } from '@/utils/types';
import { cookies } from 'next/headers';

export const api = async (req: NextApiRequest, res: NextApiResponse) => {
  
    console.log(`Request received: ${req.method} ${req.url}`);
    console.log(`Request body:`, req.body);

    if (req.method === 'POST') {
        
        const { personalDetails, accountType, accountDetails }: SignupData = req.body;

      
        const cookieStore = cookies();
        const supabase = createClient(cookieStore);

       
        const { data: signUpData, error: signUpError } = await supabase.auth.signUp({
            email: accountDetails.email,
            password: accountDetails.password,
        });

        if (signUpError) {
            console.error('Supabase signUp error:', signUpError);
            return res.status(500).json({ error: signUpError.message });
        }

      
        if (!signUpData.user) {
            console.error('User was not created.');
            return res.status(500).json({ error: "User was not created." });
        }
  const targetTable = accountType.userType === 'Job Seeker' ? 'Job Seekers' : 'Applicants';

        const userData = {
            userId: signUpData.user.id,
            firstName: personalDetails.firstName,
            middleName: personalDetails.middleName,
            lastName: personalDetails.lastName,
            country: personalDetails.country,
            dateOfBirth: personalDetails.dateOfBirth,
            userType: accountType.userType,
            email: accountDetails.email,
         
        };

        const { data: insertData, error: insertError } = await supabase
            .from(targetTable)
            .insert([userData]);

        if (insertError) {
            console.error('Error inserting user data:', insertError);
           
            return res.status(500).json({ error: insertError.message });
        }

        // Handle success
        console.log(`User data inserted successfully:`, insertData);
        return res.status(200).json({ data: { user: signUpData.user, additionalData: insertData } });
    } else {
        // Handle any non-POST requests
        console.log(`Non-POST request received: ${req.method}`);
        res.setHeader('Allow', ['POST']);
        res.status(405).end(`Method ${req.method} Not Allowed`);
    }
};
Umm... it seems that this code is for pages router.
You should use [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) in app router. And change the file from /signup/submit.tsx to /signup/submit/route.ts
@Hong Umm... it seems that this code is for pages router. You should use [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) in app router. And change the file from `/signup/submit.tsx` to `/signup/submit/route.ts`
Sun bearOP
Oh. I already have a route.ts though:
//app/auth/callback/route.ts

import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { type EmailOtpType } from '@supabase/supabase-js'
import { cookies } from 'next/headers'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url)
  const token_hash = searchParams.get('token_hash')
  const type = searchParams.get('type') as EmailOtpType | null
  const next = searchParams.get('next') ?? '/'
  const redirectTo = request.nextUrl.clone()
  redirectTo.pathname = next

  if (token_hash && type) {
    const cookieStore = cookies()
    const supabase = createServerClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
      {
        cookies: {
          get(name: string) {
            return cookieStore.get(name)?.value
          },
          set(name: string, value: string, options: CookieOptions) {
            cookieStore.set({ name, value, ...options })
          },
          remove(name: string, options: CookieOptions) {
            cookieStore.delete({ name, ...options })
          },
        },
      }
    )

    const { error } = await supabase.auth.verifyOtp({
      type,
      token_hash,
    })
    if (!error) {
      return NextResponse.redirect(redirectTo)
    }
  }

  // return the user to an error page with some instructions
  redirectTo.pathname = '/auth/auth-code-error'
  return NextResponse.redirect(redirectTo)
}
This file was created together with the project. As in is one of the default files in the supabase next.js template.
Do I need to move the code from the submit.tsx here ?
@Sun bear Oh. I already have a route.ts though: js //app/auth/callback/route.ts import { createServerClient, type CookieOptions } from '@supabase/ssr' import { type EmailOtpType } from '@supabase/supabase-js' import { cookies } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const token_hash = searchParams.get('token_hash') const type = searchParams.get('type') as EmailOtpType | null const next = searchParams.get('next') ?? '/' const redirectTo = request.nextUrl.clone() redirectTo.pathname = next if (token_hash && type) { const cookieStore = cookies() const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get(name: string) { return cookieStore.get(name)?.value }, set(name: string, value: string, options: CookieOptions) { cookieStore.set({ name, value, ...options }) }, remove(name: string, options: CookieOptions) { cookieStore.delete({ name, ...options }) }, }, } ) const { error } = await supabase.auth.verifyOtp({ type, token_hash, }) if (!error) { return NextResponse.redirect(redirectTo) } } // return the user to an error page with some instructions redirectTo.pathname = '/auth/auth-code-error' return NextResponse.redirect(redirectTo) }
No. This one is for an authentication callback. And you just need to change /signup/submit.tsx to /signup/submit/route.ts. Remove the 'use server' and use the correct way to write the API as a route handler.
Answer
Something like this
Sun bearOP
Thank you very much, I have no idea what happened but after updating the code the pages under the next folder started giving errors 😦
I haven't even touched those
And even if I undo the errors won't go away
Try to delete the folder .next and run again.
Sun bearOP
Thank you, that's what I just did. I actually just deleted the submit folder
The errors went away now and I am trying your code
That's the only error I get
It should be
const body = await req.json()
console.log(`Request received: ${req.method} ${req.url}`)
  console.log('Request body:', body)

  const { personalDetails, accountType, accountDetails }: SignupData = body

I forgot to update it.
Okay time to test if the sign-up works now!
Oof
But the account actually went through!
In Supabase
Give me the logs in your dev server
As it throws the 500 error.
@Hong Give me the logs in your dev server
Sun bearOP
[Log] Form Submitted
Object

accountDetails: {email: "mail@mail.com", confirmEmail: "mail@mail.com", password: "mail@mail.com", confirmPassword: "mail@mail.com"}

accountType: {userType: "job_seeker"}

personalDetails: {firstName: "q", middleName: "q", lastName: "q", country: "Qatar", dateOfBirth: "1994-01-18"}

Object Prototype
---
[Error] Failed to load resource: the server responded with a status of 500 (Internal Server Error) (submit, line 0)
---
[Error] Error submitting form data: 500 Internal Server Error
    (anonymous function) (app-index.js:34)
    (anonymous function) (hydration-error-info.js:41)
    (anonymous function) (sign-up-form.tsx:92)
---
[Error] Error details: – {}
    (anonymous function) (app-index.js:34)
    (anonymous function) (hydration-error-info.js:41)
    (anonymous function) (sign-up-form.tsx:93)
Those are the 4 logs form my browser, or do you mean there are logs somewhere else too ?
I mean the dev server.
your terminal logs
Sun bearOP
Oh
@Hong your terminal logs
Sun bearOP
johnnyrobert@Johnnys-MacBook-Air jobs-bringer-web % npm run dev

> dev
> next dev

   â–² Next.js 14.0.4
   - Local:        http://localhost:3000
   - Environments: .env.local

 ✓ Ready in 2s
 ✓ Compiled /middleware in 206ms (147 modules)
 â—‹ Compiling /[lang]/signup/submit ...
 ✓ Compiled /[lang]/signup/submit in 640ms (150 modules)
Request received: POST http://localhost:3000/en/signup/submit
Request body: ReadableStream { locked: false, state: 'readable', supportsBYOB: false }
Request received: POST http://localhost:3000/en/signup/submit
Request body: {
  personalDetails: {
    firstName: 'q',
    middleName: 'q',
    lastName: 'q',
    country: 'Qatar',
    dateOfBirth: '1994-01-18'
  },
  accountType: { userType: 'job_seeker' },
  accountDetails: {
    email: 'mail@mail.com',
    confirmEmail: 'mail@mail.com',
    password: 'mail@mail.com',
    confirmPassword: 'mail@mail.com'
  }
}
Error inserting user data: {}
That's all the logs there's nothing else after that
Oh, this is thrown by
const { data: insertData, error: insertError } = await supabase
    .from(targetTable)
    .insert([userData])

I'm not familiar with supabase. I can't help you with that.
as you can see Error inserting user data: {}
Sun bearOP
Oh, I see. I think Chat GPT can help me with that no worries.
I'll let you know if I can solve that but for now thank you so much for helping me with the rest of it, I really appreciate it. If you need help with UI design please let me know, that's something I can help with in exchange. Just dm me if that's the case.
Also if you need help with product design same thing.
@Hong Click to see attachment
Sun bearOP
I can confirm that your solution worked, after updating it to work with Supabase :100vercel: