Macio33
Macio33

Reputation: 41

405 Method not allowed in Vercel and Cloudflare Domain

I'm getting a 405 Error (Method not allowed) in production but not local. My guess is the domain hosted by Cloudflare. I'm using the app router in next.js

VERCEL_URL: https://www.cloudflaredomain.app

page.tsx:

const baseUrl = process.env.VERCEL_URL
    ? `https://${process.env.VERCEL_URL}`
    : "";

const sendEmail = async (emailValue: string) => {
    await fetch(`${baseUrl}/api/addcontact`, {
      method: "PUT",
      body: JSON.stringify({
        emailValue,
      }),
    });

route.ts

import { NextRequest, NextResponse } from "next/server";
const client = require("@sendgrid/client");

client.setApiKey(process.env.NEXT_PUBLIC_SENDGRID_API_KEY);

export async function PUT(req: NextRequest) {
  const { emailValue } = await req.json();
  console.log(`${emailValue} is the email value`);
  const data = {
    contacts: [
      {
        email: emailValue,
      },
    ],
  };

  const request = {
    url: "/v3/marketing/contacts",
    method: "PUT",
    body: data,
  };

  try {
    const [response, body] = await client.request(request);
    console.log(response.statusCode);
    console.log(body);
    return NextResponse.json({ status: "Ok" });
  } catch (error) {
    console.error(error);
    return NextResponse.json({ message: "Error sending email" });
  }
}

I tried disabling the firewall and turned of the proxy in the dns settings

Upvotes: 0

Views: 497

Answers (1)

DMack
DMack

Reputation: 949

I ran into something similar yesterday. In my case, it was caused by CORS preflight headers getting rejected by Vercel. The frontend was on a different domain than the backend, so I configured vercel.json to allow CORs for my API functions (and set up some redirects). A (POST) endpoint worked fine with curl, but failed with a 405 in the browser.

I was using the method-specific function API, export async function POST(... as you're doing above with PUT. I noticed it still worked if I used the export default async function handler(... API instead. This made me think it wasn't the POST request getting rejected, but the OPTIONS request fromt he CORS preflight.

In my case, my theory was correct. I was able to get it working by adding a dummy function to handle the OPTIONS method below my POST handler.

export async function POST(req) {
  // ...
}

export async function OPTIONS() {
  return Response.json({
    message: 'ok',
  })
}

If doubling up methods is too much of a hassle, you can also use handler(req, res) (which runs for all HTTP methods). I can't find documentation for it anymore, or I'd link to it 🤔 It's similar to Express

export default async function handler(req, res) {
  res.json(...);
}

I never noticed this happening before, so it seems like it could be a bug with the platform. I'll update this answer if I learn anything else about it!

Upvotes: 0

Related Questions