在 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 天的部署问题了。
我是如何部分解决我的问题的
我没有使用 getStaticProps
和 getServerSideProps
从 API 获取数据,而是使用 useSWR
库。此解决方案似乎适用于 local
和 production
版本。
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,
},
};
}
更改为 useSWR
,local
、test
和 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
注意:我不确定 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
数据。
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 特性。
我有一个非常严肃的问题,我没有找到关于 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 天的部署问题了。
我是如何部分解决我的问题的
我没有使用 getStaticProps
和 getServerSideProps
从 API 获取数据,而是使用 useSWR
库。此解决方案似乎适用于 local
和 production
版本。
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,
},
};
}
更改为 useSWR
,local
、test
和 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
注意:我不确定 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
数据。
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 特性。