Failed to Parse URL
Used in this guide:Next.js 15.3.4
Introduction
This error occurrs when a relative URL is used in a server environment
Error:
Failed to parse URL from /api/web-users/me
In this example, fetch('/api/web-users/me', {...}) is being run in an environment that does not recognize relative URLs - most likely on the server side (e.g., in a Next.js server component or a server utility).
Why this happen?
In Node.js (or server-side code), the fetch function requires an absolute URL like:
fetch('http://localhost:3000/api/web-users/me')But relative URL (/api/web-users/me) only works in the browser environment.
Error Example:
import { WebUser } from "@/payload-types";
export async function getOwnUser(): Promise<{ user: WebUser | null; error: string | null }> {
try {
const res = await fetch(`/api/web-users/me`, { // <- using relative URL in a server environment
method: "GET",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
});
if (!res.ok) {
throw new Error(`Error in try: ${res.status} ${res.statusText}`);
}
const data = await res.json();
return {
user: data.user,
error: null
};
} catch (error) {
console.error("Error in catch: ", (error as Error).message);
return {
user: null,
error: (error as Error).message,
}
}
}Solution:
If this needs to run on the server, update the URL to an absolute URL:
import { WebUser } from "@/payload-types";
export async function getOwnUser(): Promise<{ user: WebUser | null; error: string | null }> {
try {
const rootUrl = process.env.NODE_ENV === "development"
? process.env.NEXT_PUBLIC_ROOT_URL_DEV
: process.env.NEXT_PUBLIC_ROOT_URL_PROD;
const res = await fetch(`${rootUrl}/api/web-users/me`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
});
if (!res.ok) {
throw new Error(`Error in try: ${res.status} ${res.statusText}`);
}
const data = await res.json();
return {
user: data.user ?? null,
error: null
};
} catch (error) {
console.error("Error in catch: ", (error as Error).message);
return {
user: null,
error: (error as Error).message,
}
}
}Bonus: Using the getOwnUser function
"use client"
import { useEffect, useState } from "react"
import { getOwnUser } from "@/lib/payload/getOwnUser"
import { WebUser } from "@/payload-types"
export default function TestPageClient() {
const [user, setUser] = useState<WebUser | null>(null)
useEffect(() => {
const fetchOwnUser = async () => {
const { user, error } = await getOwnUser();
console.log(user);
console.log(error);
setUser(user);
}
fetchOwnUser();
}, [])
return (
<main>
<h1>Test Page</h1>
<p>Name: {user?.firstName}</p>
</main>
)
}