From d61f2b7ab0715c63f6bb534e6e72f89cd04c6994 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 23 Mar 2026 15:06:49 -0300 Subject: [PATCH] feat: update SEO handling by dynamically setting canonical links and exclude auth pages from sitemap --- frontend/index.html | 2 +- frontend/public/sitemap.xml | 14 +------------- frontend/src/utils/useSEO.ts | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 780f896..ed3b343 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -13,7 +13,7 @@ - + diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index e899f2b..6b6229f 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -129,18 +129,6 @@ 0.85 - - https://velxio.dev/login - 2026-03-06 - yearly - 0.3 - - - - https://velxio.dev/register - 2026-03-06 - yearly - 0.3 - + diff --git a/frontend/src/utils/useSEO.ts b/frontend/src/utils/useSEO.ts index 8492e2f..88ffea1 100644 --- a/frontend/src/utils/useSEO.ts +++ b/frontend/src/utils/useSEO.ts @@ -47,6 +47,17 @@ export function useSEO({ title, description, url, ogImage, jsonLd }: SEOMeta) { const origTwDesc = get(twDescEl); const origCanonical = canonicalEl?.getAttribute('href') ?? ''; + // If no exists yet, create one so each SPA route + // gets its own canonical (avoids all routes appearing to point back to /). + let createdCanonical = false; + let activeCanonical: HTMLLinkElement | null = canonicalEl as HTMLLinkElement | null; + if (!activeCanonical) { + activeCanonical = document.createElement('link') as HTMLLinkElement; + activeCanonical.rel = 'canonical'; + document.head.appendChild(activeCanonical); + createdCanonical = true; + } + // Apply document.title = title; set(descEl, description); @@ -56,7 +67,7 @@ export function useSEO({ title, description, url, ogImage, jsonLd }: SEOMeta) { if (ogImage) set(ogImgEl, ogImage); set(twTitleEl, title); set(twDescEl, description); - canonicalEl?.setAttribute('href', url); + activeCanonical.setAttribute('href', url); // Inject JSON-LD once (module-level constants don't change) if (jsonLd && !scriptRef.current) { @@ -77,7 +88,11 @@ export function useSEO({ title, description, url, ogImage, jsonLd }: SEOMeta) { if (ogImage) set(ogImgEl, origOgImg); set(twTitleEl, origTwTitle); set(twDescEl, origTwDesc); - canonicalEl?.setAttribute('href', origCanonical); + if (createdCanonical && activeCanonical && document.head.contains(activeCanonical)) { + document.head.removeChild(activeCanonical); + } else { + activeCanonical?.setAttribute('href', origCanonical); + } if (scriptRef.current) { document.head.removeChild(scriptRef.current); scriptRef.current = null;