import { getLocalizedUrl } from 'intlayer';
import type { JSX } from 'preact';
import { forwardRef } from 'preact/compat';
import { useLocale } from 'preact-intlayer';
import { useLocation } from 'preact-iso';
export interface LocalizedLinkProps
extends JSX.HTMLAttributes<HTMLAnchorElement> {
href: string;
replace?: boolean;
}
/**
* Utility function to check whether a given URL is external.
* If the URL starts with http:// or https://, it's considered external.
*/
export const checkIsExternalLink = (href?: string): boolean =>
/^https?:\/\//.test(href ?? '');
/**
* A custom Link component that adapts the href attribute based on the current locale.
* For internal links, it uses `getLocalizedUrl` to prefix the URL with the locale (e.g., /fr/about).
* This ensures that navigation stays within the same locale context.
* It uses a standard <a> tag but can trigger client-side navigation using preact-iso's `route`.
*/
export const LocalizedLink = forwardRef<HTMLAnchorElement, LocalizedLinkProps>(
({ href, children, onClick, replace = false, ...props }, ref) => {
const { locale } = useLocale();
const location = useLocation();
const isExternalLink = checkIsExternalLink(href);
const hrefI18n =
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
if (onClick) {
onClick(event);
}
if (
!isExternalLink &&
href &&
event.button === 0 &&
!event.metaKey &&
!event.ctrlKey &&
!event.shiftKey &&
!event.altKey
) {
event.preventDefault();
if (location.url !== hrefI18n) {
location.route(hrefI18n, replace);
}
}
};
return (
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
{children}
</a>
);
}
);