diff --git a/ghost/admin/app/controllers/posts/analytics.js b/ghost/admin/app/controllers/posts/analytics.js index 56ebfd195b..8fc0211315 100644 --- a/ghost/admin/app/controllers/posts/analytics.js +++ b/ghost/admin/app/controllers/posts/analytics.js @@ -13,6 +13,7 @@ export default class AnalyticsController extends Controller { @service ghostPaths; @service settings; @service membersUtils; + @service utils; @tracked sources = null; @tracked links = null; @@ -34,20 +35,6 @@ export default class AnalyticsController extends Controller { return this._fetchReferrersStats.perform(); } - cleanURL(url, display = false) { - // Remove our own querystring parameters and protocol - const removeParams = ['rel', 'attribution_id', 'attribution_type']; - const urlObj = new URL(url); - for (const param of removeParams) { - urlObj.searchParams.delete(param); - } - if (!display) { - return urlObj.toString(); - } - // Return URL without protocol - return urlObj.host + (urlObj.pathname === '/' ? '' : urlObj.pathname) + (urlObj.search ? '?' + urlObj.search : ''); - } - async fetchLinks() { if (this._fetchLinks.isRunning) { return this._fetchLinks.last; @@ -78,8 +65,8 @@ export default class AnalyticsController extends Controller { ...link, link: { ...link.link, - to: this.cleanURL(link.link.to, false), - title: this.cleanURL(link.link.to, true) + to: this.utils.cleanTrackedUrl(link.link.to, false), + title: this.utils.cleanTrackedUrl(link.link.to, true) } }; }); diff --git a/ghost/admin/app/helpers/parse-member-event.js b/ghost/admin/app/helpers/parse-member-event.js index 1c44ebb84e..e2e66bfa46 100644 --- a/ghost/admin/app/helpers/parse-member-event.js +++ b/ghost/admin/app/helpers/parse-member-event.js @@ -5,6 +5,7 @@ import {inject as service} from '@ember/service'; export default class ParseMemberEventHelper extends Helper { @service feature; + @service utils; compute([event, hasMultipleNewsletters]) { const subject = event.data.member.name || event.data.member.email; @@ -227,11 +228,7 @@ export default class ParseMemberEventHelper extends Helper { if (event.type === 'click_event') { // Clean URL try { - const parsedURL = new URL(event.data.link.to); - - // Remove protocol, querystring and hash - // + strip trailing / - return parsedURL.host + (parsedURL.pathname === '/' ? '' : parsedURL.pathname); + return this.utils.cleanTrackedUrl(event.data.link.to, true); } catch (e) { // Invalid URL } diff --git a/ghost/admin/app/services/utils.js b/ghost/admin/app/services/utils.js index 2dfb81be1b..e1e1a14ba2 100644 --- a/ghost/admin/app/services/utils.js +++ b/ghost/admin/app/services/utils.js @@ -13,4 +13,24 @@ export default class UtilsService extends Service { iframe.setAttribute('src', url); } + + /** + * Remove tracking parameters from a URL + * @param {string} url + * @param {boolean} [display] Set to true to remove protocol and hash from the URL + * @returns + */ + cleanTrackedUrl(url, display = false) { + // Remove our own querystring parameters and protocol + const removeParams = ['rel', 'attribution_id', 'attribution_type']; + const urlObj = new URL(url); + for (const param of removeParams) { + urlObj.searchParams.delete(param); + } + if (!display) { + return urlObj.toString(); + } + // Return URL without protocol + return urlObj.host + (urlObj.pathname === '/' && !urlObj.search ? '' : urlObj.pathname) + (urlObj.search ? urlObj.search : ''); + } }