Revert "fix: move reference pages to hash navigation and apply redirect rules" (#46541)

This commit is contained in:
Jeremias Menichelli authored and GitHub committed 2026-06-01 13:00:36 +02:00
1 parent 313ef75011
commit b18814faaa
9 files changed
+40 -54

No files matched your search

@@ -9,7 +9,7 @@ import { SidebarSkeleton } from '~/layouts/MainSkeleton'
export async function ApiReferencePage() {
return (
<ReferenceContentScrollHandler>
<ReferenceContentScrollHandler libPath="api" version="latest" isLatestVersion={true}>
<SidebarSkeleton
menuId={MenuId.RefApi}
NavigationMenu={
@@ -9,7 +9,7 @@ import { SidebarSkeleton } from '~/layouts/MainSkeleton'
export async function CliReferencePage() {
return (
<ReferenceContentScrollHandler>
<ReferenceContentScrollHandler libPath="cli" version="latest" isLatestVersion={true}>
<SidebarSkeleton
menuId={MenuId.RefCli}
NavigationMenu={
@@ -42,7 +42,7 @@ export async function ClientLibIntroduction({
return (
<ReferenceSectionWrapper
id="introduction"
link={`/docs/reference/${libPath}${isLatestVersion ? '' : `/${version}`}#introduction`}
link={`/docs/reference/${libPath}/${isLatestVersion ? '' : `${version}/`}introduction`}
className={cn('prose', className)}
>
<MDXRemoteRefs source={content} />
@@ -6,6 +6,7 @@ import { BASE_PATH } from '~/lib/constants'
import { debounce } from 'lodash-es'
import { ChevronUp } from 'lucide-react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { Collapsible } from 'radix-ui'
import type { HTMLAttributes, MouseEvent, PropsWithChildren } from 'react'
import {
@@ -36,7 +37,6 @@ function subscribeToPathname(callback: () => void) {
if (patchCount === 0) {
window.addEventListener('popstate', notifyPathnameListeners)
window.addEventListener('hashchange', notifyPathnameListeners)
originalPushState = history.pushState.bind(history)
history.pushState = (...args) => {
@@ -58,7 +58,6 @@ function subscribeToPathname(callback: () => void) {
if (patchCount === 0) {
window.removeEventListener('popstate', notifyPathnameListeners)
window.removeEventListener('hashchange', notifyPathnameListeners)
history.pushState = originalPushState!
history.replaceState = originalReplaceState!
originalPushState = null
@@ -67,29 +66,40 @@ function subscribeToPathname(callback: () => void) {
}
}
function getLocation() {
function getPathname() {
if (typeof window === 'undefined') return ''
const pathname = window.location.pathname
const strippedPathname = pathname.startsWith(BASE_PATH)
? pathname.slice(BASE_PATH.length)
: pathname
return `${strippedPathname}${window.location.hash}`
return pathname.startsWith(BASE_PATH) ? pathname.slice(BASE_PATH.length) : pathname
}
function getServerLocation() {
function getServerPathname() {
return ''
}
function useCurrentLocation() {
return useSyncExternalStore(subscribeToPathname, getLocation, getServerLocation)
function useCurrentPathname() {
return useSyncExternalStore(subscribeToPathname, getPathname, getServerPathname)
}
export function ReferenceContentScrollHandler({ children }: PropsWithChildren) {
export function ReferenceContentScrollHandler({
libPath,
version,
isLatestVersion,
children,
}: PropsWithChildren<{
libPath: string
version: string
isLatestVersion: boolean
}>) {
const [initiallyScrolled, setInitiallyScrolled] = useState(false)
const pathname = usePathname()
useEffect(() => {
if (!initiallyScrolled) {
const initialSelectedSection = window.location.hash.replace(/^#/, '')
const initialSelectedSection = pathname.replace(
`/reference/${libPath}/${isLatestVersion ? '' : `${version}/`}`,
''
)
if (initialSelectedSection) {
const section = document.getElementById(initialSelectedSection)
if (section) {
@@ -100,7 +110,7 @@ export function ReferenceContentScrollHandler({ children }: PropsWithChildren) {
setInitiallyScrolled(true)
}
}, [initiallyScrolled])
}, [pathname, libPath, version, isLatestVersion, initiallyScrolled])
return (
<ReferenceContentInitiallyScrolledContext.Provider value={initiallyScrolled}>
@@ -167,7 +177,7 @@ export function ReferenceNavigationScrollHandler({
}
function deriveHref(basePath: string, section: AbbrevApiReferenceSection) {
return 'slug' in section ? `${basePath}#${section.slug}` : ''
return 'slug' in section ? `${basePath}/${section.slug}` : ''
}
function getLinkStyles(isActive: boolean, className?: string) {
@@ -237,10 +247,10 @@ export function RefLink({
}) {
const ref = useRef<HTMLAnchorElement>(null)
const location = useCurrentLocation()
const pathname = useCurrentPathname()
const href = deriveHref(basePath, section)
const isActive =
location === href || (location === basePath && href.replace(basePath, '') === '#introduction')
pathname === href || (pathname === basePath && href.replace(basePath, '') === '/introduction')
useEffect(() => {
if (ref.current) {
@@ -283,15 +293,15 @@ export function RefLink({
function useCompoundRefLinkActive(basePath: string, section: AbbrevApiReferenceSection) {
const [open, _setOpen] = useState(false)
const location = useCurrentLocation()
const pathname = useCurrentPathname()
const parentHref = deriveHref(basePath, section)
const isParentActive = location === parentHref
const isParentActive = pathname === parentHref
const childHrefs = useMemo(
() => new Set((section.items || []).map((item) => deriveHref(basePath, item))),
[basePath, section]
)
const isChildActive = childHrefs.has(location)
const isChildActive = childHrefs.has(pathname)
const isActive = isParentActive || isChildActive
@@ -21,7 +21,11 @@ export async function ClientSdkReferencePage({ sdkId, libVersion }: ClientSdkRef
const menuData = NavItems[libraryMeta.meta[libVersion].libId]
return (
<ReferenceContentScrollHandler>
<ReferenceContentScrollHandler
libPath={libraryMeta.libPath}
version={libVersion}
isLatestVersion={isLatestVersion}
>
<SidebarSkeleton
menuId={libraryMeta.meta[libVersion].libId}
NavigationMenu={
@@ -94,7 +94,7 @@ export function SectionSwitch({ libraryId, version, section }: SectionSwitchProp
const allAvailableVersions = REFERENCES[libraryId.replaceAll('-', '_')].versions
const isLatestVersion = allAvailableVersions.length === 0 || version === allAvailableVersions[0]
const sectionLink = `/docs/reference/${libPath}${isLatestVersion ? '' : `/${version}`}#${section.slug}`
const sectionLink = `/docs/reference/${libPath}/${isLatestVersion ? '' : `${version}/`}${section.slug}`
switch (section.type) {
case 'markdown':
@@ -192,7 +192,7 @@ async function CliCommandSection({ link, section }: CliCommandSectionProps) {
return (
<li key={index} className="ml-4">
<RefInternalLink
href={`/reference/cli#${subcommandDetails.id}`}
href={`/reference/cli/${subcommandDetails.id}`}
sectionSlug={subcommandDetails.id}
>
{subcommandDetails.title}
@@ -48,7 +48,7 @@ export async function SelfHostingReferencePage({
const name = REFERENCES[servicePath.replaceAll('-', '_')].name
return (
<ReferenceContentScrollHandler>
<ReferenceContentScrollHandler libPath={servicePath} version="latest" isLatestVersion={true}>
<SidebarSkeleton
menuId={menuId}
NavigationMenu={
-14
View File
@@ -171,20 +171,6 @@ const nextConfig = {
source: '/guides/database/replication/replication-faq',
destination: '/guides/database/replication/external-replication-faq',
permanent: true,
},
// Reference pages use hash anchors for sections; redirect the legacy
// path-style /reference/<lib>/introduction (and versioned variants)
// back to the base reference URL. Order matters: introduction first so
// it strips to a bare URL, then the section rules add a hash anchor.
{
source: '/reference/:lib/:version(v\\d+)/:section',
destination: '/reference/:lib/:version#:section',
permanent: true,
},
{
source: '/reference/:lib/:section((?!v\\d+$)[^/]+)',
destination: '/reference/:lib#:section',
permanent: true,
},
]
},
-14
View File
@@ -3203,20 +3203,6 @@ module.exports = [
destination: '/dashboard/redeem?code=:code',
permanent: false,
},
// Reference pages use hash anchors for sections; redirect the legacy
// path-style /docs/reference/<lib>/introduction (and versioned variants)
// back to the base reference URL. Order matters: introduction first so it
// strips to a bare URL, then the section rules add a hash anchor.
{
permanent: true,
source: '/docs/reference/:lib/:version(v\\d+)/:section',
destination: '/docs/reference/:lib/:version#:section',
},
{
permanent: true,
source: '/docs/reference/:lib/:section((?!v\\d+$)[^/]+)',
destination: '/docs/reference/:lib#:section',
},
// Legacy product .txt URLs → new .md routes
{ permanent: true, source: '/llms/homepage.txt', destination: '/homepage.md' },
{ permanent: true, source: '/llms/auth.txt', destination: '/auth.md' },