'use client'; import { useLocalization } from '@akinon/next/hooks'; import { LocaleUrlStrategy } from '@akinon/next/localization'; import { urlLocaleMatcherRegex, urlSchemes } from '@akinon/next/utils'; import NextLink, { LinkProps as NextLinkProps } from 'next/link'; import { useMemo } from 'react'; type LinkProps = Omit< React.AnchorHTMLAttributes, keyof NextLinkProps > & NextLinkProps; export const Link = ({ children, href, ...rest }: LinkProps) => { const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization(); const formattedHref = useMemo(() => { if (!href) { return '#'; } if (typeof href === 'string') { const trimmedHref = href.trim(); if (!trimmedHref) { return '#'; } if (urlSchemes.some((scheme) => trimmedHref.startsWith(scheme))) { if ( trimmedHref.startsWith('mailto:') || trimmedHref.startsWith('tel:') ) { return trimmedHref; } try { new URL(trimmedHref); return trimmedHref; } catch { return '#'; } } try { new URL(trimmedHref, 'http://localhost'); } catch { return '#'; } const pathnameWithoutLocale = trimmedHref.replace( urlLocaleMatcherRegex, '' ); const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`; if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) { return hrefWithLocale; } else if ( localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale && locale !== defaultLocaleValue ) { return hrefWithLocale; } return trimmedHref || '#'; } if (typeof href !== 'string') { return href; } return '#'; }, [href, defaultLocaleValue, locale, localeUrlStrategy]); return ( {children} ); };