When you call fetch(/api/users)
with a relative path on the browser, it works because it is using the origin of the document to have fetch(https://your-domain.com/api/users)
.
However, in Node.js, where your server-side fetch is happening, there is no similar behaviour. It expects a fully defined URL. It's not related to Server Components, in fact, you get the same error in functions like getServerSideProps
in the pages
directory.
You can read more about it if you want on this GitHub Issue.
I would suggest you use an environment variable to smoothly go to production, where you may have a different URL.
app/page.js:
const getUsers = async () => {
const result = await fetch(process.env.URL + '/api/users', {method: 'GET'});
if (result.ok) {
return result.json();
}
return [];
}
export default async function IndexPage() {
const users = await getUsers();
return (<h1>Users: {users.length}</h1>);
}
.env:
URL="http://localhost:3001"
You just change the URL variable later on in your hosting service admin.
That has been said, you may still get another error at build time if you are calling an internal API route from a server component. Because at that time, there might be no application running (the application being build and not deployed yet).
Tim Neutkens from Next.js points that out in this GitHub issue:
This is because you're trying to fetch from an internal api route during build, which is not supported.
Instead of calling the internal API route from a server component, which then calls your DB or CMS, reach them directly from the component. It helps avoid the error, and also an additional useless API call.
VERCEL_URL
your build might fail if you have a "custom" vercel.app subdomain.VERCEL_URL
is the deployment-specific subdomain, not the vercel.app subdomain you picked out. For me it was causingfetch()
to fail with a "Unexpected token < in JSON at position 0" error. I just had to hardcode my vercel custom domain. – Unmoor