Skip to content

Commit 9d3337f

Browse files
committed
feat(new tool): UTM URL Generator
UTM Url Generator Fix CorentinTh#935
1 parent d3b32cc commit 9d3337f

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer';
66

77
import { tool as textToUnicode } from './text-to-unicode';
88
import { tool as safelinkDecoder } from './safelink-decoder';
9+
import { tool as utmUrlGenerator } from './utm-url-generator';
910
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
1011
import { tool as numeronymGenerator } from './numeronym-generator';
1112
import { tool as macAddressGenerator } from './mac-address-generator';
@@ -115,6 +116,7 @@ export const toolsByCategory: ToolCategory[] = [
115116
urlEncoder,
116117
htmlEntities,
117118
urlParser,
119+
utmUrlGenerator,
118120
deviceInformation,
119121
basicAuthGenerator,
120122
metaTagGenerator,

src/tools/utm-url-generator/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Ad } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'UTM Url Generator',
6+
path: '/utm-url-generator',
7+
description: 'Generate an URL with utm_ parameters',
8+
keywords: ['utm', 'url', 'generator'],
9+
component: () => import('./utm-url-generator.vue'),
10+
icon: Ad,
11+
createdAt: new Date('2024-03-15'),
12+
});
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<script setup lang="ts">
2+
import { useCopy } from '@/composable/copy';
3+
import { useValidation } from '@/composable/validation';
4+
5+
const url = useStorage('utm-generator:url', '');
6+
const utmSource = useStorage('utm-generator:source', '');
7+
const utmMedium = useStorage('utm-generator:medium', '');
8+
const utmCampaign = useStorage('utm-generator:campaign', '');
9+
const utmContent = useStorage('utm-generator:content', '');
10+
const utmTerm = useStorage('utm-generator:term', '');
11+
const utmifiedUrl = computed(() => {
12+
try {
13+
const utmUrl = new URL(url.value);
14+
utmUrl.searchParams.set('utm_source', utmSource.value);
15+
utmUrl.searchParams.set('utm_medium', utmMedium.value);
16+
utmUrl.searchParams.set('utm_campaign', utmCampaign.value);
17+
if (utmContent.value) {
18+
utmUrl.searchParams.set('utm_content', utmContent.value);
19+
}
20+
if (utmContent.value) {
21+
utmUrl.searchParams.set('utm_term', utmTerm.value);
22+
}
23+
return utmUrl.href;
24+
}
25+
catch {
26+
return '# invalid inputs';
27+
}
28+
});
29+
30+
const urlValidation = useValidation({
31+
source: url,
32+
rules: [
33+
{
34+
message: 'Invalid url string',
35+
validator: (value) => {
36+
try {
37+
const _ = (new URL(value));
38+
return true;
39+
}
40+
catch {
41+
return false;
42+
}
43+
},
44+
},
45+
],
46+
});
47+
const utmMediumValidation = useValidation({
48+
source: utmMedium,
49+
rules: [
50+
{
51+
message: 'UTM Medium is required',
52+
validator: value => value !== '',
53+
},
54+
],
55+
});
56+
const utmSourceValidation = useValidation({
57+
source: utmSource,
58+
rules: [
59+
{
60+
message: 'UTM Source is required',
61+
validator: value => value !== '',
62+
},
63+
],
64+
});
65+
const utmCampaignValidation = useValidation({
66+
source: utmCampaign,
67+
rules: [
68+
{
69+
message: 'UTM Campaign is required',
70+
validator: value => value !== '',
71+
},
72+
],
73+
});
74+
const { copy } = useCopy({ source: utmifiedUrl, text: 'UTMified url copied.' });
75+
</script>
76+
77+
<template>
78+
<div>
79+
<n-p>
80+
For more info about UTM, see <n-a href="https://en.wikipedia.org/wiki/UTM_parameters" target="_blank" rel="noopener noreferrer">
81+
UTM Parameters
82+
</n-a>
83+
</n-p>
84+
85+
<c-input-text
86+
v-model:value="url"
87+
label="Website url"
88+
placeholder="Put your website url here..."
89+
clearable
90+
mb-2
91+
:validation="urlValidation"
92+
/>
93+
<c-input-text
94+
v-model:value="utmSource"
95+
label="UTM Source (Identifies which site sent the traffic)"
96+
placeholder="Put your UTM Source here..."
97+
clearable
98+
mb-2
99+
:validation="utmSourceValidation"
100+
/>
101+
<c-input-text
102+
v-model:value="utmMedium"
103+
label="UTM Medium (Identifies what type of link was used)"
104+
placeholder="Put your UTM Medium here..."
105+
clearable
106+
mb-2
107+
:validation="utmMediumValidation"
108+
/>
109+
<c-input-text
110+
v-model:value="utmCampaign"
111+
label="UTM Campaign (Identifies a specific product promotion or strategic campaign)"
112+
placeholder="Put your UTM Campaign here..."
113+
clearable
114+
mb-2
115+
:validation="utmCampaignValidation"
116+
/>
117+
<c-input-text
118+
v-model:value="utmContent"
119+
label="UTM Content (Identifies search terms)"
120+
placeholder="Put your UTM Content here..."
121+
clearable
122+
mb-2
123+
/>
124+
<c-input-text
125+
v-model:value="utmTerm"
126+
label="UTM Term (Identifies what specifically was clicked to bring the user to the site)"
127+
placeholder="Put your UTM Term here..."
128+
clearable
129+
mb-2
130+
/>
131+
132+
<div v-if="utmifiedUrl">
133+
<div mb-2>
134+
Your url with UTM parameters added
135+
</div>
136+
<c-card>
137+
{{ utmifiedUrl }}
138+
</c-card>
139+
140+
<div mt-3 flex justify-center>
141+
<c-button autofocus @click="copy()">
142+
Copy url
143+
</c-button>
144+
</div>
145+
</div>
146+
</div>
147+
</template>

0 commit comments

Comments
 (0)