@@ -33,13 +33,26 @@ async function main() {
33
33
rscOptions ,
34
34
) ;
35
35
36
+ async function onNavigation ( ) {
37
+ const url = new URL ( window . location . href ) ;
38
+ const payload = await ReactClient . createFromFetch < RscPayload > (
39
+ fetch ( url ) ,
40
+ rscOptions ,
41
+ ) ;
42
+ setPayload ( payload ) ;
43
+ }
44
+
36
45
function BrowserRoot ( ) {
37
46
const [ payload , setPayload_ ] = React . useState ( initialPayload ) ;
38
47
39
48
React . useEffect ( ( ) => {
40
49
setPayload = v => React . startTransition ( ( ) => setPayload_ ( v ) ) ;
41
50
} , [ setPayload_ ] ) ;
42
51
52
+ React . useEffect ( ( ) => {
53
+ return listenNavigation ( ( ) => onNavigation ( ) ) ;
54
+ } , [ ] ) ;
55
+
43
56
return payload . root ;
44
57
}
45
58
@@ -64,4 +77,51 @@ async function main() {
64
77
}
65
78
}
66
79
80
+ function listenNavigation ( onNavigation : ( ) => void ) {
81
+ window . addEventListener ( 'popstate' , onNavigation ) ;
82
+
83
+ const oldPushState = window . history . pushState ;
84
+ window . history . pushState = function ( ...args ) {
85
+ const res = oldPushState . apply ( this , args ) ;
86
+ onNavigation ( ) ;
87
+ return res ;
88
+ } ;
89
+
90
+ const oldReplaceState = window . history . replaceState ;
91
+ window . history . replaceState = function ( ...args ) {
92
+ const res = oldReplaceState . apply ( this , args ) ;
93
+ onNavigation ( ) ;
94
+ return res ;
95
+ } ;
96
+
97
+ function onClick ( e : MouseEvent ) {
98
+ let link = ( e . target as Element ) . closest ( 'a' ) ;
99
+ if (
100
+ link &&
101
+ link instanceof HTMLAnchorElement &&
102
+ link . href &&
103
+ ( ! link . target || link . target === '_self' ) &&
104
+ link . origin === location . origin &&
105
+ ! link . hasAttribute ( 'download' ) &&
106
+ e . button === 0 && // left clicks only
107
+ ! e . metaKey && // open in new tab (mac)
108
+ ! e . ctrlKey && // open in new tab (windows)
109
+ ! e . altKey && // download
110
+ ! e . shiftKey &&
111
+ ! e . defaultPrevented
112
+ ) {
113
+ e . preventDefault ( ) ;
114
+ history . pushState ( null , '' , link . href ) ;
115
+ }
116
+ }
117
+ document . addEventListener ( 'click' , onClick ) ;
118
+
119
+ return ( ) => {
120
+ document . removeEventListener ( 'click' , onClick ) ;
121
+ window . removeEventListener ( 'popstate' , onNavigation ) ;
122
+ window . history . pushState = oldPushState ;
123
+ window . history . replaceState = oldReplaceState ;
124
+ } ;
125
+ }
126
+
67
127
main ( ) ;
0 commit comments