在 Vercel 上获取本地和生产

Fetching local and production on Vercel

我有一个非常严肃的问题,我没有找到关于 Vercel (NextJS) 的答案。

我正在尝试在 Versel 上部署项目,我正在使用一些结构从 API 获取数据,示例:

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,
      },
  };
}

由于 fetch 仅使用 绝对 URL 路径 ,我需要用变量 process.env.APIpath 定义基础 url。

通过本地测试,我有 process.env.APIpath = 'http://localhost:3000/' 但是:我需要为 Vercel 部署定义一个生产变量,我正在使用无服务器函数.

关于Vercel的一些信息,根据这个documentation,我们实际上可以fetch数据。但是在部署过程中,我调用的页面总是报错fetch,例如:

//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)
})

由于 fetch,我遇到了错误。当然,我知道在部署期间 Vercel 无法构建生产版本,因为我使用的是“硬编码”process.env.APIpath.

如何明确定义 process.env.APIpath(或任何不同的构建变量)来部署项目?请注意,每次 Versel 生成通用项目 link 作为 nextjs-fhp5exsvo-testing.vercel.app.

P.S。我们很乐意提供任何帮助,已经有大约 5 天的部署问题了。

我是如何部分解决我的问题的

我没有使用 getStaticPropsgetServerSideProps 从 API 获取数据,而是使用 useSWR 库。此解决方案似乎适用于 localproduction 版本。

1.Change 到 useSWR 而不是 getStaticProps

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,
      },
  };
}

更改为 useSWRlocaltestproduction

的工作示例
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

注意:我不确定 useSWR 是否可以与 SEO 完美配合,但根据此 link,我们甚至可以将其与 SSR 一起使用。

2.Modifying MongoDB 设置。

由于我正在使用mongoDB,您需要正确check MongoDB settings。完成后,您需要 check your API routes(不是页面)在 /pages/api/[apiname].js 中。只有在 API 路由工作后(在 Vercel 上)我建议你开始编码你的本地版本。

3.Change 你在 Vercel 上的 deployment variables

您需要在 Vercel 上配置环境变量和其他一些变量。 More details here

您可以使用 Next.js 的相对路径从 api 路由中 fetch 数据。

直接来自Next.js documentation

function Profile() {
  const [data, setData] = useState(null)
  const [isLoading, setLoading] = useState(false)

  useEffect(() => {
    setLoading(true)
    fetch('api/profile-data')  // <-- relative path
      .then((res) => res.json())
      .then((data) => {
        setData(data)
        setLoading(false)
      })
  }, [])

  if (isLoading) return <p>Loading...</p>
  if (!profileData) return <p>No profile data</p>

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.bio}</p>
    </div>
  )
}

Next.js 文档也明确推荐使用 SWR,就像@ChilTest 的回答所建议的那样。也就是说,相对路径并不是一个特殊的 SWR-only 特性。