The Next.js Clerk Webhook seems unresponsive and shows no output

After successfully implementing clerk authentication in my nextjs app, I encountered an issue with saving users in MongoDB through clerk webhook. Even though I have hosted my application on Vercel, added the ${vercel_site}/api/webhook endpoint in clerk, and included the clerk webhook key in .env.local, nothing seems to be working. On the clerk dashboard, I keep seeing the message:

This endpoint has not received any messages yet.

Although there are no errors in the console and the application appears to be functioning properly, I am not receiving any response from clerk. What could possibly be the issue?

api/webhook/route.js

import { Webhook } from "svix";
import { headers } from "next/headers";
import { createOrUpdateUser } from "../../lib/controllers/user.controller.js";

export async function POST(req) {
  // Relevant webhook secret from Clerk Dashboard goes here
  const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

  if (!WEBHOOK_SECRET) {
    throw new Error(
      "Please add WEBHOOK_SECRET from Clerk Dashboard to .env or .env.local"
    );
  }

  // Get the headers
  const headerPayload = headers();
  const svix_id = headerPayload.get("svix-id");
  const svix_timestamp = headerPayload.get("svix-timestamp");
  const svix_signature = headerPayload.get("svix-signature");

  // If there are no headers, error out
  if (!svix_id || !svix_timestamp || !svix_signature) {
    return new Response("Error occured -- no svix headers", {
      status: 400,
    });
  }

  // Get the body
  const payload = await req.json();
  const body = JSON.stringify(payload);

  // Create a new Svix instance with your secret.
  const wh = new Webhook(WEBHOOK_SECRET);

  let evt;

  // Verify the payload with the headers
  try {
    evt = wh.verify(body, {
      "svix-id": svix_id,
      "svix-timestamp": svix_timestamp,
      "svix-signature": svix_signature,
    });
  } catch (err) {
    console.error("Error verifying webhook:", err);
    return new Response("Error occurred", {
      status: 400,
    });
  }

  // Handle the event
  const eventType = evt?.type;

  if (eventType === "user.created" || eventType === "user.updated") {
    const { id, first_name, last_name, profile_image_url, email_addresses } =
      evt?.data;

    try {
      await createOrUpdateUser(
        id,
        first_name,
        last_name,
        profile_image_url,
        email_addresses,
      );

      return new Response("User is created or updated", {
        status: 200,
      });
    } catch (err) {
      console.error("Error creating or updating user:", err);
      return new Response("Error occurred", {
        status: 500,
      });
    }
  }
}

user.controller.js

import User from '../models/Users.model.js';
import { connectToDB } from '../mongo.js';

 export const createOrUpdateUser = async(id, first_name, last_name, profile_image_url, email_addresses) => {
 try{
    await connectToDB();

    const user = await User.findOneAndUpdate(
        { clerkId: id },
        {
          $set: {
            firstName: first_name,
            lastName: last_name,
            profilePhoto: profile_image_url,
            email: email_addresses[0].email_address,
          },
        },
        { upsert: true, new: true } // if user doesn't exist, create a new one
      );
  
      await user.save();
      return user;
    } catch (error) {
      console.error(error);
    }
}

Connection to database

 import mongoose from "mongoose";

 let isConnected = false;

 export const connectToDB = async () => {
     mongoose.set("strictQuery", true);

   if (isConnected) {
     console.log("Database is connected");
   } else {
    try {
      await mongoose.connect(process.env.MONGO_STRING, {
        dbName: "Users",
        useNewUrlParser: true,
         useUnifiedTopology: true,
      });
      isConnected = true;
    } catch (error) {
      console.log(error);
    }
  }
};

Within route.js, I attempted to

console.log(svix_id, svix_timestamp, svix_signature)
but received no response. This raises the question of whether this file is being called at all. Additionally, I set up error handling in case the POST request fails, but no errors have been detected thus far.

catch (err) {
      console.error("Error creating or updating user:", err);
      return new Response("Error occurred", {
        status: 500,
      });
    }

Answer №1

To solve the issue, consider disabling the authentication in the vercel app settings by turning off vercel authentication under deployment protection. I encountered errors with status code 401 and webhooks not functioning properly until I made this adjustment. Everything is now functioning as intended.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering the "Component resolution failed" error in Vue 3 when using global components

When I declare my Vue components in the top level HTML file, everything works fine. Here is an example: <body> <div class='app' id='app'> <header-bar id='headerBar'></header-bar> ...

Is there a way for me to utilize the imported data from one component in the context API using an arrow function?

I am trying to utilize placeInfo, reviews, detailsInfo, news from a data file. Instead of using value='hello', I am unsure if I can directly use it like this: value={placeInfo, reviews, detailsInfo, news}, as it is producing an error. Should I st ...

