🐛 Fixed member source attribution for sign-up (Portal) links (#20566)

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.
This commit is contained in:
Steve Larson 2024-07-09 11:14:33 -05:00 committed by GitHub
parent 8b45af3458
commit 00230314db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 2 deletions

View File

@ -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;

View File

@ -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
}));
});
});
});
});