π¬π§ English | πͺπΈ EspaΓ±ol
Astro-based programmatic SEO website that generated 15,500+ unique pages from an Airtable ERP, reaching 2.26M impressions and 2,000 monthly clicks in Google Spain.
Local repair shops have thousands of potential service pages (every brand x model x repair type), but creating them manually is impossible. Existing solutions either generate thin, duplicate content or require expensive CMS platforms.
A fully automated pipeline that reads device data from an Airtable ERP, uses DataForSEO to decide which pages deserve to exist based on real search volume, generates optimized images with Sharp, and builds 15,500+ unique Astro pages with structured data, breadcrumbs, and internal linking.
Key Features:
- DataForSEO-powered indexability engine β not every possible page gets indexed. A decision layer queries real search volume data to determine which combinations (model x repair x city) justify a page. Pages below threshold get
noindex. - 9 Node.js scripts that generate images, sitemaps, and metadata from Airtable
- Parametric Astro routes β one layout generates thousands of unique pages
- EXIF injection for Google Images ranking (geo-coordinates, descriptions)
- Crawl budget optimization β selective
noindex, filtered sitemaps (4,084 URLs from thousands possible), 700+ redirect rules for Squarespace migration, and strategic internal linking
The pipeline doesn't blindly generate pages for every possible combination. Before a page is built, DataForSEO's keyword data API is queried to check real search volume for that specific {brand} + {model} + {repair} + {city} combination. Pages below the volume threshold are either not generated or marked noindex, concentrating crawl budget on pages that actually drive traffic.
This is visible in Airtable's indexable field and in src/lib/airtable.ts where the indexability logic lives.
With 15,500+ possible pages, controlling what Google crawls is critical:
- Selective noindex β low-volume pages exist for UX completeness but don't waste crawl budget
- Filtered sitemaps β only 4,084 URLs submitted out of thousands possible (
public/sitemap-0.xml) - 700+ redirects β bridge rules in
vercel.jsonfor the Squarespace-to-Astro migration, preserving link equity - JSON-LD structured data β LocalBusiness, BreadcrumbList, Organization on every page
Airtable (ERP) β DataForSEO β Node.js Scripts β Astro SSG β Vercel/Cloudflare
300+ models search volume image pipeline 15,500+ CDN + Edge
50+ brands indexability EXIF injection pages
reviews decisions sitemaps
Every device model, brand, and repair type stored in Airtable flows through a decision layer (DataForSEO search volume data), then through a pipeline of Node.js scripts that generate optimized images with SEO metadata. Finally, Astro builds parametric pages using dynamic routes like:
/reparar-movil/samsung/galaxy-s24/β model page/reparar-movil/samsung/sevillaβ brand + city/reparar-movil/cambiar-pantalla/sevillaβ repair type + city/reparar-apple-watch/serie-4/40mmβ Apple product family + model
# 1. Install dependencies
npm install
# 2. Configure environment
cp .env.example .env
# Add your Airtable API key and base ID# Run image pipeline (requires Airtable data)
node scripts/generarImagenesReparacionesModelos.mjs
node scripts/ExifLocal.mjs
node scripts/sitemaps.mjs
# Start dev server
npm run dev
# Build for production
npm run build| Variable | Description | Required |
|---|---|---|
AIRTABLE_API_KEY |
Airtable personal access token | Yes |
AIRTABLE_BASE_ID |
Airtable base containing device data | Yes |
The core of the pSEO approach β 9 Node.js scripts that transform Airtable data into optimized web assets:
| Script | What it does |
|---|---|
generarImagenesReparacionesModelos.mjs |
Generates device-specific images with model overlays |
generarImagenesReparacionesMarcas.mjs |
Creates brand-level repair guide images and thumbnails |
generarImagenesReparacionesTipos.cjs |
Converts device type templates to optimized WebP |
generarImagenesBackgroundPasosReparacion.mjs |
Generates repair step illustrations with branding |
generarImagenesReseΓ±as.mjs |
Creates review/testimonial profile images |
CasosExito.mjs |
Downloads and optimizes before/after case study images |
ExifLocal.mjs |
Injects EXIF metadata (description, GPS) for Google Images SEO |
scriptImagenesGoogle.mjs |
Fetches and processes external device images |
sitemaps.mjs |
Generates XML sitemaps organized by device type and category |
The ~15,000 generated images are not included in this repo β they are pipeline output, not source code.
βββ src/
β βββ pages/ # Astro dynamic routes (parametric SEO pages)
β β βββ reparar-[paramTipo]/ # /reparar-movil, /reparar-tablet, /reparar-smartwatch
β β βββ [paramMarcaApple]/ # Apple-specific product family routes
β β βββ cambiar-[paramRep]/ # Repair type pages
β β βββ blog/ # Blog with markdown content
β βββ layouts/ # Page templates per hierarchy level
β β βββ TipoLayout.astro # Device type (mobile/tablet/watch)
β β βββ MarcaLayout.astro # Brand (Samsung, Apple, Xiaomi...)
β β βββ ModeloLayout.astro # Specific model
β β βββ ReparacionLayout.astro# Repair type (screen, battery...)
β βββ components/ # 60+ Astro components
β β βββ metadatos/ # JSON-LD structured data
β β βββ FAQs.astro # Auto-generated FAQ sections
β β βββ Buscador.astro # Client-side device search
β βββ lib/ # Airtable client, data caching, indexability logic
β βββ content/blog/ # 16 markdown blog posts
βββ scripts/ # Image generation pipeline
β βββ plantillas/ # Base templates for image compositing
β βββ src/ # Script-specific type definitions
βββ public/
β βββ marcas/ # Brand logos (50+)
β βββ scripts/ # Client-side JS (search, modals, reviews)
β βββ fonts/ # Graphik typeface
βββ vercel.json # 700+ redirect rules + headers
| Metric | Value |
|---|---|
| Pages generated | 15,500+ |
| Impressions (total) | 2,260,000+ |
| Google-indexed keywords | 1,800+ |
| Monthly organic clicks (peak) | 2,000 |
| Sitemap URLs (curated) | 4,084 of thousands possible |
| Google Search Console growth | 0 β 2K clicks in 12 months |
| Business outcome | Successful exit (Sep 2025) |
This project is shared as a portfolio piece and educational reference. The code structure and automation patterns are freely available for learning. Brand assets and business-specific content remain property of their respective owners.
Web de SEO programatico construida con Astro que genero 15.500+ paginas unicas desde un ERP en Airtable, alcanzando 2,26M impresiones y 2.000 clics mensuales en Google EspaΓ±a.
Las tiendas de reparacion locales tienen miles de paginas de servicio potenciales (cada marca x modelo x tipo de reparacion), pero crearlas manualmente es imposible. Las soluciones existentes generan contenido duplicado o requieren plataformas CMS caras.
Un pipeline completamente automatizado que lee datos de dispositivos desde un ERP en Airtable, usa DataForSEO para decidir que paginas merecen existir basandose en volumen de busqueda real, genera imagenes optimizadas con Sharp, y construye 15.500+ paginas unicas con Astro, incluyendo structured data, breadcrumbs y enlazado interno.
Funcionalidades:
- Motor de indexabilidad con DataForSEO β no todas las paginas posibles se indexan. Una capa de decision consulta datos reales de volumen de busqueda para determinar que combinaciones (modelo x reparacion x ciudad) justifican una pagina. Las que no alcanzan el umbral reciben
noindex. - 9 scripts Node.js que generan imagenes, sitemaps y metadatos desde Airtable
- Rutas parametricas en Astro β un layout genera miles de paginas unicas
- Inyeccion EXIF para posicionar en Google Images (coordenadas, descripciones)
- Optimizacion de crawl budget β
noindexselectivo, sitemaps filtrados (4.084 URLs de miles posibles), 700+ reglas de redireccion para la migracion desde Squarespace, y enlazado interno estrategico
El pipeline no genera paginas a ciegas para cada combinacion posible. Antes de construir una pagina, se consulta la API de keyword data de DataForSEO para verificar el volumen de busqueda real de esa combinacion {marca} + {modelo} + {reparacion} + {ciudad}. Las paginas por debajo del umbral no se generan o se marcan como noindex, concentrando el crawl budget en las paginas que realmente generan trafico.
Esto es visible en el campo indexable de Airtable y en src/lib/airtable.ts donde vive la logica de indexabilidad.
Con 15.500+ paginas posibles, controlar lo que Google rastrea es critico:
- Noindex selectivo β las paginas de bajo volumen existen para completitud de UX pero no desperdician crawl budget
- Sitemaps filtrados β solo 4.084 URLs enviadas de miles posibles (
public/sitemap-0.xml) - 700+ redirecciones β reglas puente en
vercel.jsonpara la migracion de Squarespace a Astro, preservando link equity - JSON-LD structured data β LocalBusiness, BreadcrumbList, Organization en cada pagina
Airtable (ERP) β DataForSEO β Scripts Node.js β Astro SSG β Vercel/Cloudflare
300+ modelos volumen de pipeline de 15.500+ CDN + Edge
50+ marcas busqueda imagenes paginas
reseΓ±as indexabilidad EXIF + sitemaps
Cada modelo de dispositivo, marca y tipo de reparacion almacenado en Airtable pasa por una capa de decision (datos de volumen de busqueda de DataForSEO), luego por un pipeline de scripts Node.js que generan imagenes optimizadas con metadatos SEO. Finalmente, Astro construye paginas parametricas con rutas dinamicas como:
/reparar-movil/samsung/galaxy-s24/β pagina de modelo/reparar-movil/samsung/sevillaβ marca + ciudad/reparar-movil/cambiar-pantalla/sevillaβ tipo de reparacion + ciudad/reparar-apple-watch/serie-4/40mmβ familia de producto Apple + modelo
# 1. Instalar dependencias
npm install
# 2. Configurar entorno
cp .env.example .env
# AΓ±ade tu API key de Airtable y base ID# Ejecutar pipeline de imagenes (requiere datos en Airtable)
node scripts/generarImagenesReparacionesModelos.mjs
node scripts/ExifLocal.mjs
node scripts/sitemaps.mjs
# Servidor de desarrollo
npm run dev
# Build de produccion
npm run build| Variable | Descripcion | Requerida |
|---|---|---|
AIRTABLE_API_KEY |
Token de acceso personal de Airtable | Si |
AIRTABLE_BASE_ID |
Base de Airtable con datos de dispositivos | Si |
| Script | Que hace |
|---|---|
generarImagenesReparacionesModelos.mjs |
Genera imagenes por modelo de dispositivo con overlays |
generarImagenesReparacionesMarcas.mjs |
Crea imagenes de guia de reparacion por marca |
generarImagenesReparacionesTipos.cjs |
Convierte plantillas por tipo de dispositivo a WebP |
generarImagenesBackgroundPasosReparacion.mjs |
Genera ilustraciones de pasos de reparacion |
generarImagenesReseΓ±as.mjs |
Crea imagenes de perfil para reseΓ±as desde Airtable |
CasosExito.mjs |
Descarga y optimiza imagenes antes/despues |
ExifLocal.mjs |
Inyecta metadatos EXIF para SEO en Google Images |
scriptImagenesGoogle.mjs |
Obtiene y procesa imagenes externas de dispositivos |
sitemaps.mjs |
Genera sitemaps XML por tipo de dispositivo y categoria |
βββ src/
β βββ pages/ # Rutas dinamicas Astro (paginas SEO parametricas)
β β βββ reparar-[paramTipo]/ # /reparar-movil, /reparar-tablet, /reparar-smartwatch
β β βββ [paramMarcaApple]/ # Rutas de familias de productos Apple
β β βββ cambiar-[paramRep]/ # Paginas por tipo de reparacion
β β βββ blog/ # Blog con contenido markdown
β βββ layouts/ # Templates de pagina por nivel de jerarquia
β β βββ TipoLayout.astro # Tipo de dispositivo (movil/tablet/watch)
β β βββ MarcaLayout.astro # Marca (Samsung, Apple, Xiaomi...)
β β βββ ModeloLayout.astro # Modelo especifico
β β βββ ReparacionLayout.astro# Tipo de reparacion (pantalla, bateria...)
β βββ components/ # 60+ componentes Astro
β β βββ metadatos/ # JSON-LD structured data
β β βββ FAQs.astro # Secciones FAQ auto-generadas
β β βββ Buscador.astro # Buscador de dispositivos del lado cliente
β βββ lib/ # Cliente Airtable, cache, logica de indexabilidad
β βββ content/blog/ # 16 posts de blog en markdown
βββ scripts/ # Pipeline de generacion de imagenes
β βββ plantillas/ # Templates base para composicion de imagenes
β βββ src/ # Tipos TypeScript de los scripts
βββ public/
β βββ marcas/ # Logos de marcas (50+)
β βββ scripts/ # JS del lado cliente (buscador, modales, reseΓ±as)
β βββ fonts/ # Tipografia Graphik
βββ vercel.json # 700+ reglas de redireccion + headers
| Metrica | Valor |
|---|---|
| Paginas generadas | 15.500+ |
| Impresiones (total) | 2.260.000+ |
| Keywords indexadas en Google | 1.800+ |
| Clics organicos mensuales (pico) | 2.000 |
| URLs en sitemap (curadas) | 4.084 de miles posibles |
| Crecimiento en GSC | 0 β 2K clics en 12 meses |
| Resultado de negocio | Venta exitosa (sep 2025) |
Este proyecto se comparte como pieza de portfolio y referencia educativa. La estructura del codigo y los patrones de automatizacion estan disponibles para aprendizaje. Los activos de marca y contenido especifico del negocio pertenecen a sus respectivos propietarios.


