webhooks - My Next.js app keeps hanging on "Generating static pages" - Stack Overflow

I am using the latest Canary version of Next.js and I am trying to deploy it on Vercel but it keeps han

I am using the latest Canary version of Next.js and I am trying to deploy it on Vercel but it keeps hanging at "Generating static pages":

Creating an optimized production build ...
 ✓ Compiled successfully
   Skipping linting
   Checking validity of types ...
   Collecting page data ...
   Generating static pages (0/15) ...
   Generating static pages (3/15) 

I have followed the steps to use the Implementing Canary Deployments on Vercel.

Nothing seems to work.

My next.config.js looks like this:

// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [{
        protocol: 'http',
        hostname: 'localhost'
      },
      {
        protocol: 'https',
        hostname: 'b.stripecdn'
      },
      {
        protocol: 'https',
        hostname: 'yt3.googleusercontent'
      },
      {
        protocol: 'https',
        hostname: 'i.ytimg'
      },
    ], // Allow images from localhost and Stripe CDN
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
  /* config options here */
  experimental: {
    dynamicIO: true,
    authInterrupts: true,
  },
  // staticPageGenerationTimeout: 1000,
}

module.exports = nextConfig

My build works fine on local. Has anyone else dealt with this on Vercel?

When the app build finally fails I get this message:

    Export encountered an error on /api/webhooks/clerk/route: /api/webhooks/clerk, exiting the build.
 ⨯ Next.js build worker exited with code: 1 and signal: null
Error: Command "npm run build" exited with 1

Here is my route.ts file for my Clerk Webhook

import {
  env
} from "@/data/env/server"
import {
  deleteUser,
  insertUser,
  updateUser
} from "@/features/users/db/users"
import {
  syncClerkUserMetadata
} from "@/services/clerk"
import {
  WebhookEvent
} from "@clerk/nextjs/server"
import {
  headers
} from "next/headers"
import {
  Webhook
} from "svix"

export async function POST(req: Request) {
  const headerPayload = await headers()
  const svixId = headerPayload.get("svix-id")
  const svixTimestamp = headerPayload.get("svix-timestamp")
  const svixSignature = headerPayload.get("svix-signature")

  if (!svixId || !svixTimestamp || !svixSignature) {
    return new Response("Error occurred -- no svix headers", {
      status: 400,
    })
  }

  const payload = await req.json()
  const body = JSON.stringify(payload)

  const wh = new Webhook(env.CLERK_WEBHOOK_SECRET)
  let event: WebhookEvent

  try {
    event = wh.verify(body, {
      "svix-id": svixId,
      "svix-timestamp": svixTimestamp,
      "svix-signature": svixSignature,
    }) as WebhookEvent
  } catch (err) {
    console.error("Error verifying webhook:", err)
    return new Response("Error occurred", {
      status: 400,
    })
  }

  switch (event.type) {
    case "user.created":
    case "user.updated": {
      const email = event.data.email_addresses.find(
        email => email.id === event.data.primary_email_address_id
      )?.email_address
      const name = `${event.data.first_name} ${event.data.last_name}`.trim()
      if (email == null) return new Response("No email", {
        status: 400
      })
      if (name === "") return new Response("No name", {
        status: 400
      })

      if (event.type === "user.created") {
        const user = await insertUser({
          clerkUserId: event.data.id,
          email,
          name,
          imageUrl: event.data.image_url,
          role: "user",
        })

        await syncClerkUserMetadata(user)
      } else {
        await updateUser({
          clerkUserId: event.data.id
        }, {
          email,
          name,
          imageUrl: event.data.image_url,
          role: event.data.public_metadata.role,
        })
      }
      break
    }
    case "user.deleted": {
      if (event.data.id != null) {
        await deleteUser({
          clerkUserId: event.data.id
        })
      }
      break
    }
  }

  return new Response("", {
    status: 200
  })
}

I am using the latest Canary version of Next.js and I am trying to deploy it on Vercel but it keeps hanging at "Generating static pages":

Creating an optimized production build ...
 ✓ Compiled successfully
   Skipping linting
   Checking validity of types ...
   Collecting page data ...
   Generating static pages (0/15) ...
   Generating static pages (3/15) 

