Tech Stack - Lolita Pank
Headless Architecture: Next.js + WordPress + Vercel
Overview
This solution implements a headless CMS architecture that separates the backend (WordPress) from the frontend (Next.js), offering significant advantages over the traditional WordPress approach:
- Greater security: Frontend and backend are physically separated
- Better performance: Next.js with SSG/ISR generates ultra-fast pages
- Scalability: Vercel automatically handles high traffic
- Better UX: Instant SPA-like navigation
- Superior SEO: Static pre-rendering with optimized metadata
- Atomic deploy: Instant rollback if something fails
Frontend (Next.js 14 + App Router)
- Framework: Next.js 14 with App Router
- Language: TypeScript
- Hosting: Vercel (automatic deployment from Git)
- Data Fetching: GraphQL via WPGraphQL
- Type generation: GraphQL Code Generator
- Cache: Next.js ISR (Incremental Static Regeneration)
- Images: Next.js Image Optimization
- Styles: Tailwind CSS (recommended) or CSS Modules
Repository: GitHub/GitLab (version control + CI/CD)
Backend (WordPress Headless)
- CMS: WordPress.org (self-hosted)
- API: WPGraphQL + WPGraphQL SEO
- E-commerce: WooCommerce with WPGraphQL for WooCommerce
- Authentication: WPGraphQL JWT Authentication
- Custom Fields: Advanced Custom Fields PRO + WPGraphQL for ACF
- Payments: MercadoPago (custom integration via REST API)
- WordPress Hosting: Hostinger Business WordPress or similar
- Security: Wordfence Security + SSL + 2FA
Infrastructure and DevOps
- Frontend Hosting: Vercel (global CDN, edge functions)
- Backend Hosting: Hostinger Business WordPress
- Database: MySQL (included in WordPress hosting)
- Version control: Git (GitHub/GitLab)
- CI/CD: Vercel Git Integration (auto-deploy on push)
- DNS: Vercel DNS or Cloudflare
- SSL: Automatic on both (Let’s Encrypt)
┌─────────────────────────────────────────────────────────────┐
│ USUARIO │
└───────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ VERCEL CDN (Edge Network) │
│ • Next.js App (SSG/ISR) │
│ • Static pages cached globally │
│ • Imágenes optimizadas │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌───────────────────────────┐ ┌──────────────────────────┐
│ WordPress GraphQL API │ │ MercadoPago REST API │
│ (Hostinger) │ │ (Pagos) │
│ • WPGraphQL │ │ • Procesamiento pagos │
│ • WooCommerce │ │ • Webhooks │
│ • ACF │ └──────────────────────────┘
│ • JWT Auth │
│ • MySQL Database │
└───────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ SISTEMA DE BACKUPS (Triple Capa) │
│ 1. Hostinger Auto Backup (semanal) │
│ 2. UpdraftPlus → Google Drive (diario DB, semanal full) │
│ 3. Manual mensual (WordPress DB + Next.js repo Git tags) │
└───────────────────────────────────────────────────────────┘
Editorial Content (Posts, Events, Artists, Galleries)
- Editing in WordPress (CMS)
- Editor adds/edits content in WordPress admin
- Custom Post Types: Posts, Events, Artists, Galleries
- ACF Flexible Content for custom blocks
- Update Webhook
- WordPress trigger webhook in
save_post - Call
/api/revalidatein Vercel
- WordPress trigger webhook in
- Incremental Revalidation
- Next.js revalidates only affected routes
- New content available in ~2-5 seconds
- Does not require a complete rebuild
- Serve the User
- User receives pre-rendered static page
- Load time <500ms from edge CDN
- Instant SPA navigation
E-commerce (Courses/Workshops)1. Management in WooCommerce
- Admin crea/edita productos (cursos) en WordPress
- Precios, descripción, cupos, fechas en ACF
- Catalog in Next.js
- Next.js fetcha productos vía WPGraphQL
- Genera páginas estáticas
/cursos/[slug] - ISR revalida cada 60 segundos (configurable)
- Purchase Flow
- Usuario navega catálogo en Next.js (fast)
- Click “Inscribirse” → Formulario Next.js
- Next.js API route procesa orden:
- Crea orden en WooCommerce vía REST API
- Genera preference en MercadoPago
- Redirige a checkout MercadoPago
- Post-Payment
- MercadoPago webhook notifies Next.js
/api/webhooks/mercadopago - Next.js updates order status in WooCommerce
- Send confirmation email via SendGrid/Resend
- User receives access to the dashboard
- MercadoPago webhook notifies Next.js
Next.js Project Structure
lolita-pank-next/
├── src/
│ ├── app/ # App Router (Next.js 14)
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Homepage
│ │ ├── [[...slug]]/ # Catch-all para páginas dinámicas
│ │ │ └── page.tsx # Template resolver
│ │ ├── cursos/ # Catálogo de cursos
│ │ │ ├── page.tsx # Listado
│ │ │ └── [slug]/
│ │ │ └── page.tsx # Detalle curso
│ │ ├── archivo/ # Archivo histórico
│ │ │ ├── page.tsx # Página principal archivo
│ │ │ ├── eventos/
│ │ │ │ ├── page.tsx
│ │ │ │ └── [slug]/page.tsx
│ │ │ ├── artistas/
│ │ │ │ ├── page.tsx
│ │ │ │ └── [slug]/page.tsx
│ │ │ └── galerias/
│ │ │ ├── page.tsx
│ │ │ └── [slug]/page.tsx
│ │ ├── blog/ # Editorial
│ │ │ ├── page.tsx
│ │ │ └── [slug]/page.tsx
│ │ ├── dashboard/ # Usuario inscrito
│ │ │ └── page.tsx
│ │ ├── api/ # API Routes
│ │ │ ├── preview/route.ts # Draft preview
│ │ │ ├── revalidate/route.ts # Webhook revalidation
│ │ │ ├── checkout/route.ts # Crear orden WC + MP
│ │ │ └── webhooks/
│ │ │ └── mercadopago/route.ts
│ │ ├── robots.ts # robots.txt dinámico
│ │ ├── sitemap.ts # sitemap.xml dinámico
│ │ ├── not-found.tsx # 404 page
│ │ └── middleware.ts # Redirects handling
│ │
│ ├── components/
│ │ ├── templates/ # Page templates
│ │ │ ├── PageTemplate.tsx
│ │ │ ├── PostTemplate.tsx
│ │ │ ├── EventoTemplate.tsx
│ │ │ ├── ArtistaTemplate.tsx
│ │ │ └── GaleriaTemplate.tsx
│ │ ├── blocks/ # ACF Flexible Content blocks
│ │ │ ├── HeroBlock.tsx
│ │ │ ├── TextBlock.tsx
│ │ │ ├── ImageGalleryBlock.tsx
│ │ │ └── VideoBlock.tsx
│ │ ├── navigation/
│ │ │ ├── Header.tsx
│ │ │ └── Footer.tsx
│ │ ├── curso/
│ │ │ ├── CursoCard.tsx
│ │ │ └── CursoCheckoutForm.tsx
│ │ └── common/
│ │ ├── SEO.tsx
│ │ └── Image.tsx
│ │
│ ├── lib/
│ │ ├── wordpress.ts # GraphQL client
│ │ ├── woocommerce.ts # WC REST API client
│ │ ├── mercadopago.ts # MercadoPago SDK
│ │ └── auth.ts # JWT auth helpers
│ │
│ ├── queries/ # GraphQL queries
│ │ ├── pages.ts
│ │ ├── posts.ts
│ │ ├── eventos.ts
│ │ ├── artistas.ts
│ │ ├── galerias.ts
│ │ ├── cursos.ts
│ │ └── navigation.ts
│ │
│ ├── gql/ # Auto-generated types
│ │ ├── schema.gql
│ │ └── graphql.ts # Generated TypeScript types
│ │
│ └── utils/
│ ├── seo.ts
│ ├── date.ts
│ └── format.ts
│
├── public/
│ └── assets/
│
├── .env.local # Environment variables
├── .env.production
├── next.config.js
├── codegen.ts # GraphQL codegen config
├── apollo.config.js # VS Code GraphQL extension
├── tsconfig.json
├── tailwind.config.js
└── package.json
WordPress Headless Configuration
Required Plugins
✓ WPGraphQL (core)
✓ WPGraphQL for Advanced Custom Fields
✓ WPGraphQL for SEO (Yoast integration)
✓ WPGraphQL JWT Authentication
✓ WPGraphQL for WooCommerce
✓ WooCommerce
✓ Yoast SEO
✓ Advanced Custom Fields PRO
✓ Redirection (con API habilitada)
✓ Wordfence Security
✓ UpdraftPlus (backups)
✓ Classic Editor (opcional)
wp-config.php
// Headless configuration
define('HEADLESS_SECRET', 'INSERT_RANDOM_SECRET_KEY');
define('HEADLESS_URL', '<https://lolitapank.com>'); // URL Next.js production
define('HEADLESS_DEV_URL', '<http://localhost:3000>'); // Local dev
// JWT Authentication
define('GRAPHQL_JWT_AUTH_SECRET_KEY', 'INSERT_RANDOM_JWT_KEY');
define('GRAPHQL_JWT_AUTH_CORS_ENABLE', true);
// WPGraphQL settings
define('GRAPHQL_DEBUG', false); // true solo en dev
functions.php (Custom Theme)
See the PHP code provided in the cms-wordpress example documentation. Includes:
- ✓ Menu registration
- ✓ Rewriting of preview links to the frontend
- ✓ Vercel revalidation webhook
- ✓ REST endpoints for sitemap
Custom Post Types (Historical Archive)
Events (custom post type: ‘event’)
ACF fields:
fecha_evento(Date Picker)ubicacion(Text)descripcion(Wysiwyg)galeria_fotos(Gallery)videos_youtube(Repeater → URL)instagram_embeds(Repeater → oEmbed)artistas_participantes(Post Object → relationship with Artists)
GraphQL Query:
query GetEvento($slug: ID!) {
evento(id: $slug, idType: SLUG) {
title
eventoFields {
fechaEvento
ubicacion
descripcion
galeriaFotos {
sourceUrl
altText
}
videosYoutube {
url
}
instagramEmbeds {
embed
}
artistasParticipantes {
... on Artista {
title
slug
}
}
}
}
}Artists (custom post type: ‘artist’)
ACF fields:
biografia(Wysiwyg)foto_perfil(Image)portfolio(Gallery)redes_sociales(Group → Instagram, Facebook, Twitter)obra_destacada(Gallery)
Galleries (custom post type: ‘gallery’)
ACF fields:
fecha_exposicion(Date Picker)descripcion(Wysiwyg)imagenes(Gallery)curador(Text)
Headless E-commerce System
Complete Purchase Flow
1. Create Product in WooCommerce
Producto WooCommerce: "Taller de Serigrafía"
- Precio: $50 USD
- SKU: CURSO-SER-001
- Stock: 15 (cupos)
- ACF Custom Fields:
- fecha_inicio: 2025-12-01
- duracion: "8 semanas"
- horario: "Sábados 10am-2pm"
- instructor: "Ana García"
- nivel: "Principiante"
2. Next.js Fetcha Courses
// src/queries/cursos.ts
export const GET_CURSOS = gql`
query GetCursos {
products(first: 100, where: { status: "publish" }) {
nodes {
id
databaseId
name
slug
price
regularPrice
stockQuantity
image {
sourceUrl
}
cursoFields {
fechaInicio
duracion
horario
instructor
nivel
}
}
}
}
`3. Course Page (/cursos/[slug])
// src/app/cursos/[slug]/page.tsx
import { getCursoBySlug } from "@/queries/cursos"
import CursoCheckoutForm from "@/components/curso/CursoCheckoutForm"
export async function generateStaticParams() {
const cursos = await getAllCursos()
return cursos.map((curso) => ({ slug: curso.slug }))
}
export default async function CursoPage({ params }) {
const curso = await getCursoBySlug(params.slug)
return (
<>
<h1>{curso.name}</h1>
<p>Precio: ${curso.price}</p>
<p>Cupos disponibles: {curso.stockQuantity}</p>
{/* Detalles del curso... */}
<CursoCheckoutForm cursoId={curso.databaseId} />
</>
)
}
// ISR: Revalidar cada 60 segundos
export const revalidate = 604. Checkout Form (Next.js)
// src/components/curso/CursoCheckoutForm.tsx
"use client"
export default function CursoCheckoutForm({ cursoId }) {
const handleSubmit = async (e) => {
e.preventDefault()
const formData = new FormData(e.target)
// Crear orden en WooCommerce + Preference en MercadoPago
const response = await fetch("/api/checkout", {
method: "POST",
body: JSON.stringify({
cursoId,
nombre: formData.get("nombre"),
email: formData.get("email"),
telefono: formData.get("telefono"),
}),
})
const { checkoutUrl } = await response.json()
// Redirigir a MercadoPago
window.location.href = checkoutUrl
}
return (
<form onSubmit={handleSubmit}>
<input name="nombre" required />
<input name="email" type="email" required />
<input name="telefono" required />
<button type="submit">Inscribirse y Pagar</button>
</form>
)
}5. API Route: Create Order + MercadoPago Preference
// src/app/api/checkout/route.ts
import { NextRequest, NextResponse } from "next/server"
import { createWooCommerceOrder } from "@/lib/woocommerce"
import { createMercadoPagoPreference } from "@/lib/mercadopago"
export async function POST(req: NextRequest) {
const { cursoId, nombre, email, telefono } = await req.json()
// 1. Crear orden en WooCommerce
const wcOrder = await createWooCommerceOrder({
product_id: cursoId,
customer: {
first_name: nombre,
email,
phone: telefono,
},
status: "pending", // Pending payment
})
// 2. Crear preference en MercadoPago
const mpPreference = await createMercadoPagoPreference({
items: [
{
title: wcOrder.line_items[0].name,
quantity: 1,
unit_price: parseFloat(wcOrder.total),
},
],
back_urls: {
success: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/success?order=${wcOrder.id}`,
failure: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/failure`,
pending: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/pending`,
},
notification_url: `${process.env.NEXT_PUBLIC_BASE_URL}/api/webhooks/mercadopago`,
external_reference: wcOrder.id.toString(), // Link WC order to MP payment
})
return NextResponse.json({
checkoutUrl: mpPreference.init_point,
orderId: wcOrder.id,
})
}6. MercadoPago Webhook → Update Order
// src/app/api/webhooks/mercadopago/route.ts
import { NextRequest, NextResponse } from "next/server"
import { getMercadoPagoPayment } from "@/lib/mercadopago"
import { updateWooCommerceOrder } from "@/lib/woocommerce"
import { sendConfirmationEmail } from "@/lib/email"
export async function POST(req: NextRequest) {
const body = await req.json()
if (body.type === "payment") {
const paymentId = body.data.id
const payment = await getMercadoPagoPayment(paymentId)
if (payment.status === "approved") {
const wcOrderId = payment.external_reference
// Actualizar orden en WooCommerce
await updateWooCommerceOrder(wcOrderId, {
status: "completed",
payment_method: "mercadopago",
transaction_id: paymentId,
})
// Enviar email de confirmación
await sendConfirmationEmail({
orderId: wcOrderId,
email: payment.payer.email,
})
}
}
return NextResponse.json({ received: true })
}Backup System (Headless Architecture)
Specific Challenge of the Headless Approach
In a headless architecture, we have TWO systems that need backup:
- WordPress Backend (CMS + Database)
- Next.js Frontend (Source code)
The advantage is that if one fails, the other keeps working. But we need a backup strategy for both.
Layer 1: WordPress Backend Backups (Triple System)
A. Automatic Hosting (Hostinger)
- Frequency: Weekly
- Retention: 30 days
- Content: Complete Files + Database
- Pros: Automatic, included
- Cons: Only 4 snapshots, slow restore
B. UpdraftPlus → Google Drive
-
Frequency:
- Database: Daily (00:00 AM)
- Complete files: Weekly (Sunday 02:00 AM)
-
Retention: 30 copies
-
Content:
/wp-content/uploads/(images, media)- Complete database (posts, users, products, orders)
/wp-content/themes/(theme custom)/wp-content/plugins/(configs)
-
Settings:
UpdraftPlus Settings: ✓ Files backup schedule: Weekly (Sunday 2am) ✓ Database backup schedule: Daily (12am) ✓ Remote Storage: Google Drive ✓ Retain: 30 backups ✓ Email notifications: admin@lolitapank.com ```### C. Monthly Manual (Total Control) -
Frequency: First Monday of each month
-
Method:
- Login to WordPress admin
- UpdraftPlus → “Backup Now”
- Download all files locally
- Store on external hard drive + personal Google Drive
- Labeling:
lolitapank-backup-2025-01-01.zip
-
Checklist:
- Database (.sql.gz)
- Uploads folder (.zip)
- Plugins (.zip)
- Themes (.zip)
- WordPress core files
Verification script (run monthly):
# Verificar que backups existen en Google Drive
curl -X GET "<https://www.googleapis.com/drive/v3/files?q=name> contains 'backup'" \\
-H "Authorization: Bearer YOUR_TOKEN"
Layer 2: Next.js Frontend Backups (Git + Vercel)
A. Git Version Control (GitHub/GitLab)
Main Advantage: Next.js code lives in Git, so it can NEVER be lost.
# Repositorio
<https://github.com/lolitapank/website>
# Branching strategy
main → Producción (Vercel auto-deploy)
staging → Testing (Vercel preview)
dev → Desarrollo activo
# Tags para releases importantes
v1.0.0-launch (Lanzamiento inicial)
v1.1.0-archivo (Sistema archivo implementado)
v1.2.0-ecommerce (Integración MercadoPago)
Backup process:
- All changes are committed to Git
- Git is hosted on GitHub (redundant servers)
- Developer maintain local clone
- Client can clone repo at any time
Recovery: If Vercel disappears, clone repo + deploy to Netlify/Cloudflare Pages in 10 minutes.
B. Vercel Deployment History
- Retention: All historical deploys (unlimited in Pro plan)
- Rollback: 1-click rollback to any previous deploy
- Snapshots: Each deploy is an immutable snapshot
- Preview URLs: Each commit generates permanent preview URLs
Ejemplo:
Commit abc123 → Deploy exitoso → URL: lolitapank-abc123.vercel.app
Commit def456 → Deploy con bug → Rollback a abc123 en 5 segundos
C. Monthly Manual (Paranoia Extra)
Frequency: First Monday of the month (along with WordPress backup)
#!/bin/bash
# backup-frontend.sh
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="$HOME/lolitapank-backups/$DATE"
# 1. Clone fresh del repo
git clone <https://github.com/lolitapank/website> $BACKUP_DIR/repo
# 2. Export de variables de entorno (desde Vercel dashboard)
# Manual: Vercel Dashboard → Settings → Environment Variables → Export
# 3. Backup de .env.local (encrypted)
gpg -c $BACKUP_DIR/.env.local
# 4. Crear tarball
tar -czf lolitapank-frontend-$DATE.tar.gz $BACKUP_DIR
# 5. Upload a Google Drive (via rclone)
rclone copy lolitapank-frontend-$DATE.tar.gz gdrive:/backups/
echo "✓ Frontend backup completed: $DATE"
Layer 3: Assets and Media (WordPress uploads)
Challenge: The historical archive images are in WordPress /wp-content/uploads/.
Solution: Next.js uses next/image with remotePatterns pointing to WordPress.
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "cms.lolitapank.com", // WordPress backend
pathname: "/wp-content/uploads/**",
},
],
},
}Image backup:
- Included in UpdraftPlus backups (Layer 1B)
- Monthly manual download complete
/wp-content/uploads/ - Optional: Automatic sync to AWS S3/Cloudinary for extra redundancy
Future migration to CDN (optional, Phase 2):
WordPress Uploads → Cloudinary/ImageKit
- Auto-upload on WordPress media upload
- Next.js Image apunta a CDN
- Ventaja: Imágenes sobreviven incluso si WordPress muere
Monitoring and Alert System
A. Uptime Monitoring (UptimeRobot)
Configured monitors:
- Frontend Next.js (
https://lolitapank.com)- Check every 5 minutes
- Alert if down >2 minutes
- Notify: Email + SMS
- WordPress GraphQL API (
https://cms.lolitapank.com/graphql)- Check every 10 minutes
- Alert if response time >5s or down
- Notify: Email
- Keyword monitoring:
- Homepage must contain “Lolita Pank”
- GraphQL should respond
{"data":...}
B. Backup Health Monitoring
Auto script (daily cron):
#!/bin/bash
# check-backups.sh (ejecutar diario vía cron)
# 1. Check que UpdraftPlus corrió hoy
LAST_BACKUP=$(wp updraftplus last-backup-time)
HOURS_AGO=$(( ($(date +%s) - $LAST_BACKUP) / 3600 ))
if [ $HOURS_AGO -gt 26 ]; then
# Backup tiene más de 26 horas, alertar
curl -X POST <https://api.sendgrid.com/v3/mail/send> \\
-H "Authorization: Bearer $SENDGRID_KEY" \\
-d '{
"to": "admin@lolitapank.com",
"subject": "⚠️ ALERTA: Backup de WordPress no corrió",
"text": "El backup diario de UpdraftPlus no se ejecutó. Verificar."
}'
fi
# 2. Check que archivos existen en Google Drive
# (requiere rclone configurado)
BACKUP_COUNT=$(rclone ls gdrive:/backups/ | wc -l)
if [ $BACKUP_COUNT -lt 5 ]; then
# Menos de 5 backups en Drive, alertar
echo "⚠️ Solo $BACKUP_COUNT backups en Google Drive"
fi
Run via cron:
# crontab -e
0 8 * * * /home/lolitapank/scripts/check-backups.sh
C. Vercel Deployment Monitoring
Vercel automatically notifies via email/Slack when:
- ✓ Successful deployment
- ✗ Deploy failed (build error)
- ⚠️ Deploy with warnings
Slack integration (optional):
Vercel → Slack integration
Canal: #website-deploys
Mensaje ejemplo:
✅ Deployed lolitapank.com
Commit: abc123 "Fix: corregir galería eventos"
Time: 45s
URL: <https://lolitapank.com>
Disaster Recovery Procedure
Scenario 1: Dead WordPress (hosting down, hacked, corrupt)
Impact: ⚠️ Medium- Frontend Next.js still working (Vercel standalone)
- Existing content is still visible (cached pages)
- You CANNOT edit new content
- New purchases cannot be processed
Recovery:
Tiempo: 2-4 horas
1. Contratar nuevo hosting WordPress (30 min)
→ Hostinger, SiteGround, o similar
2. Instalar WordPress limpio (10 min)
→ Versión misma que backup
3. Restaurar desde UpdraftPlus (45-90 min)
→ Plugins instalados
→ Restore database
→ Restore files
4. Actualizar DNS de GraphQL API (15 min)
→ cms.lolitapank.com → nuevo IP
→ TTL de 5 min para propagación rápida
5. Test de funcionalidad (30 min)
→ GraphQL queries funcionan
→ Login WordPress OK
→ WooCommerce operativo
6. Revalidar cache Next.js (5 min)
→ Trigger /api/revalidate?tag=wordpress
→ Todo el contenido refresca desde nuevo WordPress
✅ Sitio 100% operativo
Data Loss Prevention:
- Last daily backup (maximum 24 hours of lost content)
- If there is critical content of the day, recover from manual backup
Scenario 2: Vercel Dead (company closed, account canceled, catastrophic bug)
Impact: 🔴 High
- Frontend Next.js down
- WordPress backend still working
- Content exists but cannot be viewed
Recovery:
Tiempo: 15-30 minutos
1. Clone repositorio Git (2 min)
git clone <https://github.com/lolitapank/website>
cd website
2. Install dependencies (3 min)
npm install
3. Deploy a alternativa (10-15 min)
Opciones:
a) Netlify: netlify deploy --prod
b) Cloudflare Pages: pages:deploy
c) AWS Amplify: amplify push
d) Hosting propio: npm run build && npm start
4. Actualizar DNS (5 min)
lolitapank.com A record → nuevo proveedor
5. Configurar variables de entorno (5 min)
- NEXT_PUBLIC_WORDPRESS_API_URL
- HEADLESS_SECRET
- Etc. (copiar desde backup .env)
✅ Sitio 100% operativo en nuevo host
Advantage of Next.js approach: The code is in Git, full portability between providers.
Scenario 3: BOTH Dead (Total Catastrophe)
Impact: 🔴🔴 Critical
- Entire site down
- Requires complete reconstruction
Recovery:
Tiempo: 3-5 horas
1. Recuperar WordPress (Escenario 1)
→ 2-4 horas
2. Recuperar Next.js (Escenario 2)
→ 15-30 minutos
3. Reconectar ambos sistemas
→ Update environment variables
→ Test GraphQL connectivity
4. Verificación completa
→ Test e-commerce flow
→ Test preview/draft
→ Test revalidation webhooks
✅ Sitio 100% restaurado
Probability: <0.001% Requires that they fail simultaneously:
- Vercel (global CDN, 99.99% uptime)
- Git remote (GitHub, redundant servers)
- WordPress hosting
- Google Drive (99.9% uptime)
- Local backup on hard drive
Scenario 4: Loss of Access to Credentials
Impact: 🟡 Medium
- Can’t access services but everything works
Recovery:
1. WordPress admin password:
→ Reset via email
→ O via phpMyAdmin (hosting panel)
2. Vercel account:
→ Reset password via email
→ 2FA recovery codes (guardados en backup)
3. GitHub access:
→ Reset password
→ SSH keys en backup
4. Hosting panel:
→ Contact support
→ ID verification
5. MercadoPago API keys:
→ Regenerar en dashboard MP
→ Update en Vercel env vars
Prevention:
- “Master Credentials” document (encrypted) in Google Drive
- 2FA recovery codes printed and physically saved
- Secondary recovery email configured
Monthly Maintenance Checklist
Client executes (15 minutes/month):
□ Verificar que sitio está online (lolitapank.com)
□ Verificar que WordPress admin accesible (cms.lolitapank.com/wp-admin)
□ UpdraftPlus: Verificar último backup (debe ser <24 horas)
□ UpdraftPlus: "Backup Now" + Descargar local
□ Guardar backup en disco duro externo
□ Ejecutar script check-backups.sh
□ Review UptimeRobot status (verificar sin alertas)
□ Update WordPress core si disponible
□ Update plugins si disponible (test en staging primero)
□ Git: Create tag para release mensual (v1.X.0)
□ Revisar Google Drive: Confirmar >10 backups existen
□ Test compra de prueba en MercadoPago (sandbox)
□ Verificar emails de confirmación funcionan
□ Revisar Vercel dashboard (sin deploys fallidos)Developer runs (optional, 30 min/month):
□ Review Vercel analytics (performance)
□ Review WordPress slow queries
□ Optimizar imágenes si necesario
□ Update dependencies Next.js (npm outdated)
□ Security scan (npm audit)
□ Check lighthouse score (>90)
□ Review error logs (Vercel + WordPress)
□ Test preview/draft mode
□ Review backup storage costs (Google Drive)Comparison: Traditional WordPress vs Headless Next.js| Appearance | Traditional WordPress | Headless Next.js |
| ------------------------ | ------------------------------------------------------ | ----------------------------------------------------------------- | | Security | ⚠️ WordPress exposed to the internet, vulnerable to attacks | ✅ WordPress hidden, only GraphQL API exposed | | Performance | 🐢 ~2-4s initial load, each page generates server-side | 🚀 <500ms from CDN, pre-rendered pages | | Scalability | ⚠️ Hosting upgrade required for high traffic | ✅ Vercel scales automatically, without limit | | Backups | ✅ Backups included in the traditional example | ✅ Double system: WordPress + Git | | Hosting cost | ~$60-80/año (hosting único) | ~$80-100/year (WordPress host + Vercel free/Pro) | | Developer Experience | ⚠️ PHP, limited type safety | ✅ TypeScript, modern React, hot reload | | SEO | ✅ Yoast SEO integrated | ✅ Next.js metadata API, equal or better | | Mobile Performance | 🐢 Lighthouse score ~60-70 | 🚀 Lighthouse score ~95-100 | | Vendor Lock-in | ⚠️ Difficult to migrate from WordPress | ✅ Portable frontend (Git), portable backend (WordPress standard) | | Time to Interactive | ~4-6s | ~0.5-1s | | Admin UX | ✅ WordPress family admin | ✅ Same WordPress admin (does not change) | | E-commerce | ✅ Native WooCommerce with themes | ⚠️ Requires custom integration (more dev work) | | Learning Curve | ✅ Easy for non-developers | ⚠️ Requires developer with React knowledge |
Verdict:
- Traditional WordPress: Best for teams without developers, minimal budget, quick setup
- Headless Next.js: Best for extreme performance, scalability, modern UX, competitive SEO
To Lolita Pank:
- If you have a developer on a team or a budget to hire → Headless Next.js (better long-term)
- Yes zero budget and total self-management → Traditional WordPress (simpler)
Comparative Costs
Traditional WordPress Stack
Hostinger Business WordPress: $60-80/año
Dominio: $12/año
Plugins premium: $0 (todos gratuitos en propuesta)
TOTAL: ~$72-92/año
Headless Next.js Stack
WordPress Hosting (Hostinger Business): $60-80/año
Vercel Hobby (para proyectos pequeños): $0/año
Vercel Pro (para producción, recomendado): $240/año ($20/mes)
Dominio: $12/año
GitHub (repos privados): $0/año
Google Drive (15GB free): $0/año
TOTAL Hobby: ~$72-92/año (igual que tradicional)
TOTAL Pro: ~$312-332/año
Initial development:
- Traditional WordPress: ~75-95 hours (depending on proposal)
- Headless Next.js: ~95-120 hours (+20-25 hours due to integration complexity)
- Difference: ~$260 MXN/hora × 20-25 horas = ~$5,200-6,500 MXN extra
Recommendation:
-
Phase 1 (launch): Traditional WordPress (lower cost, faster)
-
Phase 2 (6-12 months later): Migrate to Headless if they scale and need performanceOr start Headless if:
-
They expect >1000 visits/day in the first year
-
Budget allows $300-350 USD/year hosting
-
They have a React developer as a team
-
Performance and SEO are priority #1
Environment Variables (.env.local)
# WordPress GraphQL API
NEXT_PUBLIC_WORDPRESS_API_URL=https://cms.lolitapank.com/graphql
NEXT_PUBLIC_WORDPRESS_API_HOSTNAME=cms.lolitapank.com
# Frontend URL
NEXT_PUBLIC_BASE_URL=https://lolitapank.com
# Headless authentication
HEADLESS_SECRET=insert_random_secret_key_min_32_chars
# WordPress credentials (para preview/draft)
WP_USER=preview_user
WP_APP_PASS=abcd 1234 efgh 5678
# WooCommerce REST API
WC_CONSUMER_KEY=ck_abc123...
WC_CONSUMER_SECRET=cs_xyz789...
# MercadoPago
MERCADOPAGO_ACCESS_TOKEN=APP_USR-1234567...
MERCADOPAGO_PUBLIC_KEY=APP_USR-abc123...
# Email (SendGrid/Resend)
SENDGRID_API_KEY=SG.abc123...
EMAIL_FROM=noreply@lolitapank.com
# Analytics (opcional)
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
Next Implementation Steps
Phase 0: Planning & Setup (Week 0-1)
□ Decisión final: Traditional vs Headless
□ Si Headless → Contratar Vercel Pro plan
□ Setup repositorio Git (GitHub)
□ Configurar WordPress en Hostinger
□ Instalar plugins requeridos
□ Configurar wp-config.php
□ Crear custom theme con functions.php
□ Setup Custom Post Types (Eventos, Artistas, Galerías)
□ Test GraphQL API funcionando
Phase 1: Next.js Base Setup (Week 1-2)
□ Create Next.js 14 project con App Router
□ Configurar TypeScript + ESLint + Prettier
□ Install dependencias: graphql, @apollo/client, etc.
□ Setup GraphQL Code Generator (codegen.ts)
□ Configurar next.config.js (images, redirects)
□ Implementar WordPress GraphQL client
□ Setup Layout + Navigation (Header/Footer)
□ Implementar catch-all route [[...slug]]
□ Test: Homepage rendering desde WordPress
Phase 2: Core Functionality (Week 3-5)
□ Implementar templates: Page, Post, Evento, Artista, Galería
□ Implementar /api/preview (Draft mode)
□ Implementar /api/revalidate (ISR webhook)
□ Setup middleware.ts (redirects handling)
□ Implementar robots.ts + sitemap.ts
□ Deploy a Vercel staging
□ Test preview mode end-to-end
□ Test revalidation funcionando
Phase 3: E-commerce Integration (Week 6-7)
□ Install WooCommerce + WPGraphQL for WooCommerce
□ Crear productos test (3-5 cursos)
□ Implementar /cursos/[slug] pages
□ Implementar CursoCheckoutForm component
□ Setup MercadoPago SDK + credentials
□ Implementar /api/checkout (crear orden WC + MP preference)
□ Implementar /api/webhooks/mercadopago
□ Test compra completa sandbox
□ Test emails confirmación
□ Switch to MercadoPago producción
□ Test compra real
Phase 4: Historical Archive (Week 8-9)
□ Importar contenido CSV (eventos, artistas, galerías)
□ Implementar templates específicos (EventoTemplate, etc.)
□ Implementar página /archivo con filtros
□ Implementar búsqueda (Algolia o built-in)
□ Optimizar galerías (lazy load, lightbox)
□ Test responsive mobile
Phase 5: Testing & Launch (Week 10-11)
□ Testing exhaustivo (ver propuesta original)
□ Setup UptimeRobot monitors
□ Setup sistema triple de backups
□ Test recuperación de backup
□ Capacitación cliente (2 sesiones)
□ Preparar documentación
□ Pre-launch checklist
□ DNS cutover
□ Launch 🚀
□ Monitoreo 72 horas
Client Documentation Deliverables
1. Daily Operation Manual
- Cómo publicar blog posts
- Cómo crear/editar cursos
- Cómo agregar eventos al archivo
- Cómo agregar artistas nuevos
- Cómo gestionar inscripciones
- Cómo responder consultas
2. Backup System Manual
- Verificar backups automáticos
- Descargar backup manual mensual
- Verificar alertas UptimeRobot
- Checklist mensual mantenimiento
3. Disaster Recovery Manual
- Escenario 1: WordPress muerto → Procedimiento paso a paso
- Escenario 2: Vercel muerto → Procedimiento paso a paso
- Escenario 3: Ambos muertos → Procedimiento completo
- Contactos de emergencia
4. Technical Manual for Developers (Future)
- Arquitectura del sistema
- Setup local development
- Deploy process
- Agregar nuevos Custom Post Types
- Agregar nuevos templates
- Troubleshooting común
Conclusion
This Headless Next.js + WordPress architecture offers:
✅ Superior performance: <500ms load time vs traditional 2-4s ✅ Improved security: WordPress not directly exposed ✅ Automatic Scaling: Vercel Global CDN ✅ Robust backup: Dual system (WordPress + Git) ✅ Modern DX: TypeScript, React, hot reload ✅ Total portability: Portable frontend, standard WordPress backend ✅ Excellent SEO: Static pre-rendering + metadata API
Trade-offs: ⚠️ Greater initial complexity (requires React developer) ⚠️ Slightly higher cost (~$240/year extra if Vercel Pro) ⚠️ E-commerce requires custom integration (vs native WooCommerce)
Ideal for Lolita Pank if:
- They have a budget for Vercel Pro (~$300-350/year total)
- They have or can hire a developer familiar with Next.js/React
- They prioritize performance, scalability and modern UX
- They plan to scale significantly in the next 2 years
Alternative: Start with Traditional WordPress (original proposal) and migrate to Headless in 6-12 months if the project is successful and requires greater performance/scale.