Fix using CMD or CTRL to open in a new tab (#3466)

This commit is contained in:
Greg Bergé
2025-07-11 16:25:37 +02:00
committed by GitHub
parent 7212345466
commit cf1fae5837
2 changed files with 25 additions and 25 deletions
@@ -6,6 +6,7 @@ import React from 'react';
import { tcls } from '@/lib/tailwind';
import { SiteExternalLinksTarget } from '@gitbook/api';
import { type TrackEventInput, useTrackEvent } from '../Insights';
import { isExternalLink } from '../utils/link';
import { type DesignTokenName, useClassnames } from './StyleProvider';
// Props from Next, which includes NextLinkProps and all the things anchor elements support.
@@ -89,7 +90,7 @@ export const Link = React.forwardRef(function Link(
if (isInIframe && isExternalWithOrigin) {
event.preventDefault();
window.open(href, '_blank', 'noopener noreferrer');
} else if (isExternal) {
} else if (isExternal && !event.ctrlKey && !event.metaKey) {
// The external logic server-side is limited
// so we use the client-side logic to determine the real target
// by default the target is "_self".
@@ -177,27 +178,3 @@ export const LinkOverlay = React.forwardRef(function LinkOverlay(
</Link>
);
});
/**
* Check if a link is external, compared to an origin.
*/
function isExternalLink(href: string, origin: string | null = null) {
if (!URL.canParse) {
// If URL.canParse is not available, we quickly check if it looks like a URL
return href.startsWith('http');
}
if (!URL.canParse(href)) {
// If we can't parse the href, we consider it a relative path
return false;
}
if (!origin) {
// If origin is not provided, we consider the link external
return true;
}
// If the url points to the same origin, we consider it internal
const parsed = new URL(href);
return parsed.origin !== origin;
}
@@ -0,0 +1,23 @@
/**
* Check if a link is external, compared to an origin.
*/
export function isExternalLink(href: string, origin: string | null = null) {
if (!URL.canParse) {
// If URL.canParse is not available, we quickly check if it looks like a URL
return href.startsWith('http');
}
if (!URL.canParse(href)) {
// If we can't parse the href, we consider it a relative path
return false;
}
if (!origin) {
// If origin is not provided, we consider the link external
return true;
}
// If the url points to the same origin, we consider it internal
const parsed = new URL(href);
return parsed.origin !== origin;
}