How to Use LinkProvider for Next.js and React Router with Astryx

Wrap your application in LinkProvider and pass your routing library's Link component to replace the default <a> element across all Astryx Link components.

The LinkProvider in Astryx enables framework-agnostic navigation by injecting a custom link component through React context. This lets you use Next.js next/link or React Router's Link throughout your Astryx UI without modifying individual components.


How LinkProvider Works

Astryx delegates rendering to a provider-driven architecture:

  1. Context creationLinkProvider instantiates LinkContext defined in packages/core/src/Link/LinkContext.ts, storing a component value that defaults to undefined.

  2. Component resolution – The useLinkComponent hook in packages/core/src/Link/Link.tsx reads this context. When a component exists, it renders that; otherwise it falls back to a native <a> element.

  3. Polymorphic rendering – The Link component accepts an as prop (as?: LinkComponentType) for per-instance overrides, bypassing the provider when needed.

  4. Button fallback – When href is omitted, Link renders a <button> with link styling via the internal renderAsButton logic, maintaining accessibility while preserving provider-based behavior.

This pattern keeps Astryx styling intact—including color variants, underline handling, disabled states, and tooltips—while delegating navigation to your chosen framework.


Using LinkProvider with Next.js

Pass next/link to LinkProvider at your application's root to convert all Astryx Link components to Next.js navigation.

// app/layout.tsx
import NextLink from 'next/link';
import { LinkProvider } from '@astryxdesign/core';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <LinkProvider component={NextLink}>
          {children}
        </LinkProvider>
      </body>
    </html>
  );
}

All Astryx Link components now use Next.js routing:

import { Link } from '@astryxdesign/core';

function Nav() {
  return (
    <>
      {/* Internal client-side navigation */}
      <Link href="/dashboard">Dashboard</Link>

      {/* External links still work correctly */}
      <Link href="https://github.com/facebook/astryx" isExternalLink>
        GitHub
      </Link>
    </>
  );
}

Astryx props like hasUnderline, color, and tooltip continue to function normally while Next.js handles the actual navigation.


Using LinkProvider with React Router

The same pattern applies to React Router—provide Link from react-router-dom to enable SPA navigation.

// src/App.tsx
import { BrowserRouter } from 'react-router-dom';
import { LinkProvider } from '@astryxdesign/core';
import { Link as RouterLink } from 'react-router-dom';

export default function App() {
  return (
    <BrowserRouter>
      <LinkProvider component={RouterLink}>
        {/* Your application components */}
      </LinkProvider>
    </BrowserRouter>
  );
}
import { Link } from '@astryxdesign/core';

function Sidebar() {
  return (
    <nav>
      {/* React Router navigation */}
      <Link href="/settings">Settings</Link>

      {/* Button-style link without navigation */}
      <Link onClick={() => alert('Action triggered')}>Do Action</Link>
    </nav>
  );
}

The href prop maps to React Router's to prop automatically through Astryx's internal prop handling.


Use the as prop to bypass the provider for specific instances:

import { Link } from '@astryxdesign/core';
import NextLink from 'next/link';

function MixedRouting() {
  return (
    <>
      {/* Uses provider default (React Router in this tree) */}
      <Link href="/standard">Standard Route</Link>

      {/* Forces Next.js Link regardless of provider */}
      <Link href="/next-page" as={NextLink} color="primary" hasUnderline>
        Next.js Page
      </Link>
    </>
  );
}

This is useful for incremental migrations, micro-frontends, or linking between different routing domains.


LinkComponentType Contract

Any component passed to LinkProvider must satisfy the LinkComponentType interface defined in packages/core/src/Link/types.ts:

  • Accepts href (or to)
  • Accepts className and style for styling
  • Accepts children for content
  • Forwards remaining props appropriately

Both Next.js Link and React Router Link conform to this contract without adaptation.


Summary

  • Single configuration – Set LinkProvider once at your app root to switch routing implementations
  • Framework flexibility – Use Next.js, React Router, Remix, or any custom link component
  • Preserved styling – All Astryx visual features remain functional
  • Per-link control – Override with the as prop when needed
  • Source locations – Implementation lives in LinkProvider.tsx, LinkContext.ts, and Link.tsx

Frequently Asked Questions

What happens if I don't use LinkProvider?

Without LinkProvider, Astryx Link components fall back to standard <a> elements. Navigation works for external URLs and full page loads, but client-side routing features like prefetching and SPA transitions won't function.

Can I nest LinkProviders?

Yes. LinkContext follows standard React context scoping—nested providers override parent configurations for their subtree. This enables mixed-routing scenarios like a Next.js shell with embedded React Router micro-apps.

No. When isExternalLink is true, Astryx prioritizes correct external link behavior and may bypass certain provider transformations to ensure security and accessibility standards are met.

Is LinkProvider required for Remix or TanStack Router?

No. The LinkProvider architecture is routing-library agnostic. Pass Remix's Link from @remix-run/react or TanStack Router's Link component the same way you would with Next.js or React Router.

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 →