I have followed the steps to use the Implementing Canary Deployments on Vercel.

Nothing seems to work.

My next.config.js looks like this:

// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [{
        protocol: 'http',
        hostname: 'localhost'
      },
      {
        protocol: 'https',
        hostname: 'b.stripecdn'
      },
      {
        protocol: 'https',
        hostname: 'yt3.googleusercontent'
      },
      {
        protocol: 'https',
        hostname: 'i.ytimg'
      },
    ], // Allow images from localhost and Stripe CDN
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
  /* config options here */
  experimental: {
    dynamicIO: true,
    authInterrupts: true,
  },
  // staticPageGenerationTimeout: 1000,
}

module.exports = nextConfig

My build works fine on local. Has anyone else dealt with this on Vercel?

When the app build finally fails I get this message:

    Export encountered an error on /api/webhooks/clerk/route: /api/webhooks/clerk, exiting the build.
 ⨯ Next.js build worker exited with code: 1 and signal: null
Error: Command "npm run build" exited with 1

Here is my route.ts file for my Clerk Webhook

import {
  env
} from "@/data/env/server"
import {
  deleteUser,
  insertUser,
  updateUser
} from "@/features/users/db/users"
import {
  syncClerkUserMetadata
} from "@/services/clerk"
import {
  WebhookEvent
} from "@clerk/nextjs/server"
import {
  headers
} from "next/headers"
import {
  Webhook
} from "svix"

export async function POST(req: Request) {
  const headerPayload = await headers()
  const svixId = headerPayload.get("svix-id")
  const svixTimestamp = headerPayload.get("svix-timestamp")
  const svixSignature = headerPayload.get("svix-signature")

  if (!svixId || !svixTimestamp || !svixSignature) {
    return new Response("Error occurred -- no svix headers", {
      status: 400,
    })
  }

  const payload = await req.json()
  const body = JSON.stringify(payload)

  const wh = new Webhook(env.CLERK_WEBHOOK_SECRET)
  let event: WebhookEvent

  try {
    event = wh.verify(body, {
      "svix-id": svixId,
      "svix-timestamp": svixTimestamp,
      "svix-signature": svixSignature,
    }) as WebhookEvent
  } catch (err) {
    console.error("Error verifying webhook:", err)
    return new Response("Error occurred", {
      status: 400,
    })
  }

  switch (event.type) {
    case "user.created":
    case "user.updated": {
      const email = event.data.email_addresses.find(
        email => email.id === event.data.primary_email_address_id
      )?.email_address
      const name = `${event.data.first_name} ${event.data.last_name}`.trim()
      if (email == null) return new Response("No email", {
        status: 400
      })
      if (name === "") return new Response("No name", {
        status: 400
      })

      if (event.type === "user.created") {
        const user = await insertUser({
          clerkUserId: event.data.id,
          email,
          name,
          imageUrl: event.data.image_url,
          role: "user",
        })

        await syncClerkUserMetadata(user)
      } else {
        await updateUser({
          clerkUserId: event.data.id
        }, {
          email,
          name,
          imageUrl: event.data.image_url,
          role: event.data.public_metadata.role,
        })
      }
      break
    }
    case "user.deleted": {
      if (event.data.id != null) {
        await deleteUser({
          clerkUserId: event.data.id
        })
      }
      break
    }
  }

  return new Response("", {
    status: 200
  })
}
Share Improve this question edited Mar 4 at 11:39 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 4 at 11:00 Amen RaAmen Ra 2,85110 gold badges49 silver badges87 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

So I discovered the problem. In my next.config.ts file I had the following code:

experimental: {
  dynamicIO: true,
  authInterrupts: true,
},

So the dynamicID feature was causing my api routes to make an infinite loop. So what I did is this

experimental: {
  dynamicIO: false,
  authInterrupts: true,
  useCache: true,
},

I just added the useCache feature so I could still use the use cache directive in my app and in my routes file I just put the following variable above my function export const dynamic = "force-dynamic"; this can be explained in this doc from next.js Route Segment Config

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745048563a4608244.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信