Relative vs Absolute Path Bugs in Next.js ?

Next.jsReactDebugging
May 15, 2025·4 min read
Relative vs Absolute Path Bugs in Next.js ?

So there I was, happily building the blog section of my portfolio. Everything was going smoothly — until I noticed something odd.

On the /en page, blog links pointed correctly to /en/blogs/article-name. But when I opened /en/blogs, the same links suddenly pointed to /en/en/blogs/article-name. A duplicated /en. Something was clearly wrong.

Investigation

I started suspecting the Blog component — specifically the href:

<Link href={`${lang}/blogs/${blog.slug}`}>{blog.frontmatter.title}</Link>

Looks fine at first glance. But then I noticed — there's no leading /. I changed it to:

<Link href={`/${lang}/blogs/${blog.slug}`}>{blog.frontmatter.title}</Link>

Fixed immediately. That simple. But why?

Why Does This Happen?

Turns out this isn't a Next.js bug — it's standard URL behavior that has existed since the early days of the web.

Without a leading /, the browser treats it as a relative path — calculated relative to the current page's URL.

Current URL: /en
href: en/blogs/article
result: /en/blogs/article ✅

Current URL: /en/blogs
href: en/blogs/article
result: /en/blogs/en/blogs/article ❌

With a leading /, the browser treats it as an absolute path — always calculated from root, regardless of the current page.

Current URL: /en          → /en/blogs/article ✅
Current URL: /en/blogs    → /en/blogs/article ✅
Current URL: /en/projects → /en/blogs/article ✅

Does the Next.js Docs Mention This?

I went straight to the Next.js documentation. The answer — not explicitly.

The Next.js docs on <Link> only show examples with absolute paths like /about and /blog/post, without ever specifically warning about the dangers of relative paths. This behavior is assumed to be common web knowledge — not something that needs re-explaining.

So if you're expecting Next.js to warn you about this — it won't. This is fundamental URL knowledge that can still catch us off guard, especially when we're focused on something else entirely.

The lesson I took away: if there's a dynamic segment like lang in your URL, always use absolute paths.

// ❌ don't
href={`${lang}/blogs/${slug}`}
 
// ✅ always
href={`/${lang}/blogs/${slug}`}

And for global or reusable components used across multiple pages — make sure every href passed in always starts with /. The responsibility lies with the caller, not the component itself.


Moral of the story: sometimes the simplest bugs are the ones that take the longest to find. And yes — looks like I need to read the documentation more carefully. Lol.