@@ -31,6 +31,7 @@ import {
31
31
} from './types'
32
32
import { hrefToUrl , mergeDataIntoQueryString , urlWithoutHash } from './url'
33
33
34
+ const isChromeIOS = / C r i O S / . test ( navigator . userAgent )
34
35
const isServer = typeof window === 'undefined'
35
36
const cloneSerializable = < T > ( obj : T ) : T => JSON . parse ( JSON . stringify ( obj ) )
36
37
const nextFrame = ( callback : ( ) => void ) => {
@@ -494,14 +495,24 @@ export class Router {
494
495
495
496
protected pushState ( page : Page ) : void {
496
497
this . page = page
497
- // Defer history.pushState to the next event loop tick to prevent timing conflicts.
498
- // Ensure any previous history.replaceState completes before pushState is executed.
499
- setTimeout ( ( ) => window . history . pushState ( cloneSerializable ( page ) , '' , page . url ) )
498
+ if ( isChromeIOS ) {
499
+ // Defer history.pushState to the next event loop tick to prevent timing conflicts.
500
+ // Ensure any previous history.replaceState completes before pushState is executed.
501
+ setTimeout ( ( ) => window . history . pushState ( cloneSerializable ( page ) , '' , page . url ) )
502
+ } else {
503
+ window . history . pushState ( cloneSerializable ( page ) , '' , page . url )
504
+ }
500
505
}
501
506
502
507
protected replaceState ( page : Page ) : void {
503
508
this . page = page
504
- window . history . replaceState ( cloneSerializable ( page ) , '' , page . url )
509
+ if ( isChromeIOS ) {
510
+ // Defer history.replaceState to the next event loop tick to prevent timing conflicts.
511
+ // Ensure any previous history.pushState completes before replaceState is executed.
512
+ setTimeout ( ( ) => window . history . replaceState ( cloneSerializable ( page ) , '' , page . url ) )
513
+ } else {
514
+ window . history . replaceState ( cloneSerializable ( page ) , '' , page . url )
515
+ }
505
516
}
506
517
507
518
protected handlePopstateEvent ( event : PopStateEvent ) : void {
0 commit comments