From 00230314db2409452869c249d80a3d9d0bac2a89 Mon Sep 17 00:00:00 2001 From: Steve Larson <9larsons@gmail.com> Date: Tue, 9 Jul 2024 11:14:33 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20member=20source=20attrib?= =?UTF-8?q?ution=20for=20sign-up=20(Portal)=20links=20(#20566)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref https://linear.app/tryghost/issue/ONC-154 - the query params did not carry through on portal sign up links because of the hash creating an ignored fragment (/#/portal/signup?ref=something) Now when we check link attribution, we'll attempt to run the same logic for the referrer source after stripping out `#/portal` from the URL. Otherwise we should continue to treat these fragments as fragments to be ignored by the client. NOTE: We do not have e2e tests that cover member signup on the front end and the data entered in the back end. The tests we have mock only the server side of things. The test added here only covers the data that is generated from the front end request (at this time), *not* the front end request itself, meaning it's fragile. --- .../member-attribution/member-attribution.js | 16 +++++++++++++- .../services/member-attribution.test.js | 22 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ghost/core/core/frontend/src/member-attribution/member-attribution.js b/ghost/core/core/frontend/src/member-attribution/member-attribution.js index 6cd8c16eebc..72223d661f2 100644 --- a/ghost/core/core/frontend/src/member-attribution/member-attribution.js +++ b/ghost/core/core/frontend/src/member-attribution/member-attribution.js @@ -76,6 +76,8 @@ const LIMIT = 15; let sourceParam; let utmSourceParam; let utmMediumParam; + let referrerSource; + try { // Fetch source/medium from query param const url = new URL(window.location.href); @@ -83,11 +85,23 @@ const LIMIT = 15; sourceParam = url.searchParams.get('source'); utmSourceParam = url.searchParams.get('utm_source'); utmMediumParam = url.searchParams.get('utm_medium'); + + referrerSource = refParam || sourceParam || utmSourceParam || null; + + // if referrerSource is not set, check to see if the url contains a hash like ghost.org/#/portal/signup?ref=ghost and pull the ref from the hash + if (!referrerSource && url.hash && url.hash.includes('#/portal')) { + const hashUrl = new URL(window.location.href.replace('/#/portal', '')); + refParam = hashUrl.searchParams.get('ref'); + sourceParam = hashUrl.searchParams.get('source'); + utmSourceParam = hashUrl.searchParams.get('utm_source'); + utmMediumParam = hashUrl.searchParams.get('utm_medium'); + + referrerSource = refParam || sourceParam || utmSourceParam || null; + } } catch (e) { console.error('[Member Attribution] Parsing referrer from querystring failed', e); } - const referrerSource = refParam || sourceParam || utmSourceParam || null; const referrerMedium = utmMediumParam || null; const referrerUrl = window.document.referrer || null; diff --git a/ghost/core/test/e2e-server/services/member-attribution.test.js b/ghost/core/test/e2e-server/services/member-attribution.test.js index f4e25e8fcbc..4a3e8099956 100644 --- a/ghost/core/test/e2e-server/services/member-attribution.test.js +++ b/ghost/core/test/e2e-server/services/member-attribution.test.js @@ -400,5 +400,25 @@ describe('Member Attribution Service', function () { referrerUrl: null })); }); + + it('resolves Portal signup URLs', async function () { + // NOTE: We cannot test the actual hash URL here; the attribution below is what is receieved when navigating to /#/portal/signup?ref=ghost + // TODO: We don't appear to have tests for parsing URLs for params. + const attribution = await memberAttributionService.service.getAttribution([ + { + path: '/', + time: Date.now(), + referrerSource: 'casper' + } + ]); + attribution.should.match(({ + id: null, + url: '/', + type: 'url', + referrerSource: 'casper', + referrerMedium: null, + referrerUrl: null + })); + }); }); -}); +}); \ No newline at end of file