diff --git a/packages/react-sdk/src/app/custom-components/shared/remix-link.tsx b/packages/react-sdk/src/app/custom-components/shared/remix-link.tsx index 93ed9cd1a9..1afba6d584 100644 --- a/packages/react-sdk/src/app/custom-components/shared/remix-link.tsx +++ b/packages/react-sdk/src/app/custom-components/shared/remix-link.tsx @@ -16,6 +16,11 @@ const isAbsoluteUrl = (href: string) => { } }; +// Remix's check for absolute URL copied from here: +// https://github.com/remix-run/react-router/blob/react-router-dom%406.8.0/packages/react-router-dom/index.tsx#L423-L424 +const isAbsoluteUrlRemix = (href: string) => + /^[a-z+]+:\/\//i.test(href) || href.startsWith("//"); + type Props = Omit, "href"> & { href?: string }; type Ref = ElementRef<"a">; @@ -25,13 +30,27 @@ export const wrapLinkComponent = ( ) => { // We're not actually wrapping BaseLink (no way to wrap with Remix's Link), // but this is still useful because we're making sure that props/ref types are compatible - const Component = forwardRef(({ href = "", ...props }, ref) => - isAbsoluteUrl(href) ? ( - - ) : ( - - ) - ); + const Component = forwardRef(({ href = "", ...props }, ref) => { + const isAbsolute = isAbsoluteUrl(href); + + // This is a workaround for a bug in Remix: https://github.com/remix-run/remix/issues/5440 + // It has a buggy absolute URL detection, which gives false positives on value like "//" or "http://" + // and causes entire app to crash + const willRemixTryToTreatAsAbsoluteAndCrash = + isAbsolute === false && isAbsoluteUrlRemix(href); + + if (isAbsolute || willRemixTryToTreatAsAbsoluteAndCrash) { + return ( + + ); + } + + return ; + }); // This is the only part that we use from BaseLink at runtime Component.displayName = BaseLink.displayName;