issues with invalid url on first deploy to vercel
Unanswered
Brown bear posted this in #help-forum
Brown bearOP
I have a standard next js app using app router and I am tryign to do the first deployment.
There is external API on heroku and I am using the NextJS API routes as an API Gateway.
So right now I have the following flow:
there is a service that calls
there is a
the route handler then does a fetch to external api.
everything works fine in localhost, if i specifcy the host ie:
What I think is happening is that on the first deploy when it tries to build the pages and it calls the fetch to the nextjs /api route it is failing because there is currently no appliaction deployed (ie the route doesn't exist yet and there is no app on vercel yet because its the first deploy)
on local if i run build it all works fine, I also have an env.local where i can specify the host
What is the right way of setting up the fetch call to the nextjs api routes so that it works on the first deploy and onward.
There is external API on heroku and I am using the NextJS API routes as an API Gateway.
So right now I have the following flow:
app/<resource>/page.tsx (server component) there is a service that calls
/api/<resource>/there is a
/app/api/<resource>/route.tsthe route handler then does a fetch to external api.
everything works fine in localhost, if i specifcy the host ie:
http://localhost:3000/api/<resource>/ but when I go to deploy it fails with invalid url.What I think is happening is that on the first deploy when it tries to build the pages and it calls the fetch to the nextjs /api route it is failing because there is currently no appliaction deployed (ie the route doesn't exist yet and there is no app on vercel yet because its the first deploy)
on local if i run build it all works fine, I also have an env.local where i can specify the host
export const nextApi = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
timeout: TIMEOUT,
headers: {
Accept: "application/json",
},
});
# API GATEWAY
NEXT_PUBLIC_API_URL=http://localhost:3000/api. // works just fine, but i cant add the url for the app in vercel env because it doesnt exist yet, causing it to fail with invalid url
// trie this as well
NEXT_PUBLIC_API_URL=/api // fails in local and deployment with invalid url What is the right way of setting up the fetch call to the nextjs api routes so that it works on the first deploy and onward.
38 Replies
Brown bearOP
import ListingsList from "@/components/listings/listings-list";
import ListingListItem from "@/components/listings/listings-list-item";
import { getAllListingsPublic } from "@/lib/models/listings/queries";
import { type ListingsResponse } from "@/types/api/listings";
export default async function PublicListingsPage() {
const res: ListingsResponse = await getAllListingsPublic();
const listings = res.data;
return (
<div>
<h1>Listings</h1>
<ListingsList listings={listings}>
{(listing) => <ListingListItem listing={listing} />}
</ListingsList>
</div>
);
}Im just pulling the data from external api through the internal nextjs api route
show your getAlllistingsPublic
func
Brown bearOP
// Public
export const getAllListingsPublic = async (): Promise<
ListingsResponse | any
> => {
try {
const response = await nextApi.get("/listings");
return handleSuccess(response);
} catch (error) {
return handleError(error);
}
};/listings is a route handler?
Brown bearOP
import { apiV1 } from "@/lib/services";
import { ListingsResponse } from "@/types/api/listings";
export async function GET(req: Request) {
try {
const response: ListingsResponse = await apiV1.get("/listings");
return Response.json(response.data);
} catch (error: any) {
return new Response(JSON.stringify(error), { status: 400 });
}
}so the comp calls the listings route.ts which then sends a call to external api
you should not fetch your own route handler trough your ssr components
keep the fetching logic outside of your route handler
and use that in your ssr component
it works on localhost but will not work on production
Brown bearOP
ok, but what if that route was calling a db that was external, woudlnt that fail as well?
you can keep your route for your clientside operations
the actual logic u should keep in a seperate file
and use it in your route handler aswell as in your ssr component
Brown bearOP
but if you import the file into the route, how does that solve the problem?
so basically i cannot use the nextjs api routes as an api gateway to hide the actual external api calls?
unless i do that on the client side
@Brown bear so basically i cannot use the nextjs api routes as an api gateway to hide the actual external api calls?
u dont need to hide anything in ssr components
it runs only on server
i told u the fix above
Brown bearOP
ok so basically call the external api directly in the ssr comps and only use the nextjs api routes if im fetching in a useEffect or something client side
but have a function calling your api
and use that in your route handler aswell
halves the amount of work
Brown bearOP
ok got it, yea ive setup a config for the external serivce already its just a matter of referencing api_v1 vs next_api
export const apiV1 = axios.create({
baseURL: process.env.NEXT_PUBLIC_V1_API_BASE,
timeout: TIMEOUT,
headers: {
Accept: "application/json",
},
});basically
export async function getListings() {
try {
const response: ListingsResponse = await apiV1.get("/listings");
return response.data
} catch (error: any) {
return null // something different here
}
}u use your code from your route handler in a seperate function
now u can call that code in your ssr component and in your route handler
apiV1 in this case is your external api
which will work perfectly
Brown bearOP
yea thats what I had in mind, thanks @gin
u can mark my message as solution