How to Create an External React Router Link to a Different Domain in Next.js

Use a fully qualified URL (e.g., https://example.com) with the Next.js <Link> component, which automatically renders a standard anchor tag and disables prefetching for external domains.

While Next.js utilizes its own routing architecture rather than React Router, the framework provides a built-in <Link> component capable of handling both internal navigation and external URLs. According to the vercel/next.js source code, linking to a different domain requires no additional configuration—simply pass an absolute URL to the component. This approach leverages automatic external-domain detection to render standard HTML anchor behavior while bypassing the framework's internal prefetching mechanisms.

The <Link> component in packages/next/src/client/app-dir/link.tsx accepts any valid URL string through its href prop. When you provide a fully qualified external URL, the component treats the link as a standard HTML anchor rather than an internal route.

As documented in the source code comments at lines 52-55, the component explicitly supports external navigation by accepting "a fully qualified URL such as https://…". This design allows you to use the same component API for both internal application navigation and external domain links without importing additional dependencies.

import Link from 'next/link';

export default function Navigation() {
  return (
    <nav>
      {/* Internal navigation - uses Next.js router */}
      <Link href="/about">About Us</Link>

      {/* External navigation - renders as standard anchor */}
      <Link href="https://example.com">
        Visit External Site
      </Link>
    </nav>
  );
}

Next.js intentionally excludes external URLs from its prefetching optimization system. In packages/next/src/client/components/links.ts, the mountLinkInstance function checks whether a URL is prefetchable through a validation process involving coercePrefetchableUrl.

External domains fail this validation check, causing the router to skip visibility observation and prefetch initiation for these links. This architectural decision prevents wasted network requests to domains outside your application's control while maintaining optimal performance for internal navigation.

The prefetch exclusion logic at lines 76-79 ensures that only internal routes—those resolvable against your application's route manifest—receive the benefits of Next.js's automatic prefetching behavior.

Implementation Examples for External Domains

When linking to external domains, you can apply standard anchor attributes such as target, rel, and className because the component spreads unknown props onto the underlying <a> element.

import Link from 'next/link';

export default function Footer() {
  return (
    <Link href="https://github.com/vercel/next.js">
      View Next.js on GitHub
    </Link>
  );
}

Opening in a New Tab

For security and performance best practices, always include rel="noopener noreferrer" when using target="_blank":

<Link 
  href="https://example.com" 
  target="_blank" 
  rel="noopener noreferrer"
>
  Open in New Tab
</Link>

Dynamic External URLs

interface Props {
  externalUrl: string;
  label: string;
}

export default function ExternalButton({ externalUrl, label }: Props) {
  return (
    <Link 
      href={externalUrl}
      className="external-link-button"
      target="_blank"
      rel="noopener noreferrer"
    >
      {label}
    </Link>
  );
}

Understanding how Next.js distinguishes between these navigation types helps optimize your application's performance and behavior:

  • Internal Links: Use relative paths (e.g., /about) or same-domain absolute paths. These trigger the Next.js router, support prefetching, and enable client-side navigation without full page reloads.
  • External Links: Use fully qualified URLs with protocols (e.g., https://). These render as standard HTML anchor tags, bypass the router's prefetch logic in packages/next/src/client/components/links.ts, and trigger full browser navigation.

Summary

  • Pass absolute URLs (starting with http:// or https://) to the <Link> component to create external links to different domains.
  • External links automatically render as standard <a> tags and bypass Next.js's prefetching system as implemented in packages/next/src/client/components/links.ts.
  • The component accepts all standard anchor attributes including target="_blank" and rel="noopener noreferrer".
  • No additional configuration is required—the framework detects external domains automatically based on URL structure.
  • This behavior works consistently across both the App Router and Pages Router architectures.

Frequently Asked Questions

Yes. The <Link> component in packages/next/src/client/app-dir/link.tsx explicitly supports external URLs by accepting fully qualified domain names. When you provide an absolute URL starting with https://, the component renders a standard HTML anchor tag instead of using the internal router.

Next.js deliberately excludes external domains from prefetching to conserve bandwidth and prevent unnecessary requests to third-party servers. The mountLinkInstance function in packages/next/src/client/components/links.ts validates URLs through coercePrefetchableUrl, and external domains fail this check, causing the router to skip prefetch observation.

While standard <a> tags work for external links, using Next.js's <Link> component provides consistency in your codebase and ensures proper prop spreading. The component handles external URLs correctly by rendering as an anchor tag internally, so either approach functions identically in the browser. However, using <Link> allows you to maintain uniform import patterns and styling logic across your application.

Does this work in both App Router and Pages Router?

Yes. The external link handling behavior is consistent across both routing architectures. The packages/next/src/client/app-dir/link.tsx implementation (used by App Router) and the Pages Router equivalent both detect external URLs and render them as standard anchor tags without prefetching.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →