Reputation: 4394
I have a route that I may call either from server side rendering, or from client:
export const getFooBar = async (): Promise<any> => {
const res = await fetch(`/foo/bar`, {
method: 'GET',
headers: CONTENT_TYPE_JSON,
})
if (!res.ok) {
//do something
}
//do something else
}
If I call this function from the server:
export const getServerSideProps: GetServerSideProps = async () => {
getFooBar().then(() => {
//do something
})
}
I got an error on because it is not an absolute URL. Solution is to create another function with slightly different URI:
export const getFooBar = async (): Promise<any> => {
const res = await fetch(`http://myapp/foo/bar`, {
method: 'GET',
headers: CONTENT_TYPE_JSON,
})
if (!res.ok) {
//do something
}
//do something else
}
Or to pass a prefix URL argument in getFooBar
.
But is there a more generic way to add the absolute URL part if it's coming from server side rendering?
Upvotes: 1
Views: 737
Reputation: 50308
The proxy you have set up in next.config.js
is only relevant for client-side requests. For requests initiated on the server (like inside getServerSideProps
) you should directly call the external API.
Given the APP_API
environment variable is not exposed to the browser (it's not prefixed with NEXT_PUBLIC_
), you could use that as a condition to either use the direct API endpoint on the server, or point to the proxy endpoint on the client.
export const getFooBar = async (): Promise<any> => {
const url = process.env.APP_API ? `http://${process.env.APP_API}/bar` : '/foo/bar'
const res = await fetch(url, {
method: 'GET',
headers: CONTENT_TYPE_JSON,
})
// Remaining code
}
Note that you could also use other conditions to verify if you're in the client or server, for example using typeof window === 'undefined'
.
Upvotes: 1