Add UTM source and medium to app links

This commit is contained in:
ponas committed 2026-07-30 00:50:02 +02:00
1 parent d19066812e
commit 398876b6c8
5 files changed
+34 -5

No files matched your search

+2 -1
View File
@@ -2,11 +2,12 @@ import React from 'react';
import { Linking, StyleSheet, Text, TouchableOpacity } from 'react-native';
import theme from '@/theme';
import { withAppSource } from '@/utils';
const PrivacyButton = () => (
<TouchableOpacity
style={[theme.background, styles.button]}
onPress={() => Linking.openURL(process.env.EXPO_PUBLIC_DUSKEN_PRIVACY_POLICY_URL || '')}
onPress={() => Linking.openURL(withAppSource(process.env.EXPO_PUBLIC_DUSKEN_PRIVACY_POLICY_URL || ''))}
>
<Text style={styles.linkText}>Personvern</Text>
</TouchableOpacity>
+6 -2
View File
@@ -13,6 +13,7 @@ import {
import Button from '@/components/Button';
import theme from '@/theme';
import { withAppSource } from '@/utils';
import logo from '@assets/DNS-logo-svart.png';
import IconClock from '@assets/icons/clock.svg';
import IconFacebook from '@assets/icons/facebook.svg';
@@ -95,7 +96,7 @@ const About = () => (
<ScrollView style={theme.background}>
<View style={theme.card}>
<Text style={[theme.text, styles.header, { marginTop: 8 }]}>Det Norske Studentersamfund</Text>
<TouchableOpacity onPress={() => Linking.openURL('https://www.studentersamfundet.no/')}>
<TouchableOpacity onPress={() => Linking.openURL(withAppSource('https://neuf.no/'))}>
<Image style={styles.logo} source={logo} />
</TouchableOpacity>
<Text style={[theme.text, styles.header]}>Følg oss på</Text>
@@ -126,7 +127,10 @@ const About = () => (
</View>
<Text style={[theme.text, styles.header]}>Åpningstider</Text>
<View style={styles.section}>
<Button onPress={() => Linking.openURL('https://studentersamfundet.no/aapningstider/')} style={theme.button}>
<Button
onPress={() => Linking.openURL(withAppSource('https://neuf.no/praktisk#apningstider'))}
style={theme.button}
>
<IconClock width={20} height={20} style={styles.icon} />
<Text style={theme.buttonText}>Vis åpningstider</Text>
</Button>
+2 -1
View File
@@ -8,6 +8,7 @@ import { StyleSheet, View, Platform, FlatList, TouchableOpacity, Text, Linking }
import Button from '@/components/Button';
import theme from '@/theme';
import { EventType } from '@/types/data';
import { withAppSource } from '@/utils';
import useEventList from './useEventList';
@@ -25,7 +26,7 @@ const EventList = () => {
const renderItem = ({ item, index }: { item: EventType; index: number }) => (
<TouchableOpacity
onPress={() => {
return Linking.openURL(item.url);
return Linking.openURL(withAppSource(item.url));
}}
style={[styles.listItem, ...(index === events.length - 1 ? [styles.lastListItem] : [])]}
>
+2 -1
View File
@@ -5,6 +5,7 @@ import Button from '@/components/Button';
import FormErrors from '@/components/FormErrors';
import FormInput from '@/components/FormInput';
import theme from '@/theme';
import { withAppSource } from '@/utils';
import useLogin from './useLogin';
@@ -47,7 +48,7 @@ const Login = () => {
<Button
small
onPress={() => {
Linking.openURL(process.env.EXPO_PUBLIC_DUSKEN_FORGOT_PASSWORD_URL || '');
Linking.openURL(withAppSource(process.env.EXPO_PUBLIC_DUSKEN_FORGOT_PASSWORD_URL || ''));
}}
style={[theme.button, styles.forgotPasswordButton]}
>
+22
View File
@@ -1,3 +1,25 @@
// Sites tracked by our Umami instance. Subdomains (galtinn.neuf.no, www.*) match too.
const APP_SOURCE_DOMAINS = ['neuf.no', 'studentersamfundet.no'];
export function withAppSource(url: string): string {
/** Tags links to our own sites with UTM params, since app links carry no referrer */
let parsed: URL;
try {
parsed = new URL(url);
} catch {
return url;
}
const isOwnSite = APP_SOURCE_DOMAINS.some(
(domain) => parsed.hostname === domain || parsed.hostname.endsWith(`.${domain}`),
);
if (!isOwnSite) {
return url;
}
parsed.searchParams.set('utm_source', 'neuf-app');
parsed.searchParams.set('utm_medium', 'app');
return parsed.toString();
}
export function snakeToCamelCase(val: string): string {
return val.replace(/_([a-z])/g, (g) => g[1].toUpperCase());
}