@@ -38,6 +38,10 @@ import * as addonManager from 'amo/addonManager';
3838import { getVersionById } from 'amo/reducers/versions' ;
3939import { getDisplayName } from 'amo/utils' ;
4040import { getFileHash , getPromotedCategory } from 'amo/utils/addons' ;
41+ import {
42+ injectUTMParams as defaultInjectUTMParams ,
43+ removeUTMParams as defaultRemoveUTMParams ,
44+ } from 'amo/utils/installAttribution' ;
4145import type { AppState } from 'amo/store' ;
4246import type { AddonVersionType } from 'amo/reducers/versions' ;
4347import type { AddonType } from 'amo/types/addons' ;
@@ -57,6 +61,7 @@ type EventType = {|
5761| } ;
5862
5963type MakeProgressHandlerParams = { |
64+ _removeUTMParams : typeof defaultRemoveUTMParams ,
6065 _tracking : typeof tracking ,
6166 addon : AddonType ,
6267 dispatch : DispatchFunc ,
@@ -65,6 +70,7 @@ type MakeProgressHandlerParams = {|
6570| } ;
6671
6772export function makeProgressHandler ( {
73+ _removeUTMParams,
6874 _tracking,
6975 addon,
7076 dispatch,
@@ -98,6 +104,7 @@ export function makeProgressHandler({
98104 params : getAddonEventParams ( addon , window . location . pathname ) ,
99105 } ) ;
100106 }
107+ _removeUTMParams ( ) ;
101108 } else if ( event . type === 'onInstallCancelled' ) {
102109 dispatch ( {
103110 type : INSTALL_CANCELLED ,
@@ -108,8 +115,10 @@ export function makeProgressHandler({
108115 category : getAddonEventCategory ( type , INSTALL_CANCELLED_ACTION ) ,
109116 params : getAddonEventParams ( addon , window . location . pathname ) ,
110117 } ) ;
118+ _removeUTMParams ( ) ;
111119 } else if ( event . type === 'onInstallFailed' ) {
112120 dispatch ( setInstallError ( { guid, error : INSTALL_FAILED } ) ) ;
121+ _removeUTMParams ( ) ;
113122 }
114123 } ;
115124}
@@ -123,12 +132,15 @@ type WithInstallHelpersPropsFromState = {|
123132 WrappedComponent : React . ComponentType < any > ,
124133 clientApp : string ,
125134 currentVersion : AddonVersionType | null ,
135+ installSource : string | null ,
126136| } ;
127137
128138type WithInstallHelpersDefaultProps = { |
129139 _addonManager : typeof addonManager ,
130140 _getPromotedCategory : typeof getPromotedCategory ,
141+ _injectUTMParams : typeof defaultInjectUTMParams ,
131142 _log : typeof log ,
143+ _removeUTMParams : typeof defaultRemoveUTMParams ,
132144 _tracking : typeof tracking ,
133145| } ;
134146
@@ -158,7 +170,9 @@ export class WithInstallHelpers extends React.Component<WithInstallHelpersIntern
158170 static defaultProps : WithInstallHelpersDefaultProps = {
159171 _addonManager : addonManager ,
160172 _getPromotedCategory : getPromotedCategory ,
173+ _injectUTMParams : defaultInjectUTMParams ,
161174 _log : log ,
175+ _removeUTMParams : defaultRemoveUTMParams ,
162176 _tracking : tracking ,
163177 } ;
164178
@@ -268,12 +282,15 @@ export class WithInstallHelpers extends React.Component<WithInstallHelpersIntern
268282 const {
269283 _addonManager,
270284 _getPromotedCategory,
285+ _injectUTMParams,
271286 _log,
287+ _removeUTMParams,
272288 _tracking,
273289 addon,
274290 clientApp,
275291 currentVersion,
276292 dispatch,
293+ installSource,
277294 } = this . props ;
278295
279296 invariant ( addon , 'need an addon to call install()' ) ;
@@ -287,6 +304,12 @@ export class WithInstallHelpers extends React.Component<WithInstallHelpersIntern
287304 return Promise . resolve ( ) ;
288305 }
289306
307+ // Inject UTM params into the page URL so Firefox can read them at
308+ // install time for attribution.
309+ if ( installSource ) {
310+ _injectUTMParams ( installSource ) ;
311+ }
312+
290313 return new Promise ( ( resolve ) => {
291314 dispatch ( { type : START_DOWNLOAD , payload : { guid } } ) ;
292315 _tracking . sendEvent ( {
@@ -311,6 +334,7 @@ export class WithInstallHelpers extends React.Component<WithInstallHelpersIntern
311334 return _addonManager . install (
312335 installURL || '' ,
313336 makeProgressHandler ( {
337+ _removeUTMParams,
314338 _tracking,
315339 addon,
316340 dispatch,
@@ -341,10 +365,16 @@ export class WithInstallHelpers extends React.Component<WithInstallHelpersIntern
341365 } ,
342366 } ) ;
343367 }
368+
369+ // Clean up UTM params injected before install. This is called on
370+ // every exit path (success, failure, cancel) to ensure the URL is
371+ // always restored. removeUTMParams() is idempotent.
372+ _removeUTMParams ( ) ;
344373 } )
345374 . catch ( ( error ) => {
346375 _log . error ( `Install error: ${ error } ` ) ;
347376
377+ _removeUTMParams ( ) ;
348378 dispatch ( setInstallError ( { guid, error : FATAL_INSTALL_ERROR } ) ) ;
349379 } ) ;
350380 }
@@ -419,6 +449,7 @@ export const withInstallHelpers = (
419449 WrappedComponent,
420450 clientApp : state . api . clientApp ,
421451 currentVersion,
452+ installSource : state . addonInstallSource . installSource ,
422453 } ;
423454 } ;
424455
0 commit comments