Starter kit para agencias
en tres idiomas desde el día uno.
Astro 7 + i18n nativo ES/EN/FR + WordPress headless opcional con Polylang. hreflang automático, sitemap multilocale, GA4 con Consent Mode v2 y 4×100 en Lighthouse.
Montar un sitio multiidioma con Astro desde cero implica configurar las rutas por locale, generar el hreflang manualmente, gestionar el sitemap multilocale y asegurarse de que el language switcher no rompe el SSG. Este starter resuelve todo eso antes de que escribas una sola línea de código de negocio.
POR QUÉ EXISTE
El problema con el multiidioma en Astro.
Astro 7 tiene i18n nativo, pero configurarlo bien desde cero lleva
más tiempo del que parece. Las rutas por locale, el hreflang en cada
página, el sitemap multilocale con
@astrojs/sitemap, el language switcher que no rompe el SSG, los JSON de contenido
por idioma — cada pieza por separado es manejable, pero montarlas
todas coherentemente desde cero puede llevarte un día entero antes
de escribir una línea de contenido real.
Además, el multiidioma añade complejidad al SEO: hay que asegurarse de que Google entiende qué versión de cada página corresponde a qué idioma y región. Un hreflang mal implementado puede hacer que Google indexe la versión incorrecta o que las páginas compitan entre sí por las mismas keywords en distintos idiomas.
Este starter resuelve todo eso antes del primer commit. Clonarlo y tener un sitio multiidioma funcionando con hreflang correcto, sitemap multilocale y language switcher tarda menos de cinco minutos.
# Estructura de rutas generada automáticamente
darumaproducciones.es/
└── / → Español (default)
└── /en/ → English
└── /fr/ → Français
# hreflang inyectado en cada página
<link rel="alternate"
hreflang="es"
href="https://tudominio.com/" />
<link rel="alternate"
hreflang="en"
href="https://tudominio.com/en/" />
<link rel="alternate"
hreflang="fr"
href="https://tudominio.com/fr/" />
Qué incluye
3 idiomas nativos
ES / EN / FR sin plugins ni librerías externas. i18n nativo de Astro 7 — rutas generadas automáticamente en el build.
hreflang automático
Inyectado en el <head> de cada página en el build. Sin configuración manual, sin errores de implementación.
Sitemap multilocale
Generado automáticamente con @astrojs/sitemap. Una URL por idioma por página, correctamente referenciada.
Language switcher
Integrado en la nav. Cambia de idioma sin recarga de página. Marca la página activa con aria-current.
WordPress + Polylang ready
Activa WP_MODE=true y conecta tu WordPress con Polylang. Mock data en JSON para desarrollo sin CMS.
GA4 + Consent Mode v2
Consentimiento denegado por defecto. GA4 solo rastrea si el usuario acepta. RGPD compliant desde el día uno.
Banner cookies RGPD
Traducido en ES/EN/FR. Guarda la decisión 1 año en localStorage. No interfiere con LCP ni CLS.
Schema.org MarketingAgency
Con availableLanguage en los 3 idiomas. Validado para Rich Results en Google.
WCAG AA
Contraste validado, aria-label, aria-hidden, aria-current y prefers-reduced-motion respetado.
Secciones incluidas
Nav.astro
Fija, language switcher integrado
Hero.astro
Tipografía gigante, outline text, animación scroll
Ticker.astro
Banda de servicios infinita en amarillo neón
Metrics.astro
Contadores animados on-scroll, card destacada
Services.astro
Lista con hover, tags, flecha animada
Manifesto.astro
Texto tipográfico de impacto
Contact.astro
Email directo, fondo amarillo neón
CookieBanner.astro
Banner RGPD, GA4 Consent Mode v2, 3 idiomas
Sistema de diseño
Paleta
#000000
Fondo negro puro
#F5FF40
Acento amarillo neón
#ffffff
Texto principal
#0a0a0a
Surface
/* Cambia el acento en un solo lugar */
--color-accent: #F5FF40;
/* BaseLayout.astro → :root */
Tipografía y efectos
- Display Bebas Neue · local · 0 peticiones externas
- Cuerpo DM Sans · local · 0 peticiones externas
- Framework CSS vanilla · sin Tailwind · variables en :root
- Cursor Custom con inercia suave
- Contadores Animados on-scroll con IntersectionObserver
- Ticker Infinito configurable en Ticker.astro
- Reveal On-scroll en todos los elementos clave
.woff2 de Google Fonts, conviértelos en cloudconvert.com y colócalos en public/fonts/.
Quick start
# 1. Clonar e instalar
git clone https://github.com/DhiviPanda/astro-agency-i18n-starter
cd astro-agency-i18n-starter
npm install
# 2. Variables de entorno
cp .env.example .env
# → Añade tu GA4: PUBLIC_GA_ID=G-TU_ID
# 3. Desarrollo (datos JSON por defecto, sin WordPress)
npm run dev → localhost:4321
# 4. Activar WordPress + Polylang (opcional)
# En src/config.ts:
WP_MODE = true
WP_API_URL = 'https://cms.tudominio.com/wp-json/wp/v2'
# 5. Build de producción
npm run build && npm run preview
Requisitos: Node.js 18+. Funciona con datos JSON estáticos sin
WordPress. Para activar la detección automática de idioma por IP, cambia
a output: 'server' y descomenta el middleware en src/middleware/index.ts.
MODO WORDPRESS
Conectar WordPress + Polylang.
Por defecto el starter usa datos JSON estáticos. Para conectarlo a WordPress con Polylang, sigue estos pasos:
- 01. Instala Polylang en WordPress (versión gratuita funciona)
- 02. Configura 3 idiomas: es, en, fr
- 03. Añade el filtro REST API en functions.php para exponer las traducciones
- 04. Crea los CPTs de servicios con CPT UI si los necesitas
- 05. Activa WP_MODE=true y añade la URL de tu API en .env
- 06. npm run build — el starter fetcha el contenido en el build
/* functions.php — exponer traducciones en REST */
add_filter(
'rest_prepare_post',
function($response, $post) {
$response->data['translations'] =
pll_get_post_translations($post->ID);
return $response;
}, 10, 2
);
ANTES DE PUBLICAR
Checklist de personalización.
🔴 Imprescindible
- · Nav.astro → cambia PULSO por el nombre de tu agencia
- · BaseLayout.astro → actualiza --color-accent con tu color
- · astro.config.mjs → actualiza site con tu dominio real
- · public/fonts/ → descarga y coloca los 4 .woff2
- · src/data/mock/*.json → textos reales en los 3 idiomas
- · .env → PUBLIC_GA_ID con tu ID de GA4
🟡 SEO y redes
- · BaseLayout.astro → schema: nombre, email, teléfono, dirección
- · BaseLayout.astro → sameAs: LinkedIn, Instagram, etc.
- · public/og-default.svg → sustituir por PNG 1200×630px real
- · public/robots.txt → actualiza la URL del sitemap
- · public/llms.txt → actualiza con tu dominio y redes reales
- · GSC → añade el sitemap: tudominio.com/sitemap-index.xml
🟢 Opcional
- · WP_MODE=true → conectar WordPress + Polylang
- · middleware/index.ts → detección automática de idioma por IP
- · Añadir idiomas adicionales (PT, DE, IT...)
- · OG images dinámicas con Satori (requiere SSR)
- · Plausible como alternativa a GA4 sin cookies
- · Cabeceras de seguridad en .htaccess o netlify.toml
Para quién es
Para developers que necesitan un punto de partida real para agencias de marketing con presencia multilingüe. El i18n nativo de Astro 7 elimina la complejidad habitual de los proyectos multiidioma: sin librerías externas, sin configuración manual de rutas, con hreflang correcto desde el primer build.
También es el tercer starter de la serie Culebra Lab. Si necesitas una base para clínicas, mira el Medical Starter. Si necesitas la base headless más simple, el Starter Kit original.
Qué falta todavía
- · Demo en vivo (próximamente)
- · Versión PT (portugués)
- · Páginas internas: /[lang]/servicios/[slug]
- · OG images dinámicas con Satori (requiere SSR)
- · Blog multiidioma con WordPress headless
Todo esto sí está resuelto en los proyectos que entrego como servicio — sitemap dinámico, SEO técnico, schema personalizado, blog multiidioma y optimización de imágenes incluidos.
PREGUNTAS FRECUENTES
¿Necesito WordPress para usar este starter? +
No. Por defecto funciona con datos JSON estáticos en src/data/mock/. WordPress + Polylang es opcional y se activa con WP_MODE=true en el archivo de configuración.
¿Cómo funciona el i18n nativo de Astro 7 en este starter? +
Astro 7 genera rutas por idioma automáticamente: / para español, /en/ para inglés y /fr/ para francés. El hreflang se inyecta en el <head> de cada página en el build sin configuración manual. El language switcher cambia de idioma sin recarga de página.
¿Qué es Consent Mode v2 y por qué está integrado? +
Consent Mode v2 es el protocolo de Google que permite a GA4 respetar la decisión del usuario antes de rastrear. Sin él, GA4 puede infringir el RGPD. Este starter lo implementa correctamente: el consentimiento está denegado por defecto y GA4 solo activa el rastreo si el usuario acepta explícitamente desde el banner de cookies.
¿Cómo añado un cuarto idioma al starter? +
Tres pasos: añade el locale a LOCALES en src/i18n/index.ts, crea src/data/mock/[lang].json con el mismo shape que es.json, y añade el idioma al objeto locales en astro.config.mjs. Astro genera las rutas automáticamente en el siguiente build.
¿Por qué no usa Tailwind este starter? +
Decisión deliberada. El sistema de diseño está construido con CSS vanilla y variables en BaseLayout.astro. Esto elimina la dependencia del compilador de Tailwind, reduce el peso del build y hace que cambiar el color de marca sea tan sencillo como modificar --color-accent en un único lugar.
¿Cómo conecto WordPress con Polylang? +
Instala Polylang en WordPress (la versión gratuita funciona), configura los 3 idiomas (es, en, fr), añade el filtro REST API en functions.php para exponer las traducciones, y activa WP_MODE=true con la URL de tu API en .env. El starter ya tiene la lógica de fetching preparada para leer los campos de Polylang.
¿Puedo desplegarlo en hosting compartido como IONOS? +
Sí. El output por defecto es estático (npm run build genera /dist). Sube el contenido de /dist a tu public_html por FTP. El .htaccess incluido activa compresión y caché automáticamente. Para activar la detección automática de idioma por IP necesitarás cambiar a output: server y un adaptador SSR.
¿Quieres que te lo monte yo?
Si prefieres un proyecto completo y verificado — sitemap multilocale, SEO técnico, hreflang, schema y optimización de imágenes incluidos — lo construyo a medida.