diff --git a/.changeset/site-auth-login-location.md b/.changeset/site-auth-login-location.md new file mode 100644 index 000000000..f453c791f --- /dev/null +++ b/.changeset/site-auth-login-location.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix the site auth login link sometimes redirecting back to an internal URL after login. diff --git a/packages/gitbook/src/components/SiteAuth/SiteAuthLoginLink.tsx b/packages/gitbook/src/components/SiteAuth/SiteAuthLoginLink.tsx index 52cfd6c10..1be3301ec 100644 --- a/packages/gitbook/src/components/SiteAuth/SiteAuthLoginLink.tsx +++ b/packages/gitbook/src/components/SiteAuth/SiteAuthLoginLink.tsx @@ -4,6 +4,7 @@ import { usePathname, useSearchParams } from 'next/navigation'; import { useMemo } from 'react'; import type React from 'react'; +import { useIsMounted } from '../hooks/useIsMounted'; import { Button, type ButtonProps } from '../primitives/Button'; import { DropdownMenuItem } from '../primitives/DropdownMenu'; import { Link, type LinkInsightsProps, type LinkProps } from '../primitives/Link'; @@ -16,9 +17,17 @@ function useSiteAuthLoginHrefWithLocation(href: string) { const rawPathname = usePathname(); const searchParams = useSearchParams(); const currentSearch = searchParams?.toString(); - const pathname = rawPathname ?? '/'; + // On the server, usePathname() returns the internal rewritten route (/sites/…, which includes + // the site API token), so the location is only added once mounted. + // https://nextjs.org/docs/app/api-reference/functions/use-pathname#avoid-hydration-mismatch-with-rewrites + const isMounted = useIsMounted(); + const pathname = isMounted ? (rawPathname ?? '/') : null; return useMemo(() => { + if (pathname === null) { + return href; + } + const baseURL = typeof window !== 'undefined' ? window.location.origin : 'http://localhost'; const resolved = URL.canParse(href) ? new URL(href) : new URL(href, baseURL); const siteBasePath = removeTrailingSlash(