import { pagePathUtils } from '@growi/core'; 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 isCreatablePage = (href: string) => { try { const url = new URL(href); const pathName = url.pathname; return pagePathUtils.isCreatablePage(pathName); } catch (err) { logger.debug(err); return false; } }; type Props = Omit & { children: React.ReactNode, id?: string, href?: string, className?: string, }; export const NextLink = (props: Props): JSX.Element => { const { id, 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-')), ); if (isExternalLink(href, siteUrl)) { return ( {children}  ); } // when href is an anchor link or not-creatable path if (isAnchorLink(href) || !isCreatablePage(href)) { return ( {children} ); } return ( {children} ); };