Warning displayed on form input still allows submission

How can I prevent users from inserting certain words in a form on my website? Even though my code detects these words and displays a popup message, the form still submits the data once the user acknowledges the message. The strange behavior has me puzzled. ...

How to transfer a portion of a MongoDB collection to a new collection

I currently have around 25 million records in my collection. What is the most efficient method for creating a new subset collection consisting of only the latest 1 million records? This was my initial approach: db.metric.find({}).sort({'createdAt&ap ...

Looking for guidance on creating a TypeScript interface within React?

How can I properly declare the tagItems in the following code? I am currently getting a warning in VSCode that reads: (property) tagItems: [{ id: number; label: String; name: String; state: Boolean; }] Type '[{ id: number; label: stri ...

Prevent selection of specific weekdays in Kendo grid calendar

When editing a record in a Kendo grid with a date field, is there a way to only allow the selection of Monday and disable all other days of the week? ...

Validation of a string or number that is not performing as expected

I have been working with the yup library for JavaScript data validation, but I am encountering unexpected behavior. Despite thoroughly reviewing their documentation, I cannot pinpoint where I am misusing their API. When I run the unit test below, it fails ...

`Three.js and its efficient use of JavaScript for enhancing performance``

Deep within the Object3D code lies: rotateX: function () { var v1 = new THREE.Vector3( 1, 0, 0 ); return function ( angle ) { return this.rotateOnAxis( v1, angle ); }; }(), But what about: rotateX: function (angle) { var v1 = new ...

Angular9: construction involves an additional compilation process

After updating my Angular8 project to Angular9, I noticed a new step in the build process which involves compiling to esm. This additional step has added approximately 1 minute to my build time. A snippet of what this step looks like: Compiling @angular/ ...

The escape character appears to be misunderstood, causing an error due to an invalid escape sequence

When using the following syntax: executeJSCommand("location.href='StatusDetails.php?CHLD=1\&JNum=1024&JTitle=';"); An error occurs displaying: Invalid Escape Sequence ...

Adding JSON data to a table with the keys in the first row is a simple process that can be achieved

Previously, I have created tables with XML formatted results and JSON data in the "key: data" format. To access the data, I would use syntax like results.heading1 and then map the data into a table by matching the key with the data. Now, a new client is o ...

Optimal method for identifying all inputs resembling text

I'm in the process of implementing keyboard shortcuts on a webpage, but I seem to be encountering a persistent bug. It is essential that keyboard shortcuts do not get activated while the user is typing in a text-like input field. The approach for hand ...

Create geometric shapes on Google Maps version 2

Can anyone guide me on how to draw a polygon on Google Maps with user-input coordinates? I have two input fields for latitude and longitude, and when the user clicks the button, I want the polygon to be drawn. The code I currently have doesn't seem to ...

The ajax function nestled within a nested forEach loop completes its execution once the inner callback function is triggered

I am encountering a problem with an ajax call that is nested within a forEach loop inside another function. The issue is that the callback of the outer function is being triggered before the inner loop completes, resulting in "staticItemList" not being p ...

Establishing a MongoDB connection only once in a Next.js application

I'm new to Next.js and have a question about database connections. In Express projects, we typically establish the connection in the main file (app.js), but it seems like in Next.js, the database connection needs to be inside the API file. Will this r ...

Tips for avoiding background-image zoom on mobile browsers when stacking elements vertically:

Within my ReactJS application, I have implemented a feature where elements are added vertically from top to bottom when the "Post" button is clicked. https://i.sstatic.net/KwPYV.jpg These elements display correctly on both mobile and desktop browsers. Ho ...

Can we display various React components based on the screen size?

I am looking to implement various components that will display at different breakpoints. I attempted this using Material-UI import withWidth, { isWidthUp } from '@material-ui/core/withWidth'; function MyComponent(props) { if (isWidthUp('s ...

Using default language in Next.js internationalization: a step-by-step guide

I've been immersing myself in the Nextjs internationalization documentation for the past two days. My goal is to have support for two languages: en, fa. I also want to be able to switch between them with URLs structured like this: https://example.com ...

Is it possible to modify the CSS of a single class when hovering over a child class of a different and unrelated class?

I am struggling with CSS combinators, especially when dealing with nested div, ul, and li elements. My issue involves changing the CSS of a div with the class "H" when hovering over li elements with the class "G". Since all of this is contained within a s ...

How can I display only four decimal places by default within textboxes in HTML?

Looking for assistance with configuring textboxes in a cshtml file. The textboxes are bound to decimal fields in a view model and currently display nine zeros after the decimal point. I would like to limit the display to only four digits by default witho ...