I have a really serious question I didn't find the answer about Vercel (NextJS).
I am trying to deploy the project on Versel and I am using some structures to get data from API, example:
export async function getStaticProps(context) {
const route = process.env.APIpath + 'api/category/getCategories'; //focusing here, ok on localhost
const res = await fetch(route)
const json = await res.json()
return {
props: {
data: json,
},
};
}
As fetch
is using only absolute URL path, I need to define base url with variable process.env.APIpath
.
With local testing I have process.env.APIpath = 'http://localhost:3000/'
but: I need to define a production variable for Vercel deployment and I am using serverless functions.
Some info about Vercel, according to this documentation, we can actually fetch
the data. But during the deployment process, I always have errors on the pages where I am calling fetch
, for example:
//this code triggers an error as code shown above, ok on localhost
const res = await fetch(process.env.APIpath + 'api/category/getCategory?_id='+ pid, {
method: 'post',
body: JSON.stringify(values, null, 2)
})
I am getting errors because of fetch
. Of course, I understand that during the deployment Vercel can't build the production version as I am using "hardcoded" process.env.APIpath
.
How can I define clearly the process.env.APIpath
(or any different built variables) to deploy the project? Please, note that every time Versel generates generic project link as nextjs-fhp5exsvo-testing.vercel.app
.
P.S. Will be happy for any help, having an issue with deployment for about 5 days already.
How I partially solved my issue
Instead of using getStaticProps
and getServerSideProps
to fetch data from API, I am using useSWR
library. This solution seems to be good with local
and production
versions.
1.Change to useSWR
instead of getStaticProps
not working code with getStaticProps
export async function getStaticProps(context) {
const route = process.env.APIpath + 'api/category/getCategories';
const res = await fetch(route)
const json = await res.json()
return {
props: {
data: json,
},
};
}
changed to useSWR
, working example for local
, test
, and production
import useSWR from 'swr'
import React from 'react';
//important to return only result, not Promise
const fetcher = (url) => fetch(url).then((res) => res.json());
const Categories = () => {
//getting data and error
const { data, error } = useSWR('/api/category/getCategories', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
if (data){
// {data} is completed, it's ok!
//your code here to make something with {data}
return (
<div>
//something here, example {data.name}
</div>
)
}
}
export default Categories
Notice: I am not sure that useSWR
will work perfectly with SEO
, but according to this link, we can even use it with SSR
.
2.Modifying MongoDB settings.
As I am using mongoDB
, you need to check MongoDB settings
properly. Once u did it, you need to check your API routes
(not pages) are in /pages/api/[apiname].js
. Only after API routes work (on Vercel) I suggest you start coding your local version.
3.Change your deployment variables
on Vercel.
You need to configure environment variables and some others on Vercel. More details here