/** * `next/link` shim — environment-aware Link component. * * Defaults to a plain `` so non-Next hosts (Vite, CRA, esbuild) * work out of the box. Next.js hosts can opt into the REAL `next/link` * (with client-router prefetching) by calling {@link registerLink} * ONCE at app init: * * // hub: lib/embed-shim-registration.ts * import NextLink from 'next/link' * import { registerLink } from '@flamingo-stack/openframe-frontend-core/embed-shims' * registerLink(NextLink) * * After registration, every lib component that renders this shim * delegates to `NextLink` — prefetch, replace, scroll, locale, etc. * all work as expected. Without registration, the shim falls through * to the plain `` path that drops Next-specific props. * * Lib internals import this shim directly (relative path); hub-side * code goes through the barrel (`@flamingo-stack/.../embed-shims`). */ 'use client' import { forwardRef, type AnchorHTMLAttributes, type ComponentType, type ReactNode, } from 'react' type LinkProps = Omit, 'href'> & { href?: string | { pathname?: string; query?: Record } prefetch?: boolean | null replace?: boolean scroll?: boolean shallow?: boolean passHref?: boolean legacyBehavior?: boolean locale?: string | false children?: ReactNode } let impl: ComponentType | null = null /** * Register the real `next/link` so this shim delegates to it instead * of rendering a plain ``. Call ONCE at app init in a Next.js host. */ export function registerLink(component: ComponentType): void { impl = component } const Link = forwardRef(function NextLinkShim( props, ref, ) { // Real impl path — registered by the host. Hand off untouched so // every Next-specific prop (prefetch, replace, scroll, locale…) // reaches the real component intact. if (impl) { const Real = impl return } // Fallback path — plain . Drops Next-only props and reduces // `UrlObject` href to its pathname. const { href, children, prefetch: _prefetch, replace: _replace, scroll: _scroll, shallow: _shallow, passHref: _passHref, legacyBehavior: _legacyBehavior, locale: _locale, ...rest } = props const hrefStr = typeof href === 'string' ? href : href?.pathname ? href.pathname : undefined return ( {children} ) }) export default Link