Todos los proyectos
Live · clienteProyecto 06
Sitio corporativoClienteSSG

PAX Elevators

Un mensaje central, "repuesto fabricado en 3 semanas en vez de 3 meses", convertido en un sitio estático que carga en 3G, se encuentra en Google y termina en un WhatsApp con contexto para el dueño.

Nuxt 3 SSGTypeScriptTailwindNitroResendLeafletVercel

Cuando el repuesto importado tarda 3 meses, ellos lo fabrican en 3 semanas. La web tenía un solo trabajo: que esa frase llegara a quien tiene un ascensor parado.

Sitio corporativo para una empresa venezolana de mantenimiento, modernización y fabricación local de repuestos de ascensores. Estático, rápido en redes malas, con catálogo, diagnóstico por termografía y un cotizador que termina en WhatsApp.

Repuesto OEM importado~3 meses
Polea, tapa o bocina fabricada en su taller~3 semanas
Cifras que el cliente publica en su web y en sus volantes; el sitio las convierte en el mensaje central.
11trabajos reales documentados con fotos, 8 con página propia
232 KBpesa el HTML de la portada, servido desde la CDN
4piezas impresas salidas del mismo HTML que la web
01 · Cómo funciona

De un ascensor parado a un WhatsApp con contexto

Pulsa los pasos o deja que avance. Cada paso ilumina la pieza de la que habla.

Búsqueda
"ascensor parado Caracas"
Página
HTML prerenderizado
Cotizador
3 preguntas
Función
/api/cotizacion
Dueño
correo + WhatsApp
Paso 1 de 5 · avanza solo
Alguien busca con un problema, no con una marca
Un administrador con un ascensor parado no busca "PAX Elevators": busca el problema. Cada servicio, cada diagnóstico y cada modelo del catálogo tiene su propia URL prerenderizada, con título, descripción y datos estructurados de LocalBusiness para que el buscador la entienda sin ejecutar nada.

El cotizador, tal como funciona en el sitio. Cambia las respuestas.

1 · Paradas
2 · Edad del equipo
3 · Urgencia
Perfil recomendado
Reparación
falla actual: diagnóstico primero, repuesto fabricado si el OEM tarda
WhatsApp prellenado
"Hola PAX, tengo un ascensor de 5 – 9 paradas con más de 20 años. Necesito: reparación."
Ningún precio en pantalla. Réplica de la lógica del sitio con las mismas opciones; el texto del mensaje es de ejemplo.
02 · Arquitectura

Todo estático menos una función

No hay CMS, ni base de datos, ni servidor propio. El contenido vive en un fichero tipado, el build lo convierte en páginas, y una sola función recibe formularios.

Topología · Vercel
DNS
paxelevators.com
dominio del cliente en GoDaddy
apex primario
A y CNAME a Vercel · MX intactos en GoDaddy
Borde
CDN
una veintena de páginas estáticas
x-vercel-cache: HIT
Función Nitro
/api/cotizacion
la única pieza dinámica
HTML prerenderizado · cache-control por ruta
Build
Nuxt 3 SSG
TypeScript · Tailwind · @nuxtjs/seo
sitemap · robots · schema.org
data/content.ts
trabajos, servicios, modelos, sectores
1 fichero, sin CMS
nuxt generate · crawlLinks descubre las rutas
Medios
Imágenes
30 ficheros · 2 MB
30 días
Vídeos
5 clips · 17,6 MB · póster
sin autoplay
Catálogos PDF
2 ficheros · 51 MB
inline · 7 días
Salida
Resend
correo al dueño con el pedido
fetch, sin SDK
WhatsApp
wa.me con el mensaje prellenado
sin backend
data/content.ts · un fichero tipado
TRABAJOS8obras reales con fotos, marca, sector y servicio
SERVICIOS4una página por servicio, con los trabajos que lo prueban
DIAGNOSTICOS3termografía, aislamiento, instrumentación
MODELOS11catálogo por familia, con página propia y CTA al contacto
SECTORES3residencial, comercial, empresarial
TRUST_BRANDS6marcas que atienden
Las rutas dinámicas (/servicios/[slug], /catalogo/[slug]) se descubren en el build siguiendo los enlaces y se prerenderizan una a una.
Cobertura por radio
El cliente no publica dirección. El mapa dibuja un círculo de 350 km alrededor de cada sede con Leaflet, cargado solo en esa página.
Datos estructurados
LocalBusiness con dos localidades, teléfono y área servida. Open Graph y Twitter con imagen estática.
Del web al papel
Volante, tríptico, mini y premium se renderizan con Chromium desde HTML con las mismas fuentes y paleta.
03 · Un ejemplo de punta a punta

Un martes, un Otis parado y una administradora

Un caso inventado, marcado como ejemplo, para ver qué produce cada pieza antes de hablar de los retos.

1
08:10 · móvil, 3G
Busca el problema
Rosa administra un edificio de 9 pisos con un ascensor parado desde el lunes. Busca "reparación ascensor Otis Caracas" y entra a la página del servicio de reparación. El HTML llega entero; no espera a que cargue ninguna aplicación.
2
08:12
Ve trabajos parecidos al suyo
La página enlaza los trabajos reales de ese servicio: un motor operador de puerta Otis en una torre residencial, con fotos. No es una promesa: es una obra con fecha y marca.
3
08:14 · cotizador
Tres toques
5 a 9 paradas, entre 10 y 20 años, reparación urgente. El cotizador propone Reparación y arma el mensaje. Rosa pulsa WhatsApp: el chat se abre con el texto escrito, ella solo añade la dirección.
4
08:15 · oficina
Al dueño le llega contexto, no un "hola"
Sabe cuántas paradas, qué edad y qué urgencia antes de responder. Si Rosa hubiera usado el formulario, el correo llega con los mismos campos en una tabla, y la fecha en hora de Caracas.
5
semana siguiente
Si el repuesto no existe, se fabrica
El diagnóstico apunta a una polea. Importarla son meses; el taller la fabrica en semanas. Es la frase del hero, y por eso está en el hero.
04 · Los retos

Cinco veces en que la solución obvia estaba mal

Cada reto sigue el mismo patrón: lo que cualquiera haría primero, por qué no sirve, lo que se hizo y el número que lo demuestra. El detalle técnico queda plegado.

01

Contenido sin CMS

Lo obvio
WordPress, o un CMS headless con panel para que el cliente edite.
Por qué falla
El cliente no tiene equipo técnico ni quiere otra cuenta con otra factura. La web cambia unas pocas veces al año y cada cambio pasa por quien la construyó. Un CMS aquí es una superficie de ataque, actualizaciones de plugins y un login que nadie va a usar.
data/content.ts · un fichero tipado
TRABAJOS8obras reales con fotos, marca, sector y servicio
SERVICIOS4una página por servicio, con los trabajos que lo prueban
DIAGNOSTICOS3termografía, aislamiento, instrumentación
MODELOS11catálogo por familia, con página propia y CTA al contacto
SECTORES3residencial, comercial, empresarial
TRUST_BRANDS6marcas que atienden
Las rutas dinámicas (/servicios/[slug], /catalogo/[slug]) se descubren en el build siguiendo los enlaces y se prerenderizan una a una.
Lo que se hizo
Todo el contenido vive en un fichero TypeScript con tipos: trabajos, servicios, diagnósticos, modelos, sectores, proceso, marcas. Las páginas dinámicas leen de ahí y el build las prerenderiza siguiendo los enlaces. Añadir un modelo es añadir un objeto; el tipo avisa si falta un campo.
0bases de datos, paneles y cuentas de terceros para el contenido. Un modelo nuevo es un objeto y un build.
Ver detalle técnico

Los ocho trabajos con página propia se cruzan con los servicios: getTrabajosByService hace que cada página de servicio muestre las obras que lo prueban, sin duplicar contenido. Los sectores y las marcas son listas del mismo fichero.

El precio es que el cliente no edita solo. Para un negocio que cambia su web dos veces al año está bien; para uno que publica novedades semanales, no.
02

Un cotizador que no inventa precios

Lo obvio
Una calculadora: metes paradas y años, sale un precio estimado.
Por qué falla
No había rangos reales validados con el cliente. Un precio inventado en la web es el peor primer contacto posible: o espanta o compromete a un número que nadie dio.
1 · Paradas
2 · Edad del equipo
3 · Urgencia
Perfil recomendado
Reparación
falla actual: diagnóstico primero, repuesto fabricado si el OEM tarda
WhatsApp prellenado
"Hola PAX, tengo un ascensor de 5 – 9 paradas con más de 20 años. Necesito: reparación."
Ningún precio en pantalla. Réplica de la lógica del sitio con las mismas opciones; el texto del mensaje es de ejemplo.
Lo que se hizo
Tres preguntas que cualquiera puede responder sin saber de ascensores: paradas, edad, urgencia. La salida no es un número, es un perfil de servicio y un mensaje ya escrito para WhatsApp o para el formulario, con el modelo del catálogo si venía de ahí.
3 → 4tres preguntas, cuatro perfiles de servicio. Cero precios en pantalla.
Ver detalle técnico

Las opciones llevan una pista debajo ("Residencial bajo · dúplex / villa") para que la persona se ubique sin vocabulario técnico. La recomendación mapea a un valor de servicio que el formulario ya entiende, así el dueño recibe el mismo campo venga de donde venga.

03

El formulario que antes era un PHP

Lo obvio
Un send-email.php en el hosting compartido, que es lo que ese hosting sabe correr.
Por qué falla
La credencial del proveedor de correo vivía dentro del script, y al mover el sitio a un hosting estático ese fichero se sirve como texto plano. Además no había validación: cualquier bot podía llenar la bandeja del dueño.
Lo que se hizo
Una función Nitro en server/api/cotizacion.post.ts: recorta y limpia cada campo, exige nombre, teléfono y ciudad, descarta bots con un campo honeypot que solo un bot rellena, y llama a Resend con fetch. La credencial es una variable de entorno; sin ella, el endpoint responde 503 con un texto útil.
503"Envío no disponible. Usa WhatsApp por ahora." Un fallo que dice qué hacer, en vez de un formulario que parece que envió.
Ver detalle técnico

El correo al dueño es una tabla con los campos, el mensaje libre en un bloque aparte y la fecha en America/Caracas. Todo se escapa antes de entrar al HTML. La copia del PHP quedó en legacy/ sin credencial, por trazabilidad.

04

Cambiar de hosting sin tumbar el correo del cliente

Lo obvio
Apuntar los nameservers del dominio a Vercel y listo.
Por qué falla
El correo del cliente vive en GoDaddy y hay un segundo MX para envíos transaccionales. Cambiar nameservers se lleva los MX por delante. Y GoDaddy tenía un forwarding activo que bloqueaba editar los registros A: no dejaba guardar hasta quitarlo.
Forwardingredirección de GoDaddyquitado
A @76.76.21.21cambiado
CNAME wwwcname.vercel-dns.comcambiado
MXsecureserver.net · correo del clienteintacto
MX sendAmazon SES · envíos transaccionalesintacto
Lo que se hizo
Solo dos registros: A del apex y CNAME de www, en la cuenta del cliente. Los MX no se tocaron. Y el apex quedó como dominio primario, porque el canonical y el sitemap del sitio ya eran sin www: Vercel venía con la redirección al revés.
2 / 0dos registros cambiados, cero MX tocados. El hosting Apache anterior siguió vivo hasta confirmar que nada dependía de él.
Ver detalle técnico

La configuración de caché y redirecciones que estaba en netlify.toml pasó a routeRules de Nuxt, así vive con el código y no con el proveedor. Nitro detecta el preset de Vercel solo: páginas prerenderizadas más una función para el formulario.

05

70 MB de medios en una web para 3G

Lo obvio
Subir los catálogos, los vídeos y las fotos y dejar que el navegador se apañe.
Por qué falla
Los dos catálogos en PDF pesan 51 MB y los vídeos de operación 17,6 MB. Si eso entra en el flujo de la portada, el sitio no carga en el teléfono de quien lo necesita. Y el mapa de cobertura arrastra una librería entera que solo una página usa.
/_nuxt/** /_fonts/**1 año · immutablenombres con hash: nunca cambian
/images/**30 días30 imágenes · 2 MB
/catalogos/**7 días · inline2 PDF · 51 MB, se abren en el navegador
/videosbajo demanda5 clips · 17,6 MB, con póster, sin autoplay
Lo que se hizo
Reglas de caché por ruta en el propio Nuxt: un año e inmutable para todo lo que lleva hash, 30 días para imágenes, 7 días para catálogos con content-disposition: inline para que se abran en el navegador. Los vídeos llevan póster y no arrancan solos. Leaflet se importa dinámicamente solo en /cobertura.
2 MBde imágenes para todo el sitio, optimizadas a 1200 y 1920 px. Los 68 MB restantes solo viajan si alguien los pide.
Ver detalle técnico

Las fuentes (Space Grotesk e Inter) se descargan en el build y se sirven desde el propio dominio con caché de un año: sin petición a Google Fonts, sin salto de layout al cargar.

Los catálogos siguen siendo PDF de fábrica. El inventario para convertirlos en páginas por familia existe, y once modelos ya tienen su página; el resto espera a que el cliente marque qué familias quiere mostrar.
"La web existe para producir un mensaje de WhatsApp con contexto."
Todo lo demás, catálogo, termografía, vídeos, mapa, trabajos con fotos, es lo que convence antes de tocar el botón. Cada decisión se midió contra eso: si no acerca a ese mensaje, sobra.
05 · Decisiones

Un solo filtro: ¿esto le añade al cliente una factura o una tarea?

Si la respuesta era sí, se buscó otra forma. El cliente paga el dominio; todo lo demás corre en planes gratuitos.

WHY
¿Por qué Nuxt SSG y no WordPress?
Porque el sitio tiene que encontrarse y cargar en redes malas, y el cliente no va a administrar un panel. HTML prerenderizado, cero plugins que actualizar, cero base de datos que respaldar. El mismo patrón que Venekambio, aplicado a un negocio físico.
Profundizar

El módulo @nuxtjs/seo genera sitemap, robots y datos estructurados desde la configuración. La imagen Open Graph generada en build quedó desactivada por una incompatibilidad del módulo; se sirve una imagen estática en su lugar, que es más predecible para WhatsApp.

WHY
¿Por qué el mensaje central es la fabricación y no los años de experiencia?
Porque es lo que nadie más ofrece. En Venezuela importar un repuesto OEM es lento y caro; fabricar poleas, tapas y bocinas de bronce en taller propio resuelve el problema del cliente, no el ego de la empresa. Los años van en un párrafo; la fabricación va en el titular, en el volante y en el tríptico.
WHY
¿Por qué cobertura por radio y no una dirección?
El cliente atiende todo el país desde dos sedes y no publica dirección física. El mapa dibuja un círculo de 350 km alrededor de cada sede con Leaflet, que se carga solo en esa página. Los datos estructurados declaran dos localidades y área servida: Venezuela.
WHY
Las piezas impresas salen del mismo HTML
Volante, tríptico, mini y premium se maquetaron en HTML con las fuentes y la paleta del sitio y se renderizan con Chromium: PDF con sangrado de 3 mm para imprenta, PDF sin sangrado y PNG a 288 dpi para WhatsApp. Un solo sistema de diseño para web y papel.
Profundizar
Volante
media carta · doble cara
"3 meses vs 3 semanas" + QR
Tríptico
carta horizontal · plegado en C
servicios, garantía, trabajos, cobertura
Mini
cuarto de carta · 4 por hoja
"¿Ascensor parado? Lo resolvemos."
Premium
media carta · 4 variantes
el hero de la web, en papel

El tríptico se pliega en C en tercios iguales; los PNG de previsualización muestran las líneas de plegado y los PDF no. El mini tiene una versión de cuatro por hoja carta con líneas de corte para imprimir en la oficina.

La única pieza dinámica, resumida.

// server/api/cotizacion.post.ts
if (clean(body.website)) return { ok: true } // honeypot: el bot cree que envió
if (!nombre || !telefono || !ciudad) throw createError({ statusCode: 400 })
if (!resendApiKey) throw createError({ statusCode: 503, statusMessage: 'Usa WhatsApp por ahora.' })
06 · Qué haría distinto

Cuatro decisiones que hoy tomaría al revés

Hice
Arrancar en el hosting Apache del cliente con un PHP para el formulario
Hoy haría
Función serverless con la credencial en variable de entorno desde el primer día. El PHP obligó a una migración y a rotar una clave.
Hice
Meter los catálogos de fábrica como PDF de 51 MB
Hoy haría
Páginas por familia desde el inicio, con el PDF como descarga secundaria. Once modelos ya tienen página; el resto espera al cliente.
Hice
Mapa de cobertura como placeholder durante meses
Hoy haría
Leaflet con carga diferida desde la primera versión. Era una tarde de trabajo y la página quedó a medias más tiempo del razonable.
Hice
Entregas por zip (v1, v2, tar para Netlify)
Hoy haría
Un repositorio y despliegues desde él. Las versiones en carpetas no dejan ver qué cambió entre una entrega y otra.
07 · Si te llevas tres cosas

Recap

1
Estático de verdad: el contenido es un fichero tipado, el build lo convierte en páginas y la CDN las sirve. Una sola función para el formulario.
2
El sitio no vende una empresa, vende una solución: repuesto fabricado en semanas en vez de meses. Ese mensaje está en el hero, en el cotizador y en cuatro piezas impresas del mismo HTML.
3
La migración de hosting tocó dos registros DNS y ningún MX, y el formulario pasó de un PHP con la clave dentro a una función con honeypot y un 503 que dice qué hacer.
Enlaces