LolitaPank

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

TechnologyStack

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)

SystemArchitecture

┌─────────────────────────────────────────────────────────────┐
│                         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) │
└───────────────────────────────────────────────────────────┘


DataFlow

Editorial Content (Posts, Events, Artists, Galleries)

  1. Editing in WordPress (CMS)
    • Editor adds/edits content in WordPress admin
    • Custom Post Types: Posts, Events, Artists, Galleries
    • ACF Flexible Content for custom blocks
  2. Update Webhook
    • WordPress trigger webhook in save_post
    • Call /api/revalidate in Vercel
  3. Incremental Revalidation
    • Next.js revalidates only affected routes
    • New content available in ~2-5 seconds
    • Does not require a complete rebuild
  4. 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
  1. Catalog in Next.js
    • Next.js fetcha productos vía WPGraphQL
    • Genera páginas estáticas /cursos/[slug]
    • ISR revalida cada 60 segundos (configurable)
  2. 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
  3. 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

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 = 60

4. 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:

  1. WordPress Backend (CMS + Database)
  2. 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:

    1. Login to WordPress admin
    2. UpdraftPlus → “Backup Now”
    3. Download all files locally
    4. Store on external hard drive + personal Google Drive
    5. 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:

  1. All changes are committed to Git
  2. Git is hosted on GitHub (redundant servers)
  3. Developer maintain local clone
  4. 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:

  1. Frontend Next.js (https://lolitapank.com)
    • Check every 5 minutes
    • Alert if down >2 minutes
    • Notify: Email + SMS
  2. WordPress GraphQL API (https://cms.lolitapank.com/graphql)
    • Check every 10 minutes
    • Alert if response time >5s or down
    • Notify: Email
  3. 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.