Fix(docs): prevent SecurityError from rapid history.replaceState call… (#38672)
* Fix(docs): prevent SecurityError from rapid history.replaceState calls during fast scrolling * url now chases the scroll * fixing merge conflicts * refactor: minor changes to safeHistoryReplaceState --------- Co-authored-by: Charis <26616127+charislam@users.noreply.github.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import MessageBird from './MessageBirdConfig.mdx'
|
||||
import Twilio from './TwilioConfig.mdx'
|
||||
import Vonage from './VonageConfig.mdx'
|
||||
import TextLocal from './TextLocalConfig.mdx'
|
||||
import { safeHistoryReplaceState } from '~/lib/historyUtils'
|
||||
|
||||
const reducer = (_, action: (typeof PhoneLoginsItems)[number] | undefined) => {
|
||||
const url = new URL(document.location.href)
|
||||
@@ -16,7 +17,7 @@ const reducer = (_, action: (typeof PhoneLoginsItems)[number] | undefined) => {
|
||||
} else {
|
||||
url.searchParams.delete('showSmsProvider')
|
||||
}
|
||||
window.history.replaceState(null, '', url)
|
||||
safeHistoryReplaceState(url.toString())
|
||||
return action
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import type { HTMLAttributes, PropsWithChildren } from 'react'
|
||||
import { useContext, useEffect, useRef, useState } from 'react'
|
||||
import { useInView } from 'react-intersection-observer'
|
||||
import { safeHistoryReplaceState } from '~/lib/historyUtils'
|
||||
|
||||
import {
|
||||
cn,
|
||||
@@ -44,7 +45,7 @@ export function ReferenceSectionWrapper({
|
||||
initialScrollHappened &&
|
||||
window.scrollY > 0 /* Don't update on first navigation to introduction */
|
||||
) {
|
||||
window.history.replaceState(null, '', link)
|
||||
safeHistoryReplaceState(link)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useNavigationMenuContext } from '~/components/Navigation/NavigationMenu
|
||||
import { menuState } from '~/hooks/useMenuState'
|
||||
import Image from 'next/legacy/image'
|
||||
import { cn } from 'ui'
|
||||
import { safeHistoryReplaceState } from '~/lib/historyUtils'
|
||||
|
||||
interface ISectionContainer {
|
||||
id: string
|
||||
@@ -97,7 +98,7 @@ const StickyHeader: FC<StickyHeader> = ({ icon, ...props }) => {
|
||||
onChange: (inView, entry) => {
|
||||
if (inView && window) highlightSelectedNavItem(entry.target.attributes['data-ref-id'].value)
|
||||
if (inView && props.scrollSpyHeader) {
|
||||
window.history.replaceState(null, '', entry.target.id)
|
||||
safeHistoryReplaceState(entry.target.id)
|
||||
// if (setActiveRefItem) setActiveRefItem(entry.target.attributes['data-ref-id'].value)
|
||||
menuState.setMenuActiveRefId(entry.target.attributes['data-ref-id'].value)
|
||||
// router.push(`/reference/javascript/${entry.target.attributes['data-ref-id'].value}`, null, {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { highlightSelectedNavItem } from 'ui/src/components/CustomHTMLElements/C
|
||||
import { useRouter } from 'next/compat/router'
|
||||
import { useNavigationMenuContext } from '~/components/Navigation/NavigationMenu/NavigationMenu.Context'
|
||||
import { menuState } from '~/hooks/useMenuState'
|
||||
import { safeHistoryReplaceState } from '~/lib/historyUtils'
|
||||
|
||||
interface ISectionContainer {
|
||||
id: string
|
||||
@@ -60,7 +61,7 @@ const StickyHeader: FC<StickyHeader> = (props) => {
|
||||
onChange: (inView, entry) => {
|
||||
if (inView && window) highlightSelectedNavItem(entry.target.attributes['data-ref-id'].value)
|
||||
if (inView && props.scrollSpyHeader) {
|
||||
window.history.replaceState(null, '', entry.target.id)
|
||||
safeHistoryReplaceState(entry.target.id)
|
||||
// if (setActiveRefItem) setActiveRefItem(entry.target.attributes['data-ref-id'].value)
|
||||
menuState.setMenuActiveRefId(entry.target.attributes['data-ref-id'].value)
|
||||
// router.push(`/reference/javascript/${entry.target.attributes['data-ref-id'].value}`, null, {
|
||||
|
||||
13
apps/docs/lib/historyUtils.ts
Normal file
13
apps/docs/lib/historyUtils.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { debounce } from 'lodash-es'
|
||||
|
||||
export const safeHistoryReplaceState = debounce((url: string) => {
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
if (url === window.location.href) return
|
||||
|
||||
try {
|
||||
window.history.replaceState(null, '', url)
|
||||
} catch (error) {
|
||||
console.warn('Failed to call history.replaceState:', error)
|
||||
}
|
||||
}, 120)
|
||||
Reference in New Issue
Block a user