mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-10 19:26:03 +02:00
Add UTM registration tracking
This commit is contained in:
@@ -4,6 +4,7 @@ import Cookies from 'js-cookie';
|
||||
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
|
||||
import { httpGet } from '../../lib/http';
|
||||
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
||||
import { triggerUtmRegistration } from '../../lib/browser.ts';
|
||||
|
||||
type GitHubButtonProps = {
|
||||
isDisabled?: boolean;
|
||||
@@ -46,6 +47,8 @@ export function GitHubButton(props: GitHubButtonProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerUtmRegistration();
|
||||
|
||||
let redirectUrl = '/';
|
||||
const gitHubRedirectAt = localStorage.getItem(GITHUB_REDIRECT_AT);
|
||||
const lastPageBeforeGithub = localStorage.getItem(GITHUB_LAST_PAGE);
|
||||
|
@@ -4,6 +4,10 @@ import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
|
||||
import { httpGet } from '../../lib/http';
|
||||
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
||||
import { GoogleIcon } from '../ReactIcons/GoogleIcon.tsx';
|
||||
import {
|
||||
getStoredUtmParams,
|
||||
triggerUtmRegistration,
|
||||
} from '../../lib/browser.ts';
|
||||
|
||||
type GoogleButtonProps = {
|
||||
isDisabled?: boolean;
|
||||
@@ -37,6 +41,8 @@ export function GoogleButton(props: GoogleButtonProps) {
|
||||
}`,
|
||||
)
|
||||
.then(({ response, error }) => {
|
||||
const utmParams = getStoredUtmParams();
|
||||
|
||||
if (!response?.token) {
|
||||
setError(error?.message || 'Something went wrong.');
|
||||
setIsLoading(false);
|
||||
@@ -45,6 +51,8 @@ export function GoogleButton(props: GoogleButtonProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerUtmRegistration();
|
||||
|
||||
let redirectUrl = '/';
|
||||
const googleRedirectAt = localStorage.getItem(GOOGLE_REDIRECT_AT);
|
||||
const lastPageBeforeGoogle = localStorage.getItem(GOOGLE_LAST_PAGE);
|
||||
@@ -97,9 +105,12 @@ export function GoogleButton(props: GoogleButtonProps) {
|
||||
// For non authentication pages, we want to redirect back to the page
|
||||
// the user was on before they clicked the social login button
|
||||
if (!['/login', '/signup'].includes(window.location.pathname)) {
|
||||
const pagePath = ['/respond-invite', '/befriend', '/r', '/ai'].includes(
|
||||
window.location.pathname,
|
||||
)
|
||||
const pagePath = [
|
||||
'/respond-invite',
|
||||
'/befriend',
|
||||
'/r',
|
||||
'/ai',
|
||||
].includes(window.location.pathname)
|
||||
? window.location.pathname + window.location.search
|
||||
: window.location.pathname;
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
|
||||
import { httpGet } from '../../lib/http';
|
||||
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
||||
import { LinkedInIcon } from '../ReactIcons/LinkedInIcon.tsx';
|
||||
import { triggerUtmRegistration } from '../../lib/browser.ts';
|
||||
|
||||
type LinkedInButtonProps = {
|
||||
isDisabled?: boolean;
|
||||
@@ -45,6 +46,8 @@ export function LinkedInButton(props: LinkedInButtonProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerUtmRegistration();
|
||||
|
||||
let redirectUrl = '/';
|
||||
const linkedInRedirectAt = localStorage.getItem(LINKEDIN_REDIRECT_AT);
|
||||
const lastPageBeforeLinkedIn = localStorage.getItem(LINKEDIN_LAST_PAGE);
|
||||
@@ -97,9 +100,12 @@ export function LinkedInButton(props: LinkedInButtonProps) {
|
||||
// For non authentication pages, we want to redirect back to the page
|
||||
// the user was on before they clicked the social login button
|
||||
if (!['/login', '/signup'].includes(window.location.pathname)) {
|
||||
const pagePath = ['/respond-invite', '/befriend', '/r', '/ai'].includes(
|
||||
window.location.pathname,
|
||||
)
|
||||
const pagePath = [
|
||||
'/respond-invite',
|
||||
'/befriend',
|
||||
'/r',
|
||||
'/ai',
|
||||
].includes(window.location.pathname)
|
||||
? window.location.pathname + window.location.search
|
||||
: window.location.pathname;
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import { httpPost } from '../../lib/http';
|
||||
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
|
||||
import { Spinner } from '../ReactIcons/Spinner';
|
||||
import { ErrorIcon2 } from '../ReactIcons/ErrorIcon2';
|
||||
import { triggerUtmRegistration } from '../../lib/browser.ts';
|
||||
|
||||
export function TriggerVerifyAccount() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -26,6 +27,8 @@ export function TriggerVerifyAccount() {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerUtmRegistration();
|
||||
|
||||
setAuthToken(response.token);
|
||||
window.location.href = '/';
|
||||
})
|
||||
|
@@ -6,6 +6,7 @@ import { X } from 'lucide-react';
|
||||
import { setViewSponsorCookie } from '../lib/jwt';
|
||||
import { isMobile } from '../lib/is-mobile';
|
||||
import Cookies from 'js-cookie';
|
||||
import { getUrlUtmParams } from '../lib/browser.ts';
|
||||
|
||||
export type PageSponsorType = {
|
||||
company: string;
|
||||
@@ -50,6 +51,16 @@ export function PageSponsor(props: PageSponsorProps) {
|
||||
const [sponsorId, setSponsorId] = useState<string | null>(null);
|
||||
const [sponsor, setSponsor] = useState<PageSponsorType>();
|
||||
|
||||
useEffect(() => {
|
||||
const foundUtmParams = getUrlUtmParams();
|
||||
|
||||
if (!foundUtmParams.utmSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.setItem('utm_params', JSON.stringify(foundUtmParams));
|
||||
}, []);
|
||||
|
||||
const loadSponsor = async () => {
|
||||
const currentPath = window.location.pathname;
|
||||
if (
|
||||
|
@@ -1,3 +1,65 @@
|
||||
type UtmParams = Partial<{
|
||||
utmSource: string;
|
||||
utmMedium: string;
|
||||
utmCampaign: string;
|
||||
utmContent: string;
|
||||
utmTerm: string;
|
||||
}>;
|
||||
|
||||
export function getUrlUtmParams(): UtmParams {
|
||||
if (typeof window === 'undefined') {
|
||||
return {};
|
||||
}
|
||||
|
||||
const utmParams = new URLSearchParams(window.location.search);
|
||||
const utmSource = utmParams.get('utm_source') ?? undefined;
|
||||
const utmMedium = utmParams.get('utm_medium') ?? undefined;
|
||||
const utmCampaign = utmParams.get('utm_campaign') ?? undefined;
|
||||
const utmContent = utmParams.get('utm_content') ?? undefined;
|
||||
const utmTerm = utmParams.get('utm_term') ?? undefined;
|
||||
|
||||
if (!utmSource || !utmCampaign) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
utmSource: utmCampaign ? utmSource.toLowerCase() : undefined,
|
||||
utmMedium: utmMedium ? utmMedium.toLowerCase() : undefined,
|
||||
utmCampaign: utmCampaign ? utmCampaign.toLowerCase() : undefined,
|
||||
utmContent: utmContent ? utmContent.toLowerCase() : undefined,
|
||||
utmTerm: utmTerm ? utmTerm.toLowerCase() : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerUtmRegistration() {
|
||||
const utmParams = getStoredUtmParams();
|
||||
console.log(utmParams);
|
||||
if (!utmParams.utmSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.removeItem('utm_params');
|
||||
|
||||
window.fireEvent({
|
||||
category: 'UserRegistration',
|
||||
action: `Registration: ${utmParams.utmSource || 'unknown'}-${utmParams.utmCampaign || 'unknown'}`,
|
||||
label: `Registration: ${utmParams.utmSource || 'unknown'}-${utmParams.utmCampaign || 'unknown'}`,
|
||||
});
|
||||
}
|
||||
|
||||
export function getStoredUtmParams(): UtmParams {
|
||||
if (typeof window === 'undefined') {
|
||||
return {};
|
||||
}
|
||||
|
||||
const utmParams = localStorage.getItem('utm_params');
|
||||
if (!utmParams) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return JSON.parse(utmParams);
|
||||
}
|
||||
|
||||
export function getUrlParams() {
|
||||
if (typeof window === 'undefined') {
|
||||
return {};
|
||||
|
Reference in New Issue
Block a user