Nextjs15 CORs: i keep getting blocked
Answered
Chilean Terrier posted this in #help-forum
Chilean TerrierOP
Access to fetch at 'https://my_domain.com/api/petLevel' from origin 'https://www.my_domain.com' has been blocked by CORS policy: 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.
i've put the headers. see the image
Answered by Black Turnstone
maybe
instead of hard coding
you can just pass
instead of hard coding
const apiUrl =
process.env.NODE_ENV === "development"
? "http://localhost:3000/api/petLevel"
: "https://hhr-bot.xyz/api/petLevel";
you can just pass
const apiUrl = '/api/petLevel';
13 Replies
Black Turnstone
Can you share some code for api and for how you are fetching it in component?
@Black Turnstone Can you share some code for api and for how you are fetching it in component?
Chilean TerrierOP
import { createClient } from "@supabase/supabase-js";
import { NextResponse } from "next/server";
const supabaseKey = process.env.SUPABASE_KEY as string;
const supabaseUrl = process.env.SUPABASE_URL as string;
console.log(supabaseUrl);
const supabase = createClient(supabaseUrl, supabaseKey);
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const limit = searchParams.get("limit");
let query = supabase.from("pet_lvl_lb").select("*");
if (limit) {
const limitValue = parseInt(limit);
if (!isNaN(limitValue) && limitValue > 0) {
query = query.limit(limitValue);
}
}
const { data, error } = await query;
if (error) {
console.error("Error fetching data from Supabase:", error);
return NextResponse.json(
{ error: "Failed to fetch data" },
{
status: 500,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Credentials": "true",
},
}
);
}
return NextResponse.json(data, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Credentials": "true",
},
});
} catch (error) {
console.error("Internal Server Error:", error);
return NextResponse.json(
{ error: "Internal Server Error" },
{
status: 500,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Credentials": "true",
},
}
);
}
}
Black Turnstone
component?
@Black Turnstone component?
Chilean TerrierOP
/* eslint-disable */
'use client';
import type { Metadata } from "next";
import { useEffect, useState } from "react";
import { Pet, columns } from "./columns";
import { DataTable } from "./data-table";
const metadata: Metadata = {
title: "Pet Level Leaderboard",
description:
"See the pet level rankings in the game.",
};
export default function PetLeaderboardPage() {
const [petsData, setPetsData] = useState<Pet[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const apiUrl =
process.env.NODE_ENV === "development"
? "http://localhost:3000/api/petLevel"
: "https://hhr-bot.xyz/api/petLevel";
useEffect(() => {
async function fetchPetsData() {
try {
const res = await fetch(apiUrl, { cache: "no-store" });
if (!res.ok) {
throw new Error("Failed to fetch data");
}
const data: Pet[] = await res.json();
const formattedData = data.map((pet) => ({
pet_name: pet.pet_name,
level: Number(pet.level).toLocaleString(),
type: pet.type,
rank: pet.rank,
}));
setPetsData(formattedData);
} catch (err) {
if (err instanceof Error) {
setError(err.message);
} else {
setError("An unknown error occurred.");
}
} finally {
setLoading(false);
}
}
fetchPetsData();
}, [apiUrl]);
if (loading) {
return (
<div className="text-center text-lg text-gray-600 mt-10">
Loading...
</div>
);
}
if (error) {
return (
<div className="text-center text-red-600 text-lg mt-10">
Error: {error}
</div>
);
}
return (
<div className="container mx-auto py-10">
<DataTable columns={columns} data={petsData} />
</div>
);
}
Black Turnstone
Working in dev env?
@Black Turnstone Working in dev env?
Chilean TerrierOP
yes.
wait... let me qq fetch latest code from main.
Black Turnstone
maybe
instead of hard coding
you can just pass
instead of hard coding
const apiUrl =
process.env.NODE_ENV === "development"
? "http://localhost:3000/api/petLevel"
: "https://hhr-bot.xyz/api/petLevel";
you can just pass
const apiUrl = '/api/petLevel';
Answer
Black Turnstone
No need to write full url since fetching on client component it will automatically look for hostname.
@Chilean Terrier wait... let me qq fetch latest code from main.
Chilean TerrierOP
even still it works on dev, but not on main prod website
@Chilean Terrier even still it works on dev, but not on main prod website
Black Turnstone
probably because you are fetching
https://hhr-bot.xyz/api/petLevel
from https://www.hhr-bot.xyz/
-> that www makes a difference@Black Turnstone maybe
instead of hard coding
ts
const apiUrl =
process.env.NODE_ENV === "development"
? "http://localhost:3000/api/petLevel"
: "https://hhr-bot.xyz/api/petLevel";
you can just pass
ts
const apiUrl = '/api/petLevel';
Chilean TerrierOP
after changing the apiUrl format works, thank you!