@jjlmoya/utils-developer 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +64 -0
- package/src/category/i18n/en.ts +34 -0
- package/src/category/i18n/es.ts +34 -0
- package/src/category/i18n/fr.ts +34 -0
- package/src/category/index.ts +31 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +78 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/css_specificity_logic.test.ts +39 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +22 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/aspectRatio/bibliography.astro +14 -0
- package/src/tool/aspectRatio/component.astro +468 -0
- package/src/tool/aspectRatio/i18n/en.ts +177 -0
- package/src/tool/aspectRatio/i18n/es.ts +177 -0
- package/src/tool/aspectRatio/i18n/fr.ts +177 -0
- package/src/tool/aspectRatio/index.ts +34 -0
- package/src/tool/aspectRatio/seo.astro +14 -0
- package/src/tool/aspectRatio/ui.ts +12 -0
- package/src/tool/calculadoraTiempoDatos/bibliography.astro +14 -0
- package/src/tool/calculadoraTiempoDatos/component.astro +829 -0
- package/src/tool/calculadoraTiempoDatos/i18n/en.ts +150 -0
- package/src/tool/calculadoraTiempoDatos/i18n/es.ts +163 -0
- package/src/tool/calculadoraTiempoDatos/i18n/fr.ts +150 -0
- package/src/tool/calculadoraTiempoDatos/index.ts +33 -0
- package/src/tool/calculadoraTiempoDatos/seo.astro +14 -0
- package/src/tool/calculadoraTiempoDatos/ui.ts +24 -0
- package/src/tool/colorConverter/bibliography.astro +14 -0
- package/src/tool/colorConverter/component.astro +504 -0
- package/src/tool/colorConverter/i18n/en.ts +126 -0
- package/src/tool/colorConverter/i18n/es.ts +126 -0
- package/src/tool/colorConverter/i18n/fr.ts +126 -0
- package/src/tool/colorConverter/index.ts +33 -0
- package/src/tool/colorConverter/seo.astro +14 -0
- package/src/tool/colorConverter/ui.ts +16 -0
- package/src/tool/conversorExcelCsvHtml/bibliography.astro +14 -0
- package/src/tool/conversorExcelCsvHtml/component.astro +595 -0
- package/src/tool/conversorExcelCsvHtml/i18n/en.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/i18n/es.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/i18n/fr.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/index.ts +33 -0
- package/src/tool/conversorExcelCsvHtml/seo.astro +14 -0
- package/src/tool/conversorExcelCsvHtml/ui.ts +14 -0
- package/src/tool/cronGenerator/bibliography.astro +14 -0
- package/src/tool/cronGenerator/component.astro +667 -0
- package/src/tool/cronGenerator/i18n/en.ts +191 -0
- package/src/tool/cronGenerator/i18n/es.ts +191 -0
- package/src/tool/cronGenerator/i18n/fr.ts +191 -0
- package/src/tool/cronGenerator/index.ts +34 -0
- package/src/tool/cronGenerator/seo.astro +14 -0
- package/src/tool/cronGenerator/ui.ts +45 -0
- package/src/tool/cssSpecificityCalculator/bibliography.astro +14 -0
- package/src/tool/cssSpecificityCalculator/component.astro +292 -0
- package/src/tool/cssSpecificityCalculator/i18n/en.ts +168 -0
- package/src/tool/cssSpecificityCalculator/i18n/es.ts +168 -0
- package/src/tool/cssSpecificityCalculator/i18n/fr.ts +168 -0
- package/src/tool/cssSpecificityCalculator/index.ts +34 -0
- package/src/tool/cssSpecificityCalculator/logic.ts +100 -0
- package/src/tool/cssSpecificityCalculator/seo.astro +14 -0
- package/src/tool/cssSpecificityCalculator/ui-controller.ts +57 -0
- package/src/tool/cssSpecificityCalculator/ui.ts +11 -0
- package/src/tool/cssToInlineConverter/bibliography.astro +14 -0
- package/src/tool/cssToInlineConverter/component.astro +308 -0
- package/src/tool/cssToInlineConverter/i18n/en.ts +160 -0
- package/src/tool/cssToInlineConverter/i18n/es.ts +160 -0
- package/src/tool/cssToInlineConverter/i18n/fr.ts +160 -0
- package/src/tool/cssToInlineConverter/index.ts +34 -0
- package/src/tool/cssToInlineConverter/seo.astro +14 -0
- package/src/tool/cssToInlineConverter/ui.ts +12 -0
- package/src/tool/duplicateCssRemover/bibliography.astro +14 -0
- package/src/tool/duplicateCssRemover/component.astro +353 -0
- package/src/tool/duplicateCssRemover/i18n/en.ts +167 -0
- package/src/tool/duplicateCssRemover/i18n/es.ts +167 -0
- package/src/tool/duplicateCssRemover/i18n/fr.ts +167 -0
- package/src/tool/duplicateCssRemover/index.ts +34 -0
- package/src/tool/duplicateCssRemover/seo.astro +14 -0
- package/src/tool/duplicateCssRemover/ui.ts +12 -0
- package/src/tool/generadorSecurityTxt/bibliography.astro +14 -0
- package/src/tool/generadorSecurityTxt/component.astro +473 -0
- package/src/tool/generadorSecurityTxt/i18n/en.ts +173 -0
- package/src/tool/generadorSecurityTxt/i18n/es.ts +173 -0
- package/src/tool/generadorSecurityTxt/i18n/fr.ts +173 -0
- package/src/tool/generadorSecurityTxt/index.ts +33 -0
- package/src/tool/generadorSecurityTxt/seo.astro +14 -0
- package/src/tool/generadorSecurityTxt/ui.ts +27 -0
- package/src/tool/hashGenerator/bibliography.astro +14 -0
- package/src/tool/hashGenerator/component.astro +367 -0
- package/src/tool/hashGenerator/i18n/en.ts +118 -0
- package/src/tool/hashGenerator/i18n/es.ts +118 -0
- package/src/tool/hashGenerator/i18n/fr.ts +118 -0
- package/src/tool/hashGenerator/index.ts +33 -0
- package/src/tool/hashGenerator/md5.ts +138 -0
- package/src/tool/hashGenerator/seo.astro +14 -0
- package/src/tool/hashGenerator/ui.ts +11 -0
- package/src/tool/inspectorCertificadosSsl/bibliography.astro +14 -0
- package/src/tool/inspectorCertificadosSsl/component.astro +580 -0
- package/src/tool/inspectorCertificadosSsl/i18n/en.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/i18n/es.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/i18n/fr.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/index.ts +33 -0
- package/src/tool/inspectorCertificadosSsl/seo.astro +14 -0
- package/src/tool/inspectorCertificadosSsl/ui.ts +29 -0
- package/src/tool/jsonFormatter/bibliography.astro +14 -0
- package/src/tool/jsonFormatter/component.astro +590 -0
- package/src/tool/jsonFormatter/i18n/en.ts +156 -0
- package/src/tool/jsonFormatter/i18n/es.ts +156 -0
- package/src/tool/jsonFormatter/i18n/fr.ts +156 -0
- package/src/tool/jsonFormatter/index.ts +34 -0
- package/src/tool/jsonFormatter/seo.astro +14 -0
- package/src/tool/jsonFormatter/ui.ts +15 -0
- package/src/tool/keycode/bibliography.astro +14 -0
- package/src/tool/keycode/component.astro +540 -0
- package/src/tool/keycode/i18n/en.ts +160 -0
- package/src/tool/keycode/i18n/es.ts +160 -0
- package/src/tool/keycode/i18n/fr.ts +160 -0
- package/src/tool/keycode/index.ts +34 -0
- package/src/tool/keycode/seo.astro +14 -0
- package/src/tool/keycode/ui.ts +10 -0
- package/src/tool/llmCostCalculator/bibliography.astro +14 -0
- package/src/tool/llmCostCalculator/component.astro +488 -0
- package/src/tool/llmCostCalculator/data.ts +99 -0
- package/src/tool/llmCostCalculator/i18n/en.ts +165 -0
- package/src/tool/llmCostCalculator/i18n/es.ts +165 -0
- package/src/tool/llmCostCalculator/i18n/fr.ts +165 -0
- package/src/tool/llmCostCalculator/index.ts +34 -0
- package/src/tool/llmCostCalculator/seo.astro +14 -0
- package/src/tool/llmCostCalculator/ui.ts +11 -0
- package/src/tool/mobileMockupGenerator/app.ts +614 -0
- package/src/tool/mobileMockupGenerator/bibliography.astro +14 -0
- package/src/tool/mobileMockupGenerator/component.astro +1044 -0
- package/src/tool/mobileMockupGenerator/constants.ts +48 -0
- package/src/tool/mobileMockupGenerator/i18n/en.ts +121 -0
- package/src/tool/mobileMockupGenerator/i18n/es.ts +121 -0
- package/src/tool/mobileMockupGenerator/i18n/fr.ts +121 -0
- package/src/tool/mobileMockupGenerator/index.ts +33 -0
- package/src/tool/mobileMockupGenerator/rendering.ts +189 -0
- package/src/tool/mobileMockupGenerator/seo.astro +14 -0
- package/src/tool/mobileMockupGenerator/store.ts +145 -0
- package/src/tool/mobileMockupGenerator/types.ts +41 -0
- package/src/tool/mobileMockupGenerator/ui.ts +48 -0
- package/src/tool/musicalTypography/bibliography.astro +14 -0
- package/src/tool/musicalTypography/component.astro +480 -0
- package/src/tool/musicalTypography/i18n/en.ts +179 -0
- package/src/tool/musicalTypography/i18n/es.ts +179 -0
- package/src/tool/musicalTypography/i18n/fr.ts +179 -0
- package/src/tool/musicalTypography/index.ts +33 -0
- package/src/tool/musicalTypography/seo.astro +14 -0
- package/src/tool/musicalTypography/ui.ts +25 -0
- package/src/tool/placeholderGenerator/bibliography.astro +14 -0
- package/src/tool/placeholderGenerator/component.astro +499 -0
- package/src/tool/placeholderGenerator/i18n/en.ts +176 -0
- package/src/tool/placeholderGenerator/i18n/es.ts +176 -0
- package/src/tool/placeholderGenerator/i18n/fr.ts +176 -0
- package/src/tool/placeholderGenerator/index.ts +34 -0
- package/src/tool/placeholderGenerator/seo.astro +14 -0
- package/src/tool/placeholderGenerator/ui.ts +14 -0
- package/src/tool/promptLibrary/bibliography.astro +14 -0
- package/src/tool/promptLibrary/component.astro +1131 -0
- package/src/tool/promptLibrary/controller.ts +49 -0
- package/src/tool/promptLibrary/i18n/en.ts +131 -0
- package/src/tool/promptLibrary/i18n/es.ts +131 -0
- package/src/tool/promptLibrary/i18n/fr.ts +126 -0
- package/src/tool/promptLibrary/index.ts +33 -0
- package/src/tool/promptLibrary/seo.astro +14 -0
- package/src/tool/promptLibrary/ui.ts +29 -0
- package/src/tool/readabilityCalculator/bibliography.astro +14 -0
- package/src/tool/readabilityCalculator/component.astro +534 -0
- package/src/tool/readabilityCalculator/i18n/en.ts +133 -0
- package/src/tool/readabilityCalculator/i18n/es.ts +133 -0
- package/src/tool/readabilityCalculator/i18n/fr.ts +133 -0
- package/src/tool/readabilityCalculator/index.ts +33 -0
- package/src/tool/readabilityCalculator/seo.astro +14 -0
- package/src/tool/readabilityCalculator/ui.ts +27 -0
- package/src/tool/svgSanitizer/bibliography.astro +14 -0
- package/src/tool/svgSanitizer/component.astro +554 -0
- package/src/tool/svgSanitizer/i18n/en.ts +125 -0
- package/src/tool/svgSanitizer/i18n/es.ts +125 -0
- package/src/tool/svgSanitizer/i18n/fr.ts +125 -0
- package/src/tool/svgSanitizer/index.ts +33 -0
- package/src/tool/svgSanitizer/seo.astro +14 -0
- package/src/tool/svgSanitizer/ui.ts +18 -0
- package/src/tool/svgToCss/bibliography.astro +14 -0
- package/src/tool/svgToCss/component.astro +381 -0
- package/src/tool/svgToCss/i18n/en.ts +174 -0
- package/src/tool/svgToCss/i18n/es.ts +174 -0
- package/src/tool/svgToCss/i18n/fr.ts +174 -0
- package/src/tool/svgToCss/index.ts +34 -0
- package/src/tool/svgToCss/seo.astro +14 -0
- package/src/tool/svgToCss/ui.ts +13 -0
- package/src/tool/urlCleaner/bibliography.astro +14 -0
- package/src/tool/urlCleaner/component.astro +458 -0
- package/src/tool/urlCleaner/i18n/en.ts +116 -0
- package/src/tool/urlCleaner/i18n/es.ts +116 -0
- package/src/tool/urlCleaner/i18n/fr.ts +116 -0
- package/src/tool/urlCleaner/index.ts +33 -0
- package/src/tool/urlCleaner/seo.astro +14 -0
- package/src/tool/urlCleaner/ui.ts +12 -0
- package/src/tool/urlEncoderDecoder/bibliography.astro +14 -0
- package/src/tool/urlEncoderDecoder/component.astro +291 -0
- package/src/tool/urlEncoderDecoder/i18n/en.ts +162 -0
- package/src/tool/urlEncoderDecoder/i18n/es.ts +162 -0
- package/src/tool/urlEncoderDecoder/i18n/fr.ts +162 -0
- package/src/tool/urlEncoderDecoder/index.ts +34 -0
- package/src/tool/urlEncoderDecoder/seo.astro +14 -0
- package/src/tool/urlEncoderDecoder/ui.ts +11 -0
- package/src/tool/utmGenerator/bibliography.astro +14 -0
- package/src/tool/utmGenerator/component.astro +270 -0
- package/src/tool/utmGenerator/i18n/en.ts +117 -0
- package/src/tool/utmGenerator/i18n/es.ts +117 -0
- package/src/tool/utmGenerator/i18n/fr.ts +117 -0
- package/src/tool/utmGenerator/index.ts +33 -0
- package/src/tool/utmGenerator/seo.astro +14 -0
- package/src/tool/utmGenerator/ui.ts +13 -0
- package/src/tools.ts +27 -0
- package/src/types.ts +72 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { UtmGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'utm-generator';
|
|
6
|
+
const title = 'UTM Parameter Generator for Google Analytics';
|
|
7
|
+
const description = 'Create precise tracking links for your digital marketing campaigns. Optimized for Google Analytics and other analytics tools.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: 'Is using UTM parameters bad for SEO?',
|
|
12
|
+
answer: 'No, as long as you use canonical tags. Search engines understand that UTM parameters are for analytics and do not create duplicate content.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Should I use UTM parameters for internal links?',
|
|
16
|
+
answer: 'No, never. UTM tags on internal links break the user session in tools like Google Analytics, distorting your traffic data.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Does Google Analytics distinguish between uppercase and lowercase in UTM?',
|
|
20
|
+
answer: 'Yes. "google", "Google" and "GOOGLE" will be treated as different sources. Always maintain consistency, preferably using only lowercase.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{ name: 'Enter the URL', text: 'Input the complete URL of your website, including https://' },
|
|
26
|
+
{ name: 'Define the source', text: 'Specify where the traffic comes from (google, facebook, newsletter, etc.)' },
|
|
27
|
+
{ name: 'Select the medium', text: 'Choose the type of channel (cpc, email, social, organic, etc.)' },
|
|
28
|
+
{ name: 'Name your campaign', text: 'Assign an identifiable name to group your marketing efforts' },
|
|
29
|
+
{ name: 'Copy and use', text: 'Copy the generated URL and use it in your posts, ads or email signatures' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
33
|
+
'@context': 'https://schema.org',
|
|
34
|
+
'@type': 'FAQPage',
|
|
35
|
+
mainEntity: faqData.map((item) => ({
|
|
36
|
+
'@type': 'Question',
|
|
37
|
+
name: item.question,
|
|
38
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
43
|
+
'@context': 'https://schema.org',
|
|
44
|
+
'@type': 'HowTo',
|
|
45
|
+
name: title,
|
|
46
|
+
description,
|
|
47
|
+
step: howToData.map((s, i) => ({ '@type': 'HowToStep', position: i + 1, name: s.name, text: s.text })),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
51
|
+
'@context': 'https://schema.org',
|
|
52
|
+
'@type': 'SoftwareApplication',
|
|
53
|
+
name: title,
|
|
54
|
+
description,
|
|
55
|
+
applicationCategory: 'UtilityApplication',
|
|
56
|
+
operatingSystem: 'All',
|
|
57
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
58
|
+
inLanguage: 'en',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const ui: UtmGeneratorUI = {
|
|
62
|
+
labelUrl: 'Website URL (e.g. https://example.com) *',
|
|
63
|
+
labelSource: 'Campaign source (e.g. google, newsletter) *',
|
|
64
|
+
labelMedium: 'Campaign medium (e.g. cpc, email)',
|
|
65
|
+
labelCampaign: 'Campaign name (e.g. summer_offer)',
|
|
66
|
+
labelTerm: 'Campaign term (e.g. buy_shoes)',
|
|
67
|
+
labelContent: 'Campaign content (e.g. banner_top)',
|
|
68
|
+
labelGenerated: 'Generated URL:',
|
|
69
|
+
btnCopy: 'Copy Link',
|
|
70
|
+
btnCopied: 'Copied!',
|
|
71
|
+
errorInvalid: 'Enter a valid URL',
|
|
72
|
+
errorInvalidUrl: 'Invalid URL',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const content: ToolLocaleContent<UtmGeneratorUI> = {
|
|
76
|
+
slug,
|
|
77
|
+
title,
|
|
78
|
+
description,
|
|
79
|
+
ui,
|
|
80
|
+
faqTitle: 'Frequently Asked Questions',
|
|
81
|
+
faq: faqData,
|
|
82
|
+
bibliographyTitle: 'References',
|
|
83
|
+
bibliography: [
|
|
84
|
+
{ name: 'Collect campaign data with custom URLs - Google Analytics Help (2024)', url: 'https://support.google.com/analytics/answer/1033863' },
|
|
85
|
+
{ name: 'Best Practices for Campaign URL Tagging - VWO Blog (2023)', url: 'https://vwo.com/blog/utm-tagging-best-practices/' },
|
|
86
|
+
],
|
|
87
|
+
howTo: howToData,
|
|
88
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
89
|
+
seo: [
|
|
90
|
+
{ type: 'title', text: 'UTM Generator: Tracking Parameters for Google Analytics', level: 2 },
|
|
91
|
+
{
|
|
92
|
+
type: 'paragraph',
|
|
93
|
+
html: '<strong>UTM</strong> parameters (Urchin Tracking Module) are text labels added to the end of a URL to track web traffic. Our generator simplifies creating trackable links for your digital marketing campaigns.',
|
|
94
|
+
},
|
|
95
|
+
{ type: 'title', text: 'The 5 Pillars of a Trackable URL', level: 3 },
|
|
96
|
+
{
|
|
97
|
+
type: 'list',
|
|
98
|
+
items: [
|
|
99
|
+
'<strong>Campaign Source:</strong> Identifies the search engine, social network or traffic origin. Example: google, newsletter, facebook.',
|
|
100
|
+
'<strong>Campaign Medium:</strong> Refers to the marketing channel. Example: cpc, email, social, banner, organic.',
|
|
101
|
+
'<strong>Campaign Name:</strong> The specific name of your campaign. Example: summer_offer_2025, app_launch_v2.',
|
|
102
|
+
'<strong>Campaign Term:</strong> For paid searches, the keywords you bid on. Example: buy_sports_shoes.',
|
|
103
|
+
'<strong>Campaign Content:</strong> For A/B testing. Differentiates similar elements within a campaign. Example: header_v1, sidebar_v2.',
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{ type: 'title', text: 'Best Practices for UTM Tagging', level: 3 },
|
|
107
|
+
{
|
|
108
|
+
type: 'list',
|
|
109
|
+
items: [
|
|
110
|
+
'<strong>Case consistency:</strong> Tools differentiate "Google", "GOOGLE" and "google". Always use lowercase to avoid duplicates.',
|
|
111
|
+
'<strong>Avoid spaces:</strong> Spaces become %20. Use hyphens (-) or underscores (_) instead.',
|
|
112
|
+
'<strong>Don\'t use on internal links:</strong> UTM tracking is exclusively for external traffic. On internal links, it breaks the session and ruins key metrics.',
|
|
113
|
+
'<strong>Document your tags:</strong> Keep a record of all combinations you use to prevent inconsistencies.',
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { UtmGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'generador-utm';
|
|
6
|
+
const title = 'Generador de Parámetros UTM para Google Analytics';
|
|
7
|
+
const description = 'Crea enlaces de seguimiento precisos para tus campañas de marketing digital. Optimizado para Google Analytics y otras herramientas de analítica.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: '¿Es perjudicial para el SEO usar parámetros UTM?',
|
|
12
|
+
answer: 'No, siempre que uses etiquetas canónicas. Los buscadores entienden que los parámetros UTM son para analítica y no crean contenido duplicado.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: '¿Debo usar parámetros UTM para enlaces internos?',
|
|
16
|
+
answer: 'No, nunca. Las etiquetas UTM en enlaces internos rompen la sesión del usuario en herramientas como Google Analytics, distorsionando tus datos de tráfico.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: '¿Google Analytics distingue entre mayúsculas y minúsculas en UTM?',
|
|
20
|
+
answer: 'Sí. "google", "Google" y "GOOGLE" se tratarán como fuentes diferentes. Mantén siempre la consistencia, preferiblemente usando solo minúsculas.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{ name: 'Ingresa la URL', text: 'Introduce la URL completa de tu sitio web, incluyendo https://' },
|
|
26
|
+
{ name: 'Define la fuente', text: 'Especifica de dónde viene el tráfico (google, facebook, newsletter, etc.)' },
|
|
27
|
+
{ name: 'Selecciona el medio', text: 'Elige el tipo de canal (cpc, email, social, organic, etc.)' },
|
|
28
|
+
{ name: 'Nombra tu campaña', text: 'Asigna un nombre identificable para agrupar tus esfuerzos de marketing' },
|
|
29
|
+
{ name: 'Copia y utiliza', text: 'Copia la URL generada y úsala en tus publicaciones, anuncios o firmas de correo' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
33
|
+
'@context': 'https://schema.org',
|
|
34
|
+
'@type': 'FAQPage',
|
|
35
|
+
mainEntity: faqData.map((item) => ({
|
|
36
|
+
'@type': 'Question',
|
|
37
|
+
name: item.question,
|
|
38
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
43
|
+
'@context': 'https://schema.org',
|
|
44
|
+
'@type': 'HowTo',
|
|
45
|
+
name: title,
|
|
46
|
+
description,
|
|
47
|
+
step: howToData.map((s, i) => ({ '@type': 'HowToStep', position: i + 1, name: s.name, text: s.text })),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
51
|
+
'@context': 'https://schema.org',
|
|
52
|
+
'@type': 'SoftwareApplication',
|
|
53
|
+
name: title,
|
|
54
|
+
description,
|
|
55
|
+
applicationCategory: 'UtilityApplication',
|
|
56
|
+
operatingSystem: 'All',
|
|
57
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
58
|
+
inLanguage: 'es',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const ui: UtmGeneratorUI = {
|
|
62
|
+
labelUrl: 'URL del sitio web (p. ej. https://ejemplo.com) *',
|
|
63
|
+
labelSource: 'Fuente de la campaña (p. ej. google, newsletter) *',
|
|
64
|
+
labelMedium: 'Medio de la campaña (p. ej. cpc, email)',
|
|
65
|
+
labelCampaign: 'Nombre de la campaña (p. ej. oferta_verano)',
|
|
66
|
+
labelTerm: 'Término de la campaña (p. ej. comprar_zapatos)',
|
|
67
|
+
labelContent: 'Contenido de la campaña (p. ej. banner_superior)',
|
|
68
|
+
labelGenerated: 'URL Generada:',
|
|
69
|
+
btnCopy: 'Copiar Enlace',
|
|
70
|
+
btnCopied: '¡Copiado!',
|
|
71
|
+
errorInvalid: 'Introduce una URL válida',
|
|
72
|
+
errorInvalidUrl: 'URL no válida',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const content: ToolLocaleContent<UtmGeneratorUI> = {
|
|
76
|
+
slug,
|
|
77
|
+
title,
|
|
78
|
+
description,
|
|
79
|
+
ui,
|
|
80
|
+
faqTitle: 'Preguntas Frecuentes',
|
|
81
|
+
faq: faqData,
|
|
82
|
+
bibliographyTitle: 'Referencias',
|
|
83
|
+
bibliography: [
|
|
84
|
+
{ name: 'Collect campaign data with custom URLs - Google Analytics Help (2024)', url: 'https://support.google.com/analytics/answer/1033863' },
|
|
85
|
+
{ name: 'Best Practices for Campaign URL Tagging - VWO Blog (2023)', url: 'https://vwo.com/blog/utm-tagging-best-practices/' },
|
|
86
|
+
],
|
|
87
|
+
howTo: howToData,
|
|
88
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
89
|
+
seo: [
|
|
90
|
+
{ type: 'title', text: 'Generador UTM: Parámetros de Seguimiento para Google Analytics', level: 2 },
|
|
91
|
+
{
|
|
92
|
+
type: 'paragraph',
|
|
93
|
+
html: 'Los parámetros <strong>UTM</strong> (Urchin Tracking Module) son etiquetas de texto que se añaden al final de una URL para realizar un seguimiento del tráfico web. Nuestro generador simplifica la creación de enlaces rastreables para tus campañas de marketing digital.',
|
|
94
|
+
},
|
|
95
|
+
{ type: 'title', text: 'Los 5 pilares de una URL rastreable', level: 3 },
|
|
96
|
+
{
|
|
97
|
+
type: 'list',
|
|
98
|
+
items: [
|
|
99
|
+
'<strong>Campaign Source (Fuente):</strong> Identifica el buscador, la red social o el origen del tráfico. Ejemplo: google, newsletter, facebook.',
|
|
100
|
+
'<strong>Campaign Medium (Medio):</strong> Se refiere al canal de marketing. Ejemplo: cpc, email, social, banner, organico.',
|
|
101
|
+
'<strong>Campaign Name (Nombre):</strong> El nombre específico de tu campaña. Ejemplo: oferta_verano_2025, lanzamiento_app_v2.',
|
|
102
|
+
'<strong>Campaign Term (Término):</strong> Para búsquedas pagadas, las palabras clave por las que has pujado. Ejemplo: comprar_zapatos_deportivos.',
|
|
103
|
+
'<strong>Campaign Content (Contenido):</strong> Para A/B testing. Diferencia elementos similares dentro de una campaña. Ejemplo: header_v1, sidebar_v2.',
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{ type: 'title', text: 'Mejores prácticas para el etiquetado UTM', level: 3 },
|
|
107
|
+
{
|
|
108
|
+
type: 'list',
|
|
109
|
+
items: [
|
|
110
|
+
'<strong>Consistencia en mayúsculas:</strong> Las herramientas diferencian "Google", "GOOGLE" y "google". Usa siempre minúsculas para evitar duplicidades.',
|
|
111
|
+
'<strong>Evita los espacios:</strong> Los espacios se convierten en %20. Usa guiones medios (-) o guiones bajos (_) en su lugar.',
|
|
112
|
+
'<strong>No uses en enlaces internos:</strong> El seguimiento UTM es exclusivamente para tráfico externo. En enlaces internos rompe la sesión y arruina métricas clave.',
|
|
113
|
+
'<strong>Documenta tus etiquetas:</strong> Mantén un registro de todas las combinaciones que uses para evitar inconsistencias.',
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { UtmGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'generateur-utm';
|
|
6
|
+
const title = 'Générateur de Paramètres UTM pour Google Analytics';
|
|
7
|
+
const description = 'Créez des liens de suivi précis pour vos campagnes de marketing numérique. Optimisé pour Google Analytics et autres outils d\'analyse.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: 'L\'utilisation de paramètres UTM est-elle préjudiciable au référencement?',
|
|
12
|
+
answer: 'Non, à condition d\'utiliser des balises canoniques. Les moteurs de recherche comprennent que les paramètres UTM sont destinés à l\'analyse et ne créent pas de contenu dupliqué.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Dois-je utiliser des paramètres UTM pour les liens internes?',
|
|
16
|
+
answer: 'Non, jamais. Les balises UTM sur les liens internes rompent la session de l\'utilisateur dans des outils comme Google Analytics, faussant vos données de trafic.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Google Analytics distingue-t-il les majuscules et minuscules dans les UTM?',
|
|
20
|
+
answer: 'Oui. "google", "Google" et "GOOGLE" seront traités comme des sources différentes. Maintenez toujours la cohérence, de préférence en utilisant uniquement des minuscules.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{ name: 'Entrez l\'URL', text: 'Saisissez l\'URL complète de votre site Web, y compris https://' },
|
|
26
|
+
{ name: 'Définissez la source', text: 'Spécifiez d\'où provient le trafic (google, facebook, newsletter, etc.)' },
|
|
27
|
+
{ name: 'Sélectionnez le medium', text: 'Choisissez le type de canal (cpc, email, social, organic, etc.)' },
|
|
28
|
+
{ name: 'Nommez votre campagne', text: 'Attribuez un nom identifiable pour regrouper vos efforts marketing' },
|
|
29
|
+
{ name: 'Copiez et utilisez', text: 'Copiez l\'URL générée et utilisez-la dans vos publications, annonces ou signatures d\'e-mail' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
33
|
+
'@context': 'https://schema.org',
|
|
34
|
+
'@type': 'FAQPage',
|
|
35
|
+
mainEntity: faqData.map((item) => ({
|
|
36
|
+
'@type': 'Question',
|
|
37
|
+
name: item.question,
|
|
38
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
43
|
+
'@context': 'https://schema.org',
|
|
44
|
+
'@type': 'HowTo',
|
|
45
|
+
name: title,
|
|
46
|
+
description,
|
|
47
|
+
step: howToData.map((s, i) => ({ '@type': 'HowToStep', position: i + 1, name: s.name, text: s.text })),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
51
|
+
'@context': 'https://schema.org',
|
|
52
|
+
'@type': 'SoftwareApplication',
|
|
53
|
+
name: title,
|
|
54
|
+
description,
|
|
55
|
+
applicationCategory: 'UtilityApplication',
|
|
56
|
+
operatingSystem: 'All',
|
|
57
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
58
|
+
inLanguage: 'fr',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const ui: UtmGeneratorUI = {
|
|
62
|
+
labelUrl: 'URL du site Web (p. ex. https://exemple.com) *',
|
|
63
|
+
labelSource: 'Source de la campagne (p. ex. google, newsletter) *',
|
|
64
|
+
labelMedium: 'Medium de la campagne (p. ex. cpc, email)',
|
|
65
|
+
labelCampaign: 'Nom de la campagne (p. ex. offre_ete)',
|
|
66
|
+
labelTerm: 'Terme de la campagne (p. ex. acheter_chaussures)',
|
|
67
|
+
labelContent: 'Contenu de la campagne (p. ex. banniere_haut)',
|
|
68
|
+
labelGenerated: 'URL Générée:',
|
|
69
|
+
btnCopy: 'Copier le Lien',
|
|
70
|
+
btnCopied: 'Copié!',
|
|
71
|
+
errorInvalid: 'Entrez une URL valide',
|
|
72
|
+
errorInvalidUrl: 'URL invalide',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const content: ToolLocaleContent<UtmGeneratorUI> = {
|
|
76
|
+
slug,
|
|
77
|
+
title,
|
|
78
|
+
description,
|
|
79
|
+
ui,
|
|
80
|
+
faqTitle: 'Questions Fréquemment Posées',
|
|
81
|
+
faq: faqData,
|
|
82
|
+
bibliographyTitle: 'Références',
|
|
83
|
+
bibliography: [
|
|
84
|
+
{ name: 'Collect campaign data with custom URLs - Google Analytics Help (2024)', url: 'https://support.google.com/analytics/answer/1033863' },
|
|
85
|
+
{ name: 'Best Practices for Campaign URL Tagging - VWO Blog (2023)', url: 'https://vwo.com/blog/utm-tagging-best-practices/' },
|
|
86
|
+
],
|
|
87
|
+
howTo: howToData,
|
|
88
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
89
|
+
seo: [
|
|
90
|
+
{ type: 'title', text: 'Générateur UTM: Paramètres de Suivi pour Google Analytics', level: 2 },
|
|
91
|
+
{
|
|
92
|
+
type: 'paragraph',
|
|
93
|
+
html: 'Les paramètres <strong>UTM</strong> (Urchin Tracking Module) sont des libellés de texte ajoutés à la fin d\'une URL pour suivre le trafic Web. Notre générateur simplifie la création de liens traçables pour vos campagnes de marketing numérique.',
|
|
94
|
+
},
|
|
95
|
+
{ type: 'title', text: 'Les 5 Piliers d\'une URL Traçable', level: 3 },
|
|
96
|
+
{
|
|
97
|
+
type: 'list',
|
|
98
|
+
items: [
|
|
99
|
+
'<strong>Campaign Source (Source):</strong> Identifie le moteur de recherche, le réseau social ou l\'origine du trafic. Exemple: google, newsletter, facebook.',
|
|
100
|
+
'<strong>Campaign Medium (Medium):</strong> Fait référence au canal marketing. Exemple: cpc, email, social, banner, organic.',
|
|
101
|
+
'<strong>Campaign Name (Nom):</strong> Le nom spécifique de votre campagne. Exemple: offre_ete_2025, lancement_app_v2.',
|
|
102
|
+
'<strong>Campaign Term (Terme):</strong> Pour les recherches payantes, les mots-clés sur lesquels vous enchérissez. Exemple: acheter_chaussures_sport.',
|
|
103
|
+
'<strong>Campaign Content (Contenu):</strong> Pour les tests A/B. Différencie les éléments similaires d\'une campagne. Exemple: header_v1, sidebar_v2.',
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{ type: 'title', text: 'Meilleures Pratiques pour l\'Étiquetage UTM', level: 3 },
|
|
107
|
+
{
|
|
108
|
+
type: 'list',
|
|
109
|
+
items: [
|
|
110
|
+
'<strong>Cohérence de casse:</strong> Les outils distinguent "Google", "GOOGLE" et "google". Utilisez toujours les minuscules pour éviter les doublons.',
|
|
111
|
+
'<strong>Évitez les espaces:</strong> Les espaces deviennent %20. Utilisez des tirets (-) ou des traits de soulignement (_) à la place.',
|
|
112
|
+
'<strong>Ne l\'utilisez pas sur les liens internes:</strong> Le suivi UTM est exclusivement pour le trafic externe. Sur les liens internes, il casse la session et détruit les métriques clés.',
|
|
113
|
+
'<strong>Documentez vos étiquettes:</strong> Gardez un enregistrement de toutes les combinaisons que vous utilisez pour éviter les incohérences.',
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DeveloperToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
|
|
2
|
+
import UtmGeneratorComponent from './component.astro';
|
|
3
|
+
import UtmGeneratorSEO from './seo.astro';
|
|
4
|
+
import UtmGeneratorBibliography from './bibliography.astro';
|
|
5
|
+
import type { UtmGeneratorUI } from './ui';
|
|
6
|
+
|
|
7
|
+
export type UtmGeneratorLocaleContent = ToolLocaleContent<UtmGeneratorUI>;
|
|
8
|
+
|
|
9
|
+
import { content as es } from './i18n/es';
|
|
10
|
+
import { content as en } from './i18n/en';
|
|
11
|
+
import { content as fr } from './i18n/fr';
|
|
12
|
+
|
|
13
|
+
export const utmGenerator: DeveloperToolEntry<UtmGeneratorUI> = {
|
|
14
|
+
id: 'utm-generator',
|
|
15
|
+
icons: {
|
|
16
|
+
bg: 'mdi:link-variant',
|
|
17
|
+
fg: 'mdi:tag-multiple',
|
|
18
|
+
},
|
|
19
|
+
i18n: {
|
|
20
|
+
es: async () => es,
|
|
21
|
+
en: async () => en,
|
|
22
|
+
fr: async () => fr,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { UtmGeneratorComponent, UtmGeneratorSEO, UtmGeneratorBibliography };
|
|
27
|
+
|
|
28
|
+
export const UTM_GENERATOR_TOOL: ToolDefinition = {
|
|
29
|
+
entry: utmGenerator,
|
|
30
|
+
Component: UtmGeneratorComponent,
|
|
31
|
+
SEOComponent: UtmGeneratorSEO,
|
|
32
|
+
BibliographyComponent: UtmGeneratorBibliography,
|
|
33
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { utmGenerator } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await utmGenerator.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SEORenderer content={{ locale, sections: content.seo }} />}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UtmGeneratorUI extends Record<string, string> {
|
|
2
|
+
labelUrl: string;
|
|
3
|
+
labelSource: string;
|
|
4
|
+
labelMedium: string;
|
|
5
|
+
labelCampaign: string;
|
|
6
|
+
labelTerm: string;
|
|
7
|
+
labelContent: string;
|
|
8
|
+
labelGenerated: string;
|
|
9
|
+
btnCopy: string;
|
|
10
|
+
btnCopied: string;
|
|
11
|
+
errorInvalid: string;
|
|
12
|
+
errorInvalidUrl: string;
|
|
13
|
+
}
|
package/src/tools.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ToolDefinition } from './types';
|
|
2
|
+
import { JSON_FORMATTER_TOOL } from './tool/jsonFormatter/index';
|
|
3
|
+
import { SVG_TO_CSS_TOOL } from './tool/svgToCss/index';
|
|
4
|
+
import { ASPECT_RATIO_TOOL } from './tool/aspectRatio/index';
|
|
5
|
+
import { PLACEHOLDER_GENERATOR_TOOL } from './tool/placeholderGenerator/index';
|
|
6
|
+
import { URL_ENCODER_DECODER_TOOL } from './tool/urlEncoderDecoder/index';
|
|
7
|
+
import { DUPLICATE_CSS_REMOVER_TOOL } from './tool/duplicateCssRemover/index';
|
|
8
|
+
import { CSS_TO_INLINE_CONVERTER_TOOL } from './tool/cssToInlineConverter/index';
|
|
9
|
+
import { CSS_SPECIFICITY_CALCULATOR_TOOL } from './tool/cssSpecificityCalculator/index';
|
|
10
|
+
import { CRON_GENERATOR_TOOL } from './tool/cronGenerator/index';
|
|
11
|
+
import { KEYCODE_TOOL } from './tool/keycode/index';
|
|
12
|
+
import { LLM_COST_CALCULATOR_TOOL } from './tool/llmCostCalculator/index';
|
|
13
|
+
import { MUSICAL_TYPOGRAPHY_TOOL } from './tool/musicalTypography/index';
|
|
14
|
+
import { MOBILE_MOCKUP_GENERATOR_TOOL } from './tool/mobileMockupGenerator/index';
|
|
15
|
+
import { HASH_GENERATOR_TOOL } from './tool/hashGenerator/index';
|
|
16
|
+
import { PROMPT_LIBRARY_TOOL } from './tool/promptLibrary/index';
|
|
17
|
+
import { COLOR_CONVERTER_TOOL } from './tool/colorConverter/index';
|
|
18
|
+
import { READABILITY_CALCULATOR_TOOL } from './tool/readabilityCalculator/index';
|
|
19
|
+
import { SVG_SANITIZER_TOOL } from './tool/svgSanitizer/index';
|
|
20
|
+
import { UTM_GENERATOR_TOOL } from './tool/utmGenerator/index';
|
|
21
|
+
import { URL_CLEANER_TOOL } from './tool/urlCleaner/index';
|
|
22
|
+
import { INSPECTOR_CERTIFICADOS_SSL_TOOL } from './tool/inspectorCertificadosSsl/index';
|
|
23
|
+
import { GENERADOR_SECURITY_TXT_TOOL } from './tool/generadorSecurityTxt/index';
|
|
24
|
+
import { CALCULADORA_TIEMPO_DATOS_TOOL } from './tool/calculadoraTiempoDatos/index';
|
|
25
|
+
import { CONVERSOR_EXCEL_CSV_HTML_TOOL } from './tool/conversorExcelCsvHtml/index';
|
|
26
|
+
|
|
27
|
+
export const ALL_TOOLS: ToolDefinition[] = [JSON_FORMATTER_TOOL, SVG_TO_CSS_TOOL, ASPECT_RATIO_TOOL, PLACEHOLDER_GENERATOR_TOOL, URL_ENCODER_DECODER_TOOL, DUPLICATE_CSS_REMOVER_TOOL, CSS_TO_INLINE_CONVERTER_TOOL, CSS_SPECIFICITY_CALCULATOR_TOOL, CRON_GENERATOR_TOOL, KEYCODE_TOOL, LLM_COST_CALCULATOR_TOOL, MUSICAL_TYPOGRAPHY_TOOL, MOBILE_MOCKUP_GENERATOR_TOOL, HASH_GENERATOR_TOOL, PROMPT_LIBRARY_TOOL, COLOR_CONVERTER_TOOL, READABILITY_CALCULATOR_TOOL, SVG_SANITIZER_TOOL, UTM_GENERATOR_TOOL, URL_CLEANER_TOOL, INSPECTOR_CERTIFICADOS_SSL_TOOL, GENERADOR_SECURITY_TXT_TOOL, CALCULADORA_TIEMPO_DATOS_TOOL, CONVERSOR_EXCEL_CSV_HTML_TOOL];
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { SEOSection } from '@jjlmoya/utils-shared';
|
|
2
|
+
import type { WithContext, Thing } from 'schema-dts';
|
|
3
|
+
|
|
4
|
+
export type { SEOSection };
|
|
5
|
+
|
|
6
|
+
export type KnownLocale =
|
|
7
|
+
| 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
|
|
8
|
+
| 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
|
|
9
|
+
| 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
|
|
10
|
+
|
|
11
|
+
export interface FAQItem {
|
|
12
|
+
question: string;
|
|
13
|
+
answer: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface BibliographyEntry {
|
|
17
|
+
name: string;
|
|
18
|
+
url: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HowToStep {
|
|
22
|
+
name: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ToolLocaleContent<TUI extends Record<string, string> = Record<string, string>> {
|
|
27
|
+
slug: string;
|
|
28
|
+
title: string;
|
|
29
|
+
description: string;
|
|
30
|
+
ui: TUI;
|
|
31
|
+
seo: SEOSection[];
|
|
32
|
+
faqTitle?: string;
|
|
33
|
+
faq: FAQItem[];
|
|
34
|
+
bibliographyTitle?: string;
|
|
35
|
+
bibliography: BibliographyEntry[];
|
|
36
|
+
howTo: HowToStep[];
|
|
37
|
+
schemas: WithContext<Thing>[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CategoryLocaleContent {
|
|
41
|
+
slug: string;
|
|
42
|
+
title: string;
|
|
43
|
+
description: string;
|
|
44
|
+
seo: SEOSection[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type LocaleLoader<T> = () => Promise<T>;
|
|
48
|
+
|
|
49
|
+
export type LocaleMap<T> = Partial<Record<KnownLocale, LocaleLoader<T>>>;
|
|
50
|
+
|
|
51
|
+
export interface DeveloperToolEntry<TUI extends Record<string, string> = Record<string, string>> {
|
|
52
|
+
id: string;
|
|
53
|
+
icons: {
|
|
54
|
+
bg: string;
|
|
55
|
+
fg: string;
|
|
56
|
+
};
|
|
57
|
+
i18n: LocaleMap<ToolLocaleContent<TUI>>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface DeveloperCategoryEntry {
|
|
61
|
+
icon: string;
|
|
62
|
+
tools: DeveloperToolEntry[];
|
|
63
|
+
i18n: LocaleMap<CategoryLocaleContent>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ToolDefinition {
|
|
67
|
+
entry: DeveloperToolEntry;
|
|
68
|
+
Component: unknown;
|
|
69
|
+
SEOComponent: unknown;
|
|
70
|
+
BibliographyComponent: unknown;
|
|
71
|
+
}
|
|
72
|
+
|