TL;DR. Para frontends modernos en React, Next.js, Vue/Nuxt, Astro, Remix o SvelteKit, la integración del Libro de Reclamaciones se hace mediante un componente reutilizable que consume la API REST/GraphQL de claimbook.pe. El patrón típico: hook custom useComplaint() con manejo de estado vía useReducer, validación de schema con Zod, llamada autenticada con Bearer Token o HMAC firmado en backend, y persistencia opcional en SSR/SSG/ISR. Headless commerce (Shopify Hydrogen, BigCommerce, Saleor) lo integra como un «module» con webhook bidireccional. La API key nunca debe exponerse en cliente: se firma en una route handler de Next.js o serverless function. Tiempo de implementación con dev senior: 2-4 días para un componente production-ready. Snippets en TypeScript incluidos.
Implementar el Libro de Reclamaciones en React, Next.js y entornos Headless (Perú 2026)
Las plataformas no-code y los CMS tradicionales cubren bien al comerciante mediano, pero el ecosistema peruano de e-commerce moderno se mueve cada vez más hacia frontends headless: Next.js sobre Shopify Hydrogen, Astro como capa SEO sobre Saleor, Nuxt sobre commercetools o stacks 100 % custom con backend en Node/Go y frontend React/Vue. Esta guía aterriza la integración del Libro de Reclamaciones para developers que diseñan estos frontends, con foco en Ley 32495, Resolución 0272-2024/SPC-INDECOPI y plazo de respuesta de 15 días hábiles (Ley 31435).
React, Next.js y headless: contexto 2026
El stack moderno peruano se concentra en cuatro estrategias: Next.js 14 con App Router para tiendas DTC con personalización fuerte, Astro para sitios content-heavy con islas de interactividad, Nuxt 3 para SPAs con SSR donde el equipo prefiere Vue, y Remix/SvelteKit para casos específicos. Headless commerce ya no es ciencia ficción: Saleor, BigCommerce, Shopify Hydrogen y commercetools tienen presencia real en proyectos peruanos.
El reto regulatorio: el frontend headless no puede tener lógica de negocio del libro embebida (sería brecha de seguridad expone el API key) y no puede asumir que el backend de e-commerce maneja la responsabilidad (no la maneja: ningún headless commerce trae libro virtual peruano nativo). La solución limpia es exponer el formulario en el frontend y delegar la creación al SaaS especializado vía API server-side.
Componente React básico (con hooks)
El componente mínimo viable usa useReducer para manejar estado del formulario, fetch hacia un endpoint propio (/api/complaint) que firma la llamada al SaaS, y muestra estados de loading, success y error. Patrón:
type State = { name: string; doc: string; description: string; status: 'idle' | 'loading' | 'success' | 'error' };
const reducer = (s: State, a: Action): State => { /* ... */ };
const [state, dispatch] = useReducer(reducer, initial);
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
dispatch({ type: 'submit' });
const res = await fetch('/api/complaint', { method: 'POST', body: JSON.stringify(state) });
if (res.ok) dispatch({ type: 'success', payload: await res.json() });
else dispatch({ type: 'error', error: await res.text() });
};
El componente se puede empaquetar como módulo NPM privado @claimbook/react que el equipo importa con import { ComplaintForm } from '@claimbook/react'. Esto evita que cada proyecto reimplemente la lógica de validación.
Next.js: SSR vs SSG vs ISR
Next.js 14 con App Router ofrece tres estrategias para servir el formulario del libro:
| Modo | Cuándo usar | Latencia | SEO |
|---|---|---|---|
| SSR (dynamic) | Cuando precargas datos del usuario logueado | ~200ms TTFB | Excelente |
| SSG (static) | Página pública sin datos personalizados | ~50ms TTFB | Excelente |
| ISR (revalidate) | Página con contenido legal que cambia mensualmente | ~50ms TTFB | Excelente |
| Client-only | Nunca para libro de reclamaciones | ~varía | Pobre |
El default recomendado es SSG con revalidate: 86400 (un día). El formulario es interactivo y se renderea en cliente, pero el shell de la página es estático. La route handler en app/api/complaint/route.ts es el único componente server que toca la API key:
export async function POST(req: Request) {
const body = await req.json();
const sig = createHmac('sha256', process.env.CLAIMBOOK_SECRET!).update(JSON.stringify(body)).digest('hex');
const res = await fetch('https://claimbook.pe/api/v1/complaints', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.CLAIMBOOK_TOKEN}`, 'X-Signature': sig, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return Response.json(await res.json(), { status: res.status });
}
La env var CLAIMBOOK_SECRET nunca se filtra al bundle del cliente porque vive solo en el runtime serverless. Vercel, Netlify, AWS Lambda y Cloudflare Workers respetan esta separación.
Vue y Nuxt
El equivalente Vue/Nuxt usa ref y reactive en lugar de hooks, pero el patrón es idéntico. Nuxt 3 con server routes (server/api/complaint.post.ts) firma la llamada al SaaS y devuelve el ID del reclamo al cliente. Composable equivalente:
export const useComplaint = () => {
const state = reactive({ name: '', doc: '', description: '', status: 'idle' });
const submit = async () => {
state.status = 'loading';
const res = await $fetch('/api/complaint', { method: 'POST', body: state });
state.status = res.id ? 'success' : 'error';
return res;
};
return { state, submit };
};
El sweet spot de Nuxt es la combinación con Pinia para persistir borradores de reclamación entre rutas (cuando el usuario navega y vuelve, no pierde lo escrito). Este patrón eleva la calidad de los reclamos recibidos porque elimina abandono por interrupción.
Astro: islas + persistencia
Astro es la opción con mejor performance para sitios donde el libro virtual es una página secundaria. La página libro-de-reclamaciones.astro se renderiza estática 100 % y el formulario se hidrata como isla con client:visible:
---
// libro-de-reclamaciones.astro
---
<Layout>
<ComplaintForm client:visible />
</Layout>
La isla solo carga JavaScript cuando entra al viewport del usuario. En conexiones 3G peruanas (todavía 35 % del tráfico mobile en provincia) esto reduce LCP de 4s a menos de 1s. La integración con la API se hace vía Astro server endpoints en src/pages/api/complaint.ts.
Headless commerce: Hydrogen, Saleor, BigCommerce
Cada plataforma headless tiene su lugar para integrar el libro:
- Shopify Hydrogen: ruta
/libro-de-reclamacionesen Remix conactionque firma la llamada server-side. El catálogo viene de Shopify Storefront API; el reclamo va a claimbook.pe. - Saleor: plugin Saleor App con webhook
ORDER_CREATEDque precarga datos en el formulario. La autenticación cruza por GraphQL Federation. - BigCommerce: Stencil theme custom con Embed JS que apunta a un microservicio Node propio que firma la llamada. Big tiene API key con scopes muy granulares.
- commercetools: integración vía Subscriptions con destinos AWS SQS y Lambda function que invoca claimbook.pe.
El patrón común: el headless commerce expone eventos del Order Lifecycle, un middleware backend escucha esos eventos y precarga datos en el flujo de reclamo. El usuario completa solo lo que falta (descripción del problema, evidencia adjunta).
Webhooks para recepción asíncrona
El frontend headless suele tener panel administrativo propio (típicamente Next.js con NextAuth para el equipo de operaciones). Para que ese panel reciba notificaciones de reclamos sin polling, se suscribe a webhooks de claimbook.pe:
POST https://claimbook.pe/api/v1/webhooks/register
{
"url": "https://tu-tienda.com/api/webhooks/claimbook",
"events": ["complaint.created", "complaint.due_in_5_days", "complaint.escalated_to_indecopi"],
"secret": "<tu-secret-rotativo>"
}
El handler en Next.js verifica firma HMAC del header X-Claimbook-Signature y dispara notificación interna (Slack, email, webhook a Pipedream). El SLA de delivery es menor a 2 segundos.
Snippets de código en TypeScript
Tipos compartidos recomendados para el cliente y backend:
type Complaint = {
id: string;
code: string; // correlativo asignado por claimbook.pe
customer: { name: string; doc: string; docType: 'DNI' | 'CE' | 'PAS'; email: string; phone: string };
product: { name: string; orderId?: string; amount: number; currency: 'PEN' | 'USD'; date: string };
type: 'reclamo' | 'queja';
description: string;
request: string;
attachments: { url: string; name: string; size: number }[];
status: 'received' | 'in_review' | 'responded' | 'escalated';
createdAt: string;
responseDeadline: string; // 15 días hábiles desde createdAt
};
La validación con Zod evita que el cliente envíe payloads inválidos al backend (el backend valida también, pero la primera barrera reduce 60 % de errores). El bundle final con Zod + el componente form pesa menos de 18 KB gzipped.
Seguridad: API key, CORS y CSP
Tres reglas no negociables:
- La API key de claimbook.pe vive solo en variables de entorno del servidor. Nunca en
NEXT_PUBLIC_*, nunca enVITE_, nunca en bundle del cliente. - CORS de claimbook.pe acepta el dominio del retailer pero rechaza llamadas directas desde el cliente sin firma HMAC. Toda llamada pasa por el backend.
- CSP del frontend permite
connect-srchacia el backend propio pero no hacia claimbook.pe directamente. Esto cierra el vector de «filter bypass» descrito en OWASP Top 10.
La guía sobre seguridad y cifrado del Libro de Reclamaciones entra al detalle del threat model y el mapeo con DS 016-2024-JUS sobre protección de datos personales.
Testing y CI/CD
Para mantener calidad de la integración a lo largo del tiempo:
- Pruebas unitarias del reducer y del componente con Vitest + React Testing Library.
- Pruebas de integración contra sandbox de claimbook.pe con MSW para mockear respuestas en CI.
- E2E con Playwright que ejecuta el flujo completo desde la home hasta la confirmación de reclamo.
- Pruebas de carga con k6 simulando 100 reclamos/min para validar que la queue asíncrona absorbe spike sin caídas.
- Lighthouse CI para asegurar que la página del libro mantiene LCP < 2.5s y CLS < 0.1.
Si tu equipo desarrolla sobre VTEX o Magento (retail enterprise), revisa la guía VTEX y Magento enterprise. Si prefieres no-code, la configuración en Shopify Perú y la guía general de integración e-commerce cubren mejor ese terreno.
Performance, Core Web Vitals y SEO técnico
Google mide la página del Libro de Reclamaciones igual que cualquier otra del dominio. Si esa página tiene LCP de 6 segundos en mobile, baja el promedio del sitio entero y degrada Search Console. Tres reglas concretas para mantener performance en orden:
- Code-splitting agresivo: el componente form se carga vía
dynamic(() => import('./ComplaintForm'), { ssr: false })en Next.js. Esto evita que el bundle inicial cargue dependencias del formulario cuando el usuario solo está leyendo la página. - Imágenes optimizadas: si la página incluye sello de Indecopi o icono institucional, sirvelo como SVG inline o WebP con
next/imageconpriority={false}. - Prefetch del endpoint: cuando el usuario hace foco en el primer input, dispara un
fetch HEAD /api/complaintpara abrir conexión TCP+TLS y ahorrar 200ms en el submit final.
El SEO técnico de la página: meta title Libro de Reclamaciones | [Marca], meta description con foco en cumplimiento y plazo de 15 días, structured data WebPage con about apuntando a «Consumer Complaints» y publisher al Organization del retailer. Esto ayuda a que Google entienda el propósito de la página y la indexe correctamente.
Observabilidad y métricas internas
Para retailers con cultura data-driven, el flujo del libro debe instrumentarse:
- Eventos GA4:
complaint_form_view,complaint_form_start,complaint_form_abandon,complaint_form_submit,complaint_form_success. - Métricas Prometheus en backend:
claimbook_request_duration_seconds,claimbook_request_total,claimbook_errors_totalcon label por código HTTP. - Trazas OpenTelemetry: spans desde el componente cliente hasta la respuesta del SaaS, atravesando la route handler. Esto permite identificar el cuello de botella cuando hay latencia anómala.
- Dashboard ejecutivo: un panel Grafana o Looker Studio con tasa de reclamos/día, tiempo promedio de respuesta, % cumplido en 15 días, y top 10 problemas por categoría. Insumo directo para gerencia legal y CX.
La métrica de oro es «% de reclamos respondidos en plazo». Por debajo de 95 %, el riesgo de sanción Indecopi sube de manera no lineal: cada reclamo no respondido en 15 días hábiles es una infracción potencial. Con UIT 2026 a S/ 5,500, una franja de 50 reclamos no respondidos puede acumular más de S/ 200,000 en multas si se ventilan en procedimientos sumarísimos.
Preguntas frecuentes
¿Cómo integro en Next.js?
Crea una ruta App Router app/libro-de-reclamaciones/page.tsx con el componente form, una route handler app/api/complaint/route.ts que firma con HMAC y llama a la API de claimbook.pe usando la env var del servidor, y opcionalmente un webhook handler en app/api/webhooks/claimbook/route.ts para recibir notificaciones.
¿Y en Vue/Nuxt?
En Nuxt 3, el composable useComplaint() maneja estado con reactive, llama a /api/complaint con $fetch, y la server route en server/api/complaint.post.ts firma la llamada y reenvía a claimbook.pe.
¿Astro soporta?
Sí, y es la opción con mejor performance para sitios content-heavy. El formulario se hidrata como isla con client:visible, lo cual mantiene LCP bajo en conexiones 3G. La API se invoca vía Astro server endpoints.
¿Cómo manejo el SSR?
Next.js permite SSR, SSG e ISR. El default recomendado es SSG con revalidate: 86400. El formulario es interactivo en cliente; la página es estática. El componente form se hidrata cuando el usuario interactúa.
¿Headless: cómo lo conecto?
Plataformas headless (Hydrogen, Saleor, BigCommerce, commercetools) exponen eventos del Order Lifecycle. Un middleware backend escucha esos eventos, precarga datos del pedido en el flujo del reclamo y reenvía al SaaS de libro virtual. El frontend solo muestra el formulario y consume el ID devuelto.
¿API key segura?
La API key vive solo en variables de entorno del servidor. Nunca en bundles del cliente, nunca con prefijo público. Toda llamada al SaaS pasa por una route handler o serverless function que firma con HMAC y autentica con Bearer Token rotado cada 90 días.
¿Webhook para recepción?
Sí. claimbook.pe expone un endpoint /api/v1/webhooks/register que suscribe tu URL a eventos como complaint.created, complaint.due_in_5_days, complaint.responded. El payload viene firmado con HMAC; tu handler verifica firma y dispara notificación interna.
¿Hook personalizado para validar?
Recomendado: useComplaintValidation() con Zod schema que valida DNI peruano (8 dígitos), CE (extranjeros), email y descripción mínima 50 caracteres. Devuelve errores por campo y deshabilita el botón submit si hay invalidaciones.
Conclusión
Frontends headless modernos integran Libro de Reclamaciones con tres piezas claras: componente reutilizable en cliente, route handler en server que firma la llamada, webhook handler para recibir notificaciones. La API key nunca toca el cliente. El bundle se mantiene en menos de 20 KB gzipped. La validación Zod elimina 60 % de errores antes del primer roundtrip. Y el flujo cumple Ley 32495, Ley 31435 y la doctrina vigente de Indecopi sin sacrificar performance ni DX.
¿Tu stack es React/Next.js/Vue/Astro y necesitas integración profesional? claimbook.pe expone APIs REST y GraphQL documentadas con SDK TypeScript opcional, sandbox para testing y soporte dev. Solicita acceso a la documentación técnica completa.