Al integrar la potente gestión de eventos de Eventbrite directamente en tu sitio de Webflow, puedes crear un calendario comunitario fluido y en tiempo real que potencie tu marca mientras automatizas las actualizaciones.
Los calendarios comunitarios tienen un punto débil: los eventos viven en Eventbrite porque allí es donde se gestionan las entradas, los reembolsos y los datos de los asistentes. El sitio web vive en Webflow porque ahí es donde reside la marca, y a veces, ambos mundos se desincronizan en cuanto alguien cambia una fecha.
Esta guía extrae los eventos de Eventbrite a través de tu propio controlador de rutas en Webflow Cloud, para que el calendario refleje siempre la información real de Eventbrite sin que nadie tenga que mantener una copia duplicada.
¿Qué necesitas para conectar Eventbrite y Webflow?
Necesitas una organización de Eventbrite con eventos, un token privado y un proyecto de Webflow Cloud desde el cual llamar a la API. El token determina la arquitectura, ya que Eventbrite es muy estricto sobre dónde puede y no puede utilizarse.
Aquí tienes la lista completa antes de empezar:
- Una cuenta de Eventbrite con una organización que sea propietaria de los eventos que quieres listar
- Un token privado desde tu página de claves de API de Eventbrite, además del ID de la organización
- Un proyecto de Webflow Cloud que ejecute Next.js 15 o superior, con Node.js 22 o posterior instalado localmente.
- Una página o un elemento Embed en el Designer donde se mostrará el calendario
Nunca debes incluir un token privado en el código del lado del cliente, y deberías eliminar los tokens que ya no necesites. Esa simple regla es la razón por la que esta implementación requiere una ruta de servidor. Así es como encajan las piezas.
¿Qué endpoints de Eventbrite necesita un calendario comunitario?
Cuatro endpoints cubren todo lo que hace una página de eventos comunitarios, y elegir el adecuado para cada tarea te permite mantener la integración dentro del presupuesto de solicitudes sin complicaciones.
La base de la API es https://www.eventbriteapi.com/v3, y estas son las llamadas que vale la pena conocer:
| Lo que quieres mostrar en la página | Endpoint | Por qué este |
|---|---|---|
| Todos los eventos que organiza tu entidad | /organizations/{id}/events/ | La fuente principal para listar eventos en un calendario comunitario, además está paginado |
| Detalles completos de un evento | /events/{id}/ | Usa expand= aquí en lugar de hacer llamadas adicionales |
| Tipos de entradas y precios | /events/{id}/ticket_classes/ | Solo necesario si muestras los precios tú mismo en lugar de integrar el proceso de pago |
| Quién se registró | /events/{id}/attendees/ | Los datos de los asistentes son privados, así que esto se queda en el servidor |
| Lo que quieres en la página → Endpoint → Por qué este |
|---|
| Todos los eventos que organiza tu entidad |
| /organizations/{id}/events/ |
| La fuente principal para listar eventos en un calendario comunitario, además está paginado |
| Detalles completos de un evento |
| /events/{id}/ |
| Usa expand= aquí en lugar de hacer llamadas adicionales |
| Tipos de entradas y precios |
| /events/{id}/ticket_classes/ |
| Solo necesario si muestras los precios tú mismo en lugar de integrar el proceso de pago |
| Quién se registró |
| /events/{id}/attendees/ |
| Los datos de los asistentes son privados, así que esto se queda en el servidor |
La distinción más importante es la última fila. Los datos de los asistentes y los pedidos son información personal de quienes compraron entradas, por lo que deben ir en una ruta del servidor con acceso autenticado, nunca en una respuesta JSON pública que alimente un listado.
5 pasos para crear un calendario de Eventbrite en Webflow Cloud
La estructura consiste en un token en una variable de entorno, un asistente de búsqueda que pide todo lo necesario en una sola llamada, un gestor de rutas que publica una versión simplificada y una caché que lo protege.
Cada paso protege el token o el presupuesto de solicitudes por hora.
1. Crea un token privado y anota el ID de la organización
Inicia sesión en Eventbrite, abre tu página de claves API y copia el token privado. Ya que estás ahí, busca el ID de la organización a la que pertenecen tus eventos, ya que un calendario comunitario se basa en la organización y no en un usuario personal.
Trata este token como si fuera una contraseña. La propia guía de Eventbrite recomienda mantenerlo fuera del código del cliente y eliminar los tokens que ya no uses; es mejor hacerlo de forma periódica que nunca.
Si has heredado un proyecto con un token subido a un repositorio, cámbialo antes de hacer cualquier otra cosa, porque un token en el historial de git es un token que ha sido expuesto.
Termina este paso con los dos valores anotados, y asegúrate de que ninguno esté en tu código.
2. Guarda ambos valores como variables de entorno en Webflow Cloud
Abre tu entorno de Webflow Cloud y añade el token y el ID de la organización, marcando el token como secreto para que se oculte en los registros de compilación.
Webflow Cloud hace que las variables de entorno estén disponibles durante la compilación y para la aplicación desplegada en tiempo de ejecución, de modo que la ruta pueda leerlas en cada solicitud. Lléelas dentro del controlador en lugar de en el nivel superior del módulo.
No añadas ningún prefijo a ninguna de las variables con NEXT_PUBLIC_. Ese prefijo es lo que le indica a Next.js que un valor es seguro para enviarlo al navegador, y aplicarlo a un token privado de Eventbrite publicaría el token para cualquier visitante que abra las herramientas de desarrollo. Los cambios en las variables de entorno requieren un nuevo despliegue para que surtan efecto.
Finaliza este paso con un despliegue exitoso y ambas variables listadas en la pestaña de Variables de Entorno, con el token marcado como secreto. No las imprimas para comprobarlo: Webflow trata la ocultación como una red de seguridad, no como un flujo de trabajo de gestión.
3. Obtén eventos con expansiones en lugar de llamadas de seguimiento
La versión ingenua de esta integración lista los eventos y luego busca el lugar de cada uno por separado. Eso supone una solicitud por evento, y así es como un calendario con cuarenta eventos se convierte en cuarenta y una solicitudes cada vez que alguien carga la página.
El sistema de expansiones de Eventbrite lo resuelve permitiéndote solicitar objetos relacionados en la llamada original:
// lib/eventbrite.ts
const BASE = 'https://www.eventbriteapi.com/v3'
type EventbriteEvent = {
id: string
name: { text: string }
start: { utc: string; local: string; timezone: string }
url: string
online_event: boolean
venue?: { name: string; address: { localized_address_display: string } }
logo?: { url: string }
}
export async function listOrganizationEvents(page = 1) {
const orgId = process.env.EVENTBRITE_ORG_ID as string
const token = process.env.EVENTBRITE_PRIVATE_TOKEN as string
const url = new URL(`${BASE}/organizations/${orgId}/events/`)
// 'started' matters: an event in progress leaves 'live'.
url.searchParams.set('status', 'live,started')
url.searchParams.set('order_by', 'start_asc')
url.searchParams.set('page', String(page))
// Pull the venue and logo in the same call rather than one
// follow-up request per event.
url.searchParams.set('expand', 'venue,logo')
const res = await fetch(url, {
headers: { Authorization: `Bearer ${token}` },
})
if (res.status === 429) {
const detail = (await res.json().catch(() => null)) as
| { error?: string; error_description?: string }
| null
// Branch on error, not error_description: the constant is stable.
console.error('Eventbrite', detail?.error, detail?.error_description)
throw new Error('EVENTBRITE_RATE_LIMITED')
}
if (!res.ok) {
const detail = (await res.json().catch(() => null)) as
| { error_description?: string }
| null
throw new Error(detail?.error_description ?? `Eventbrite ${res.status}`)
}
return (await res.json()) as {
events: EventbriteEvent[]
pagination: { has_more_items: boolean; page_number: number }
}
}
El expand=venue,logo parámetro hace el trabajo pesado aquí. Eventbrite documenta venue y logo como expansiones de eventos, aunque su propio ejemplo utiliza el listado de eventos propios en lugar del de la organización, así que confirma que los objetos regresan en tu endpoint antes de confiar en ellos.
Es la diferencia entre una solicitud y una por evento, y con un presupuesto predeterminado de 2000 llamadas por hora, esa diferencia decide si la página sobrevive a ser compartida.
Ten en cuenta también la rama 429. Eventbrite devuelve HIT_RATE_LIMIT con un error 429 cuando se alcanza el límite horario de un token, y sus respuestas de error contienen un error_description que vale la pena mostrar en los registros en lugar de descartar. Una llamada exitosa devuelve tus eventos con el lugar y el logotipo ya adjuntos.
4. Publica una respuesta recortada desde un controlador de ruta
La ruta es la frontera entre lo que sabe Eventbrite y lo que necesita la página pública. Todo lo que la cruce debe ser deliberado.
Devuelve solo los campos que el calendario renderiza:
// app/api/events/route.ts
import { NextResponse } from 'next/server'
import { getCloudflareContext } from '@opennextjs/cloudflare'
import { listOrganizationEvents } from '@/lib/eventbrite'
const CACHE_KEY = 'eventbrite:org-events'
export async function GET() {
// Webflow Cloud replaces any Cache-Control response header with
// private, no-cache, so cache in the KV store instead.
const { env } = getCloudflareContext()
const cache = env.EVENTS_CACHE
const cached = await cache.get(CACHE_KEY)
if (cached) {
return NextResponse.json(JSON.parse(cached))
}
try {
const { events } = await listOrganizationEvents()
// Return only what the page renders. Attendee and order data
// never belongs in a public response.
const payload = {
events: events.map((event) => ({
id: event.id,
title: event.name.text,
startsAt: event.start.utc,
startsAtLocal: event.start.local,
timezone: event.start.timezone,
url: event.url,
venue:
event.venue?.name ??
(event.online_event ? 'Online' : 'Venue to be announced'),
image: event.logo?.url ?? null,
})),
}
// 60 seconds is the documented minimum TTL for the KV store.
await cache.put(CACHE_KEY, JSON.stringify(payload), {
expirationTtl: 60,
})
return NextResponse.json(payload)
} catch (error) {
if ((error as Error).message === 'EVENTBRITE_RATE_LIMITED') {
return NextResponse.json({ error: 'Try again shortly' }, { status: 503 })
}
return NextResponse.json({ error: 'Could not load events' }, { status: 502 })
}
}
Un límite a tener en cuenta: esto devuelve solo la primera página. Eventbrite pagina en grupos de 50, por lo que un calendario con más eventos que eso necesita seguir la paginación en lugar de detenerse en la primera respuesta.
Mapear la respuesta en lugar de reenviarla es un hábito que vale la pena mantener. El objeto de evento sin procesar contiene mucho más de lo que necesita un listado, y una respuesta que simplemente actúa como proxy de la API tiende a convertirse en una exportación pública accidental de cualquier cosa que Eventbrite añada después.
El almacenamiento en caché es la otra mitad de la historia del límite de velocidad, y en Webflow Cloud no puede ser una cabecera de respuesta. Webflow Cloud siempre reemplaza una cabecera de respuesta Cache-Control con private, no-cache y la elimina de las solicitudes, por lo que una ruta que intenta almacenar en caché de esa manera no está almacenando nada en absoluto.
Almacena la carga útil en el almacén de clave-valor (Key Value Store) en su lugar, donde 60 segundos es el tiempo de vida mínimo documentado. Un minuto de caché significa que una página compartida con unos pocos miles de personas cuesta el mismo número de llamadas a Eventbrite que una página que nadie visita. Terminarás este paso con un endpoint JSON desde el que tu página de Designer puede obtener datos.
5. Decide dónde ocurre el proceso de pago
Ya tienes un calendario. La decisión restante es qué hace el botón de registro, y es más importante de lo que parece.
Enviar a los visitantes a la URL del evento de Eventbrite significa que Eventbrite se encarga del pago, los reembolsos, los impuestos y la comunicación con los asistentes, lo cual suele ser el intercambio correcto para un evento comunitario.
Integrar el proceso de pago de Eventbrite permite que los usuarios permanezcan en tu página mientras Eventbrite se encarga de las responsabilidades. Crear tu propio flujo de registro significa que te haces cargo de todo, incluso de esas partes que a nadie le gusta gestionar.
La opción intermedia es la predeterminada para la mayoría de los calendarios comunitarios, y el url campo que ya aparece en tu respuesta recortada es lo que se necesita. Elijas lo que elijas, mantén el inventario de entradas en Eventbrite en lugar de duplicar los recuentos en el CMS, ya que un aviso de "agotado" desactualizado es peor que no tener nada.
Terminas este paso con un calendario cuyos botones dirigen a un lugar que realmente puede procesar pagos.
¿Qué hace que las integraciones de Eventbrite fallen en Webflow Cloud?
Los fallos aquí suelen deberse a dos cosas: que un token privado termine donde no debe y que el presupuesto de solicitudes por hora se agote antes de lo previsto. Ninguno de los dos se manifiesta claramente en el navegador.
Cuatro problemas aparecen repetidamente, y el primero es el que debes revisar antes que nada.
Los eventos dejan de cargarse durante un pico de tráfico
Causa: El límite de tasa por hora. El valor predeterminado de Eventbrite es de 2000 llamadas por hora por token, y devuelve un error 429 con HIT_RATE_LIMIT una vez que lo alcanzas. Una ruta sin caché que realiza peticiones por cada vista de página llegará a ese límite justo cuando más necesitas que la página funcione.
Solución: Almacena la carga útil de Eventbrite en el Key Value Store en lugar de usar un encabezado Cache-Control , que Webflow Cloud reemplaza, y utiliza expansiones para que el renderizado de una página cueste una sola llamada en lugar de una por cada evento.
Si después de esto sigues cerca del límite, aumenta el tiempo de caché en lugar de intentar optimizar las peticiones. Un calendario con sesenta segundos de retraso es aceptable; un calendario que devuelve errores cuando un evento se vuelve viral, no.
El token aparece en el navegador
Causa: La variable tenía el prefijo NEXT_PUBLIC_, o la petición se movió a un componente de cliente durante una refactorización. Ambos casos envían el token a cada visitante, y ninguno genera un error.
Solución: Mantén el token en una variable sin prefijo leída dentro del Route Handler y luego verifica el resultado compilado en lugar de confiar ciegamente en el código. Busca los primeros caracteres del token en el paquete desplegado, ya que eso lo detectará independientemente de si llegó a través de un prefijo o de un componente de cliente.
Si alguna vez estuvo expuesto, cámbialo en Eventbrite en lugar de solo eliminarlo, porque hay que asumir que todo lo publicado ha sido recopilado. Eventbrite también aconseja eliminar los tokens que ya no necesites, que es la forma más económica de limitar el alcance de uno que haya sido filtrado.
Faltan datos del lugar o de la imagen en el listado
Causa: No se solicitó la expansión. Eventbrite no devuelve objetos expandidos de forma predeterminada, por lo que event.venue está ausente en lugar de vacío, y el código que utiliza encadenamiento opcional termina con un campo en blanco sin generar errores.
Solución: Añade el objeto al parámetro expand y confírmalo en la respuesta sin procesar en lugar de en tu salida renderizada, porque un encadenamiento opcional en tu código de mapeo ocultará la diferencia entre ausente y vacío.
Gestiona también el caso de la ausencia real de datos, ya que un evento online no tiene lugar físico, y un listado que muestra una cadena vacía parece roto en lugar de intencional. Usar una etiqueta como "Online" es más honesto que dejar el campo en blanco y esperar que nadie se dé cuenta.
La compilación falla después de añadir las rutas de la API
Causa: Una directiva en uno de los archivos nuevos. Webflow Cloud despliega Next.js a través del export const runtime = 'edge'adaptador OpenNext Cloudflare, que no es compatible con el entorno de ejecución edge de Next.js.
Solución: Elimina la línea y vuelve a desplegar, ya que los Route Handlers ya se ejecutan en el entorno de ejecución de Workers. Busca en todo el proyecto, no solo en el archivo que tocaste por última vez, porque una sola directiva en cualquier lugar puede hacer fallar la compilación.
Revisa esto primero si una compilación de Webflow Cloud falla justo después de añadir nuevas rutas, ya que la página de "trae tu propia aplicación" de Webflow sigue indicando a los usuarios de Next.js que añadan la directiva, lo que significa que la instrucción que seguiste podría ser la causa y no tu código.
El error aparece durante la compilación y menciona el adaptador, no la directiva, por lo que rara vez se señala a sí mismo.
Qué puedes construir a continuación con Eventbrite y Webflow
Un calendario en vivo es solo el punto de partida. Los siguientes pasos lógicos son un archivo de eventos pasados creado desde el mismo endpoint, filtros por categoría o lugar, y un webhook que reaccione cuando un evento cambie en lugar de esperar a la próxima caducidad de la caché.
Si quieres que los registros alimenten tanto a una audiencia de correo electrónico como a una plataforma de venta de entradas, nuestra guía de registro de eventos en Mailchimp cubre ese proceso, incluida la pregunta de consentimiento necesaria. Para rutas de conexión sin código, consulta la integración de Webflow y Eventbrite.
Preguntas frecuentes
¿Puedo llamar a la API de Eventbrite directamente desde el navegador?
No. La documentación de Eventbrite indica explícitamente que no se debe incluir un token privado en el código del lado del cliente, ya que cualquier solicitud desde el navegador es visible para el visitante. Llama a la API desde un Route Handler y devuelve solo los campos que tu página necesite mostrar.
¿Cuántas llamadas a la API de Eventbrite tengo disponibles?
El límite predeterminado documentado es de 2000 llamadas por hora y por token; superarlo devuelve un error 429 con HIT_RATE_LIMIT. Almacenar la carga útil en el almacén de clave-valor de Webflow Cloud y usar expansiones permite mantener un calendario activo dentro de esos límites. Ten en cuenta también el segundo tope: Eventbrite documenta 48 000 llamadas al día además del límite horario.
¿Debería copiar los eventos al CMS de Webflow en su lugar?
Solo si necesitas funciones del CMS que la API no ofrece, como contenido enriquecido con estilos del Designer para cada evento. Un espejo requiere sincronización, y si esta falla silenciosamente, el sitio mostrará un evento que ya cambió. Leer los datos en vivo evita este tipo de problemas por completo.
¿Qué ahorra realmente el parámetro expand?
Una solicitud por cada objeto relacionado. Sin él, listar eventos y luego obtener cada lugar implica una llamada por evento. Con él, la información del lugar llega en la respuesta original, lo que marca la diferencia entre una sola llamada y cuarenta y una en un calendario con mucha actividad.
¿Dónde debería realizarse el proceso de pago de las entradas?
Normalmente en Eventbrite, ya sea mediante un enlace a la URL del evento o integrando su sistema de pago. Ambas opciones dejan la gestión de reembolsos, impuestos y comunicación con los asistentes en manos de la plataforma diseñada para ello. Crea tu propio sistema solo si necesitas algo que el flujo de Eventbrite no pueda cubrir.





