#NextJs 15 vs nextJs 14

1 messages · Page 1 of 1 (latest)

cunning herald
#

@worthy wyvern , I had an old project in next 14 and I had some route handlers especially for stripe webhook handling,

and now I use nextjs 15.4.3, and all my route handlers are not working at all do I need to change something (using app router)?

worthy wyvernBOT
#

Hi @cunning herald. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

If your Stripe webhook route handlers worked in Next.js 14 but are not working after upgrading to Next.js 15.4.3 (using the App Router), there are a few important changes and considerations:

  1. Route Handler Caching Behavior Changed in v15
    In Next.js 15, the default caching for GET route handlers changed from static to dynamic. However, for Stripe webhooks, you should be using a POST handler, which is not cached by default in either version. So, this change should not directly affect your webhook route, but it's important to be aware of for other handlers. If you have any GET handlers that need to be cached, you now need to explicitly opt-in using export const dynamic = 'force-static' in your route file How to upgrade to version 15 > Route Handlers.

  2. No Need for bodyParser or export const config in App Router
    In the App Router, you do not need to use bodyParser or export const config to access the raw request body. This was required in the Pages Router, but in the App Router, you can use the standard Web APIs directly. If you try to use export const config in your App Router route handler, you will get a build error STRIPE WEBHOOK - Cannot access request raw body with Javascript (request vs NextApiRequest).

#

Example for Stripe Webhook in App Router:

// app/api/webhook/route.ts
export async function POST(request: Request) {
  try {
    const rawBody = await request.text();
    // Use rawBody and request.headers['stripe-signature'] for Stripe verification
  } catch (error) {
    return new Response(`Webhook error: ${error.message}`, { status: 400 });
  }
  return new Response('Success!', { status: 200 });
}

You do not need to use any special config or body parser—just use the standard request.text() or request.json() as needed Webhooks Example.

  1. Check for Other Breaking Changes
    If your route handlers are still not working, double-check that:
    • Your route files are named correctly (e.g., route.ts or route.js).
    • They are placed inside the app directory, not pages.
    • You are using the correct HTTP method (POST for Stripe webhooks).
    • You are not using any deprecated configuration from the Pages Router.

If you follow the above, your Stripe webhook route handlers should work in Next.js 15 with the App Router. If you are still experiencing issues, please check for any error messages in your build or runtime logs, as they may indicate misconfiguration or other problems.

Summary:

  • Remove any export const config or bodyParser usage.
  • Use the standard Web API to read the request body.
  • Ensure your route handler is correctly placed and named.
#

If you need a working example, see the official docs for webhook route handlers and the related GitHub issue.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@cunning herald Kapa.ai is still learning and improving, please let me know how I did by reacting below.

cunning herald
#

@worthy wyvern write a simple ping route so i can test if its working in nextjs 15

worthy wyvernBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Certainly! Here’s a simple example of a "ping" route handler for Next.js 15 using the App Router. Place this file at app/api/ping/route.ts or app/api/ping/route.js:

export async function GET() {
  return Response.json({ message: 'pong' })
}

This will respond to a GET request at /api/ping with a JSON object { message: 'pong' }. This example follows the official Next.js 15 route handler conventions route.js API reference.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@cunning herald Kapa.ai is still learning and improving, please let me know how I did by reacting below.

cunning herald
#

@worthy wyvern

import { getSettingsByOrgId } from '@/app/data/organization_availability/get-availibilities'
import { getOrgIdByHash } from '@/app/data/route_logic/retrieve_orgId_by_hash'
import AppointmentBooking from '@/components/appointment'
import { notFound } from 'next/navigation'

type Params = {
hashedOrgId: string
}

export default async function BookingPage({ params }: { params: Params }) {
const { hashedOrgId } = params

const org = await getOrgIdByHash(hashedOrgId)
if (!org) notFound()

const business_settings = await getSettingsByOrgId(org.id)
if (!business_settings) notFound()

return (
<div>
<AppointmentBooking settings={business_settings} />
</div>
)
}

app/booking/[hashedOrgId]/page.tsx
Type error: Type '{ params: Params; }' does not satisfy the constraint 'PageProps'.
Types of property 'params' are incompatible.
Type 'Params' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]

Next.js build worker exited with code: 1 and signal: null

worthy wyvernBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

In Next.js 15, the params prop for dynamic routes is now a Promise rather than a plain object. This is a breaking change from Next.js 14. Your current code expects params to be an object, but the generated types expect it to be a Promise, which is why you see the type error:

Type '{ params: Params; }' does not satisfy the constraint 'PageProps'.
  Types of property 'params' are incompatible.
    Type 'Params' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]

How to fix:
Update your page component to expect params as a Promise<Params>, and use await to access its value:

type Params = {
  hashedOrgId: string
}

export default async function BookingPage({ params }: { params: Promise<Params> }) {
  const { hashedOrgId } = await params

  const org = await getOrgIdByHash(hashedOrgId)
  if (!org) notFound()

  const business_settings = await getSettingsByOrgId(org.id)
  if (!business_settings) notFound()

  return (
    <div>
      <AppointmentBooking settings={business_settings} />
    </div>
  )
}

This change is required for compatibility with Next.js 15 dynamic route pages, as documented in the official Next.js docs and confirmed by multiple community reports and GitHub issues Minimal Next.js Type Pollution Reproduction, params typed as Promise<any> in .next/types when using dynamic route server component.

Summary:

  • Change { params: Params } to { params: Promise<Params> }
  • Use const { hashedOrgId } = await params
#

This will resolve the type error and make your route compatible with Next.js 15.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: