diff --git a/scripts/htaccess.conf b/scripts/htaccess.conf index c82c2e4..b70416e 100644 --- a/scripts/htaccess.conf +++ b/scripts/htaccess.conf @@ -12,9 +12,7 @@ RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] - # Quitar .html de la URL (limpieza opcional) - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d + # Quitar .html de la URL — evita duplicados index.html vs / RewriteCond %{REQUEST_URI} ^(.+)\.html$ [NC] RewriteRule ^(.+)\.html$ /$1 [R=301,L] diff --git a/src/components/LangToggle.astro b/src/components/LangToggle.astro index 1cc14d6..c569244 100644 --- a/src/components/LangToggle.astro +++ b/src/components/LangToggle.astro @@ -1,5 +1,6 @@ --- -import { LANGUAGES, DEFAULT_LANG, type Lang } from '@/i18n/utils'; +import { LANGUAGES, type Lang } from '@/i18n/utils'; +import { getHreflangUrl } from '@/i18n/hreflang-map'; interface Props { lang: Lang; @@ -7,19 +8,17 @@ interface Props { const { lang } = Astro.props; const path = Astro.url.pathname; -function otherLangUrl(): string { - const cleanPath = path.replace(/^\/(en|es)/, '') || '/'; - if (lang === DEFAULT_LANG) { - return `/en${cleanPath === '/' ? '' : cleanPath}`; - } - return cleanPath; -} +const otherLang = lang === 'en' ? 'es' : 'en'; +const fullUrl = getHreflangUrl(path, lang, otherLang); +const href = fullUrl + ? fullUrl.replace('https://hostingdelsur.net', '') + : otherLang === 'en' ? '/en/' : '/'; const other = LANGUAGES.find((l) => l.code !== lang); const isEn = lang === 'en'; --- = { + '/nosotros/': '/en/about/', + '/contacto/': '/en/contact/', + '/planes/': '/en/plans/', + '/instructivos/': '/en/tutorials/', + '/legal/privacidad/': '/en/legal/privacy/', + '/legal/terminos/': '/en/legal/terms/', + '/preguntas/': null, +}; + +const enToEsMap: Record = {}; +for (const [esPath, enPath] of Object.entries(esToEnOverrides)) { + if (enPath) enToEsMap[enPath] = esPath; +} + +const SITE_URL = 'https://hostingdelsur.net'; + +export function getHreflangUrl( + pathname: string, + currentLang: Lang, + targetLang: Lang +): string | null { + if (currentLang === targetLang) { + return `${SITE_URL}${pathname}`; + } + + if (currentLang === 'es' && targetLang === 'en') { + const override = esToEnOverrides[pathname]; + if (override === null) return null; + if (override) return `${SITE_URL}${override}`; + return `${SITE_URL}/en${pathname}`; + } + + if (currentLang === 'en' && targetLang === 'es') { + const override = enToEsMap[pathname]; + if (override) return `${SITE_URL}${override}`; + const esPath = pathname.replace(/^\/en/, '') || '/'; + return `${SITE_URL}${esPath}`; + } + + return null; +} diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 43d4131..ddee6d9 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -1,5 +1,6 @@ --- import { getLangFromUrl, useTranslations, type Lang } from '@/i18n/utils'; +import { getHreflangUrl } from '@/i18n/hreflang-map'; interface Props { title: string; @@ -15,6 +16,8 @@ const currentLang = lang ?? getLangFromUrl(Astro.url); const t = useTranslations(currentLang); const siteUrl = Astro.site?.toString().replace(/\/$/, '') ?? 'https://hostingdelsur.net'; const canonicalUrl = canonical ? `${siteUrl}${canonical}` : `${siteUrl}${Astro.url.pathname}`; +const esHreflang = getHreflangUrl(Astro.url.pathname, currentLang, 'es'); +const enHreflang = getHreflangUrl(Astro.url.pathname, currentLang, 'en'); import '@/styles/global.css'; import Navbar from '@/components/Navbar.astro'; @@ -95,8 +98,8 @@ const localBusinessJsonLd = { - - + {esHreflang && } + {enHreflang && }