import Link, { LinkProps } from 'next/link'; import { useSiteUrl } from '~/stores/context'; import loggerFactory from '~/utils/logger'; const logger = loggerFactory('growi:components:NextLink'); const isAnchorLink = (href: string): boolean => { return href.toString().length > 0 && href[0] === '#'; }; const isExternalLink = (href: string, siteUrl: string | undefined): boolean => { try { const baseUrl = new URL(siteUrl ?? 'https://example.com'); const hrefUrl = new URL(href, baseUrl); return baseUrl.host !== hrefUrl.host; } catch (err) { logger.debug(err); return false; } }; const isAttached = (href: string): boolean => { return href.startsWith('/attachment/'); }; type Props = Omit & { children: React.ReactNode, href?: string, className?: string, }; export const NextLink = (props: Props): JSX.Element => { const { href, children, className, ...rest } = props; const { data: siteUrl } = useSiteUrl(); if (href == null) { return {children}; } // extract 'data-*' props const dataAttributes = Object.fromEntries( Object.entries(rest).filter(([key]) => key.startsWith('data-')), ); // when href is an anchor link if (isAnchorLink(href)) { return ( {children} ); } if (isExternalLink(href, siteUrl)) { return ( {children}  ); } // when href is an attachment file if (isAttached(href)) { const dlhref = href.replace('/attachment/', '/download/'); return ( {children}   ); } return ( {children} ); };