From 5c9a37dca459cf91d53c9567f8293d7c16293951 Mon Sep 17 00:00:00 2001 From: Roger Date: Thu, 7 May 2020 19:22:41 -0400 Subject: [PATCH] Change how relative fragments are handled. (#1260) - Page-relative fragments (specifically, where the whole href starts with '#') are now demoted to plain `a` links in our link wrapper. - The previous behavior that prepended to these links is now removed. - The link wrapper `a` fallback has been expanded upon with comments, and now sets rel specifically on external links that don't already have it. --- src/components/Link/index.tsx | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/Link/index.tsx b/src/components/Link/index.tsx index a621cae8de..da0a066036 100644 --- a/src/components/Link/index.tsx +++ b/src/components/Link/index.tsx @@ -20,13 +20,29 @@ const isMailto = (url: string): boolean => url.startsWith('mailto:') const ResultLinkComponent: React.FC = ({ href, children, + rel, ...restProps }) => { - if (!isRelative(href) || isMailto(href) || restProps.target) { - let rel = 'noopener noreferrer' - - if (restProps.rel) { - rel = `${rel} ${restProps.rel}` + // Handle all situations where a basic `a` must be used over Gatsby Link + const hrefIsRelative = isRelative(href) + const hrefIsMailto = isMailto(href) + const hrefHasTarget = restProps.target + // Fragments within the page should be `a`, but links to other pages + // that have anchors should be okay. + const hrefIsRelativeFragment = href.startsWith('#') + + if ( + !hrefIsRelative || + hrefIsMailto || + hrefHasTarget || + hrefIsRelativeFragment + ) { + /* + Change external links without an explicit rel to have 'noopener + noreferrer', but leave explicitly defined rels alone. + */ + if (!hrefIsRelative && typeof rel !== 'string') { + rel = 'noopener noreferrer' } return ( @@ -82,10 +98,6 @@ const Link: React.FC = ({ href, ...restProps }) => { ) const location = new URL(href) - // Navigate from @reach/router handles hash links incorrectly. Fix it - if (href.startsWith('#')) { - href = currentLocation.pathname + href - } if (location.host === currentLocation.host) { // Replace link href with redirect if it exists