@@ -33,13 +33,26 @@ async function main() {
3333 rscOptions ,
3434 ) ;
3535
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+
3645 function BrowserRoot ( ) {
3746 const [ payload , setPayload_ ] = React . useState ( initialPayload ) ;
3847
3948 React . useEffect ( ( ) => {
4049 setPayload = v => React . startTransition ( ( ) => setPayload_ ( v ) ) ;
4150 } , [ setPayload_ ] ) ;
4251
52+ React . useEffect ( ( ) => {
53+ return listenNavigation ( ( ) => onNavigation ( ) ) ;
54+ } , [ ] ) ;
55+
4356 return payload . root ;
4457 }
4558
@@ -64,4 +77,51 @@ async function main() {
6477 }
6578}
6679
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+
67127main ( ) ;
0 commit comments