@@ -18,12 +18,22 @@ export type ScrollRestorationOptions = {
18
18
scrollBehavior ?: ScrollToOptions [ 'behavior' ]
19
19
}
20
20
21
+ function getSafeSessionStorage ( ) {
22
+ try {
23
+ if (
24
+ typeof window !== 'undefined' &&
25
+ typeof window . sessionStorage === 'object'
26
+ ) {
27
+ return window . sessionStorage
28
+ }
29
+ } catch {
30
+ return undefined
31
+ }
32
+ return undefined
33
+ }
34
+
21
35
export const storageKey = 'tsr-scroll-restoration-v1_3'
22
- let sessionsStorage = false
23
- try {
24
- sessionsStorage =
25
- typeof window !== 'undefined' && typeof window . sessionStorage === 'object'
26
- } catch { }
36
+
27
37
const throttle = ( fn : ( ...args : Array < any > ) => void , wait : number ) => {
28
38
let timeout : any
29
39
return ( ...args : Array < any > ) => {
@@ -35,28 +45,32 @@ const throttle = (fn: (...args: Array<any>) => void, wait: number) => {
35
45
}
36
46
}
37
47
}
38
- export const scrollRestorationCache : ScrollRestorationCache = sessionsStorage
39
- ? ( ( ) => {
40
- const state : ScrollRestorationByKey =
41
- JSON . parse ( window . sessionStorage . getItem ( storageKey ) || 'null' ) || { }
42
-
43
- return {
44
- state,
45
- // This setter is simply to make sure that we set the sessionStorage right
46
- // after the state is updated. It doesn't necessarily need to be a functional
47
- // update.
48
- set : ( updater ) => (
49
- ( scrollRestorationCache . state =
50
- functionalUpdate ( updater , scrollRestorationCache . state ) ||
51
- scrollRestorationCache . state ) ,
52
- window . sessionStorage . setItem (
53
- storageKey ,
54
- JSON . stringify ( scrollRestorationCache . state ) ,
55
- )
56
- ) ,
57
- }
58
- } ) ( )
59
- : ( undefined as any )
48
+
49
+ function createScrollRestorationCache ( ) : ScrollRestorationCache | undefined {
50
+ const safeSessionStorage = getSafeSessionStorage ( )
51
+ if ( ! safeSessionStorage ) {
52
+ return undefined
53
+ }
54
+
55
+ const persistedState = safeSessionStorage . getItem ( storageKey )
56
+ let state : ScrollRestorationByKey = persistedState
57
+ ? JSON . parse ( persistedState )
58
+ : { }
59
+
60
+ return {
61
+ state,
62
+ // This setter is simply to make sure that we set the sessionStorage right
63
+ // after the state is updated. It doesn't necessarily need to be a functional
64
+ // update.
65
+ set : ( updater ) => (
66
+ ( state = functionalUpdate ( updater , state ) || state ) ,
67
+ safeSessionStorage . setItem ( storageKey , JSON . stringify ( state ) )
68
+ ) ,
69
+ }
70
+ }
71
+
72
+ export const scrollRestorationCache = createScrollRestorationCache ( )
73
+
60
74
/**
61
75
* The default `getKey` function for `useScrollRestoration`.
62
76
* It returns the `key` from the location state or the `href` of the location.
@@ -176,6 +190,9 @@ export function restoreScroll(
176
190
}
177
191
178
192
export function setupScrollRestoration ( router : AnyRouter , force ?: boolean ) {
193
+ if ( scrollRestorationCache === undefined ) {
194
+ return
195
+ }
179
196
const shouldScrollRestoration =
180
197
force ?? router . options . scrollRestoration ?? false
181
198
0 commit comments