Next.js Discord

Discord Forum

cors error deploying vercel

Answered
Briard posted this in #help-forum
Open in Discord
BriardOP
trying to deply my website to vercel but getting cors error http://localhost:3000/api/auth/sign-in/username

Access to fetch at 'http://localhost:3000/api/auth/sign-in/username' from origin 'https://tazhab-4r9typfhf-codecret-projects.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

next.config.ts
async headers() { return [ { source: "/api/:path*", headers: [ { key: "Access-Control-Allow-Origin", value: "*", // Set your origin }, { key: "Access-Control-Allow-Methods", value: "GET, POST, PUT, DELETE, OPTIONS", }, { key: "Access-Control-Allow-Headers", value: "Content-Type, Authorization", }, ], }, ]; },
Answered by Dutch
you can add a middleware to make it more specific
// ./middleware.ts
import { NextRequest, NextResponse } from 'next/server'
 
const allowedOrigins = ['https://acme.com', 'https://my-app.org']
 
const corsOptions = {
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
 
export function middleware(request: NextRequest) {
  // Check the origin from the request
  const origin = request.headers.get('origin') ?? ''
  const isAllowedOrigin = allowedOrigins.includes(origin)
 
  // Handle preflighted requests
  const isPreflight = request.method === 'OPTIONS'
 
  if (isPreflight) {
    const preflightHeaders = {
      ...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
      ...corsOptions,
    }
    return NextResponse.json({}, { headers: preflightHeaders })
  }
 
  // Handle simple requests
  const response = NextResponse.next()
 
  if (isAllowedOrigin) {
    response.headers.set('Access-Control-Allow-Origin', origin)
  }
 
  Object.entries(corsOptions).forEach(([key, value]) => {
    response.headers.set(key, value)
  })
 
  return response
}
 
export const config = { // <-- here is your filter
  matcher: '/api/:path*',
}
View full answer

36 Replies

Dutch
check your api
BriardOP
Access to fetch at 'https://domain-ecz3uowws-codecret-projects.vercel.app/api/auth/sign-in/username' from origin 'https://domain-ph82sfsq7-codecret-projects.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
BriardOP
i changed it
to my actuall domain
Dutch
no your api should have cors
BriardOP
im using betterauth
Dutch
not related
BriardOP
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

export const { GET, POST } = toNextJsHandler(auth.handler);
is it related to this
because this is my api/auth/route
Dutch
is it working at local
BriardOP
yes
Dutch
need to see your /api folder
BriardOP
that's it
Dutch
what is that blue file
BriardOP
its outside
BriardOP
yes that was route.ts inside my auth/[...all] directory
Dutch
do you have auth-client.ts
BriardOP
yes
import { createAuthClient } from "better-auth/react"; // make sure to import from better-auth/react
import { adminClient, usernameClient } from "better-auth/client/plugins";
import { inferAdditionalFields } from "better-auth/client/plugins";
import type { auth } from "./auth";
import { env } from "./env";
// check https://www.better-auth.com/ for more information
export const authClient = createAuthClient({
  baseURL: env.NEXT_PUBLIC_BETTER_AUTH_URL,
  plugins: [
    usernameClient(),
    adminClient(),
    inferAdditionalFields<typeof auth>(),
  ],
});

export type Session = typeof authClient.$Infer.Session;
export type User = Session["user"];
Dutch
can you add cors rules to there
or your next config
const nextConfig = {
  ...
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [
          { key: "Access-Control-Allow-Origin", value: "*" },
          { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT,OPTIONS" },
          { key: "Access-Control-Allow-Credentials", value: "true" },
          {
            key: "Access-Control-Allow-Headers",
            value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, x-auth-return-redirect",
          },
        ],
      },
    ];
  },
};
Dutch
nice to see that i still remember some things xd
Dutch
you can add a middleware to make it more specific
// ./middleware.ts
import { NextRequest, NextResponse } from 'next/server'
 
const allowedOrigins = ['https://acme.com', 'https://my-app.org']
 
const corsOptions = {
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
 
export function middleware(request: NextRequest) {
  // Check the origin from the request
  const origin = request.headers.get('origin') ?? ''
  const isAllowedOrigin = allowedOrigins.includes(origin)
 
  // Handle preflighted requests
  const isPreflight = request.method === 'OPTIONS'
 
  if (isPreflight) {
    const preflightHeaders = {
      ...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
      ...corsOptions,
    }
    return NextResponse.json({}, { headers: preflightHeaders })
  }
 
  // Handle simple requests
  const response = NextResponse.next()
 
  if (isAllowedOrigin) {
    response.headers.set('Access-Control-Allow-Origin', origin)
  }
 
  Object.entries(corsOptions).forEach(([key, value]) => {
    response.headers.set(key, value)
  })
 
  return response
}
 
export const config = { // <-- here is your filter
  matcher: '/api/:path*',
}
Answer
Dutch
also clerk is better than better auth
can we mark it as resolved @Briard