@@ -114,6 +114,9 @@ export const useInitGalaxy = () => {
114114
115115 const [ galaxy , stopGalaxy ] = Galaxy . init ( galaxyOptions ) ;
116116 window . galaxy = galaxy ;
117+ // Signal readiness so page-level effects that mounted before init (the
118+ // common case on a cold visit) can fire their queued load events.
119+ window . dispatchEvent ( new Event ( "galaxy:ready" ) ) ;
117120
118121 return ( ) => {
119122 void stopGalaxy ( ) ;
@@ -138,7 +141,7 @@ export const galaxyOnLoad = (event) => {
138141 */
139142export const galaxyOnFocus = ( event , depsArray ) => {
140143 const listener = ( ) => {
141- window . galaxy . track ( event , { interaction : "trigger" } ) ;
144+ window . galaxy ? .track ( event , { interaction : "trigger" } ) ;
142145 } ;
143146
144147 useEffect ( ( ) => {
@@ -157,7 +160,7 @@ export const galaxyOnFocus = (event, depsArray) => {
157160 */
158161export const galaxyOnBlur = ( event , depsArray ) => {
159162 const listener = ( ) => {
160- window . galaxy . track ( event , { interaction : "trigger" } ) ;
163+ window . galaxy ? .track ( event , { interaction : "trigger" } ) ;
161164 } ;
162165
163166 useEffect ( ( ) => {
@@ -171,14 +174,34 @@ export const galaxyOnBlur = (event, depsArray) => {
171174/**
172175 * Instrument galaxy for this page for load, blur and focus events.
173176 *
177+ * Fires `${prefix}.window.load` once each time the page (or `depsArray`)
178+ * changes, and tracks blur/focus for the lifetime of the component.
179+ *
174180 * @param prefix used to name the events sent to galaxy (`${prefix}.window.load`, `${prefix}.window.blur` and `${prefix}.window.focus`)
175181 * @param depsArray used to trigger a rerender of the component that will re-run the useEffect
176182 *
177183 */
178- export const galaxyOnPage = ( prefix , depsArray = [ ] ) => {
179- galaxyOnLoad ( `${ prefix } .window.load` ) ;
180- galaxyOnBlur ( `${ prefix } .window.blur` , depsArray ) ;
181- galaxyOnFocus ( `${ prefix } .window.focus` , depsArray ) ;
184+ export const useGalaxyOnPage = ( prefix , depsArray = [ ] ) => {
185+ // Fire the load event once per page change. Galaxy is initialised in an
186+ // effect of its own (see useInitGalaxy) in an unrelated subtree, so on a
187+ // cold visit this effect usually runs before galaxy is ready. If it isn't
188+ // ready yet, wait for the one-shot `galaxy:ready` signal instead of dropping
189+ // the event with no retry.
190+ useEffect ( ( ) => {
191+ const track = ( ) =>
192+ window . galaxy . track ( `${ prefix } .window.load` , { interaction : "trigger" } ) ;
193+
194+ if ( window . galaxy ) {
195+ track ( ) ;
196+ return ;
197+ }
198+
199+ window . addEventListener ( "galaxy:ready" , track , { once : true } ) ;
200+ return ( ) => window . removeEventListener ( "galaxy:ready" , track ) ;
201+ } , [ prefix , ...depsArray ] ) ;
202+
203+ galaxyOnBlur ( `${ prefix } .window.blur` , [ prefix , ...depsArray ] ) ;
204+ galaxyOnFocus ( `${ prefix } .window.focus` , [ prefix , ...depsArray ] ) ;
182205} ;
183206
184207// Pass String with convention 'namespace.component.eventName'
0 commit comments