Search code examples
reactjsdeploymentfetchnext.jsvercel

Fetching local and production on Vercel


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.


Solution

  • 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