How to Fix: ` ` tag is used, instead of ` … ` tag in basic template generated while creating a new next project.

5 min read

The generated Next.js starter can show a plain <a> tag in app/page.tsx, and that looks wrong if you expect every internal navigation link to use <Link>. The key detail is that this starter markup often contains links that are not acting as client-side route transitions, or it was generated from a template snapshot where semantics, external navigation, and App Router behavior were prioritized differently than older examples. If you want consistent internal routing behavior, the fix is straightforward: replace internal anchor usage with next/link where appropriate and keep plain anchors only for external destinations.

Understanding the Root Cause

This issue appears in the basic template generated by a new Next.js project because the template content is not always meant to demonstrate every recommended navigation pattern. In modern Next.js, especially with the App Router, the distinction is:

  • Use <Link> from next/link for internal navigation between routes in your app.
  • Use a plain <a> tag for external links, downloads, fragment jumps, or cases where browser-native navigation is intended.

Technically, next/link enhances navigation by enabling client-side transitions, prefetching, and preserving app state more smoothly. A raw anchor tag triggers a standard browser navigation unless the destination is external or intentionally full-page. If the template uses <a> for something that points to an internal route, then the generated code is inconsistent with Next.js best practice.

Why this happens:

  • The starter template may have been authored for visual simplicity rather than routing guidance.
  • Some links in starter files point to external resources, where <a> is actually correct.
  • Template revisions can lag behind framework conventions or mix examples from different Next.js versions.
  • With the App Router, developers often assume every visible link should be a <Link>, but only internal route transitions need it.

So the real bug is not that <a> exists at all. The bug is using it where the destination is an internal application route and the expected behavior is Next.js client-side routing.

Step-by-Step Solution

Audit the generated app/page.tsx file and convert only the internal anchors to <Link>.

If the href points to something like /about, /dashboard, or another route in your app, use Link. If it points to documentation, GitHub, or another domain, keep <a>.

import Link from 'next/link'

3. Replace internal anchor tags

Before

export default function Page() {
  return (
    <main>
      <a href="/about">Go to About</a>
    </main>
  )
}

After

import Link from 'next/link'

export default function Page() {
  return (
    <main>
      <Link href="/about">Go to About</Link>
    </main>
  )
}
export default function Page() {
  return (
    <main>
      <a
        href="https://nextjs.org/docs"
        target="_blank"
        rel="noopener noreferrer"
      >
        Read the docs
      </a>
    </main>
  )
}

5. Apply this to the generated starter template

If your starter contains a mix of links, update only those that target internal pages. A cleaned-up example looks like this:

import Link from 'next/link'

export default function Home() {
  return (
    <main>
      <h1>Welcome</h1>
      <nav>
        <ul>
          <li>
            <Link href="/about">About</Link>
          </li>
          <li>
            <Link href="/contact">Contact</Link>
          </li>
          <li>
            <a
              href="https://nextjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Next.js Website
            </a>
          </li>
        </ul>
      </nav>
    </main>
  )
}

6. Verify the result

  • Run your app locally.
  • Click internal links and confirm navigation is instant and handled without a full page refresh.
  • Check that external links still open correctly.

If you are maintaining a starter template or contributing upstream, this is the expected remediation:

import Link from 'next/link'

// Replace
<a href="/internal-route">Internal Page</a>

// With
<Link href="/internal-route">Internal Page</Link>

Common Edge Cases

This is a common overcorrection. Do not replace every anchor with Link. External destinations should remain plain anchors, especially when using target="_blank".

If the link is something like #features, a plain anchor is usually fine. It is not a route transition in the Next.js sense.

Links such as mailto:support@example.com or tel:+123456789 should remain <a> tags.

4. Legacy assumptions from older Next.js versions

Older codebases sometimes use nested patterns like <Link><a>...</a></Link>. In current Next.js, that is generally unnecessary. The preferred pattern is:

<Link href="/about">About</Link>

5. Styling differences after replacement

If your CSS targeted only anchor selectors, replacing an anchor with Link still renders an anchor under the hood, but verify class names and component structure if custom wrappers are involved.

6. Server and client component confusion

next/link works in App Router components without requiring you to convert the page into a client component. This is often misunderstood by developers migrating from older React router patterns.

7. False positives in starter code review

Not every visible anchor in the default template is a bug. If it points to official docs, deployment platforms, or templates outside your app, the anchor is correct and should stay.

FAQ

No. Use <Link> for internal routes inside your Next.js application. Use plain <a> tags for external links, downloads, email links, telephone links, and hash fragments.

Why does internal navigation matter if an anchor still works?

A raw anchor works, but it triggers standard browser navigation. next/link enables client-side routing, faster transitions, and route prefetching, which is the expected optimized behavior in Next.js.

Is this a framework bug or just template behavior?

In most cases, this is better described as a template inconsistency rather than a routing engine bug. The framework still behaves correctly; the generated starter code may simply not reflect the best internal linking pattern for that specific case.

In short, the correct fix is to review the generated template and replace only internal <a> tags with <Link>. That preserves proper semantics for external navigation while restoring the optimized routing behavior expected in a modern Next.js app.

Leave a Reply

Your email address will not be published. Required fields are marked *