Neon Postgres se conecta a Webflow Cloud sin proxies, sin configuraciones de Hyperdrive y sin ciclos de vida de conexión que gestionar. Si estás creando una aplicación Next.js en Webflow Cloud que necesita una base de datos real, esta configuración es la solución.
Cómo añadir una base de datos Postgres serverless (Neon) a tu proyecto de Webflow Cloud
El CMS de Webflow gestiona bien el contenido. Sin embargo, en cuanto necesitas datos relacionales (registros de usuario, directorios con búsqueda, uniones entre tablas, búsqueda de similitud pgvector), necesitas algo más.
Webflow Cloud ejecuta Next.js en Cloudflare Workers. Cada invocación de Worker se ejecuta en un contexto sin estado; los clientes de Postgres estándar que mantienen conexiones persistentes entre consultas no encajan en este modelo.
Neon soluciona esto: su @neondatabase/serverless controlador envía cada consulta como una solicitud HTTP independiente, sin objetos de conexión que abrir, gestionar o cerrar entre invocaciones.
En Webflow Cloud, una consulta de Neon se ejecuta de forma nativa desde un gestor de rutas sin proxies, sin configuración de Hyperdrive y sin ciclos de vida de conexión que gestionar.
Esta guía cubre toda la configuración: crear un proyecto en Neon, configurar la cadena de conexión agrupada, realizar consultas desde componentes de servidor y gestores de rutas API de Next.js, y desplegar en Webflow Cloud.
¿Cuáles son las opciones de conexión para Neon en Webflow Cloud?
Existen tres formas prácticas de conectar Neon Postgres a un entorno de Cloudflare Workers. Yo uso la neon() función HTTP para casi todos mis proyectos en Webflow Cloud. Requiere la configuración mínima y se ejecuta de forma nativa en el entorno de ejecución de Workers sin ajustes adicionales.
La siguiente tabla relaciona cada método con su capa de transporte, caso de uso principal y compatibilidad con el entorno de ejecución de Workers de Webflow Cloud:
| Método | Paquete | Transporte | Ideal para | Webflow Cloud |
|---|---|---|---|---|
neon() función |
@neondatabase/serverless |
HTTP | Consultas únicas, serverless, edge | Recomendado |
Pool / Client |
@neondatabase/serverless |
WebSocket | Sesiones, transacciones | Funciona, requiere más configuración |
Hyperdrive + pg |
pg + Cloudflare Hyperdrive |
TCP (con proxy) | Aplicaciones de alto volumen, agrupación de conexiones | Funciona, requiere Hyperdrive |
Estándar pg |
pg |
TCP | Servidores tradicionales | Conexiones TCP persistentes; incompatibles con el modelo de ejecución sin estado de los Workers |
| Método → Paquete → Transporte → Ideal para → Webflow Cloud |
|---|
neon() función |
@neondatabase/serverless |
| HTTP |
| Consultas únicas, serverless, edge |
| Recomendado |
Pool / Client |
@neondatabase/serverless |
| WebSocket |
| Sesiones, transacciones |
| Funciona, requiere más configuración |
Hyperdrive + pg |
pg + Cloudflare Hyperdrive |
| TCP (con proxy) |
| Aplicaciones de alto volumen, agrupación de conexiones |
| Funciona, requiere Hyperdrive |
Estándar pg |
pg |
| TCP |
| Servidores tradicionales |
| Conexiones TCP persistentes; incompatibles con el modelo de ejecución sin estado de los Workers |
Estándar pg abre conexiones TCP persistentes que esperan sobrevivir a múltiples consultas. En el entorno de ejecución de Workers, cada solicitud se ejecuta en un contexto nuevo. No existe un grupo de conexiones entre invocaciones, por lo que esas conexiones terminan al finalizar cada controlador, dejando estados pendientes.
El @neondatabase/serverless controlador se creó para resolver exactamente esta limitación: reimplementa el protocolo Postgres sobre HTTP y WebSockets, ambos soportados de forma nativa por los Workers.
La neon() función es la opción HTTP: la más rápida de configurar, sin objetos de conexión que gestionar, sin ciclo de vida de apertura/cierre, y cada consulta es una solicitud HTTP independiente. Para la mayoría de las operaciones CRUD en una aplicación de Webflow Cloud, esta es la opción ideal.
¿Qué necesitas para conectar Neon Postgres a Webflow Cloud?
Necesitas un espacio de trabajo de Webflow con acceso a Cloud, una cuenta de Neon, Node.js 22.0.0 o superior y la CLI de Webflow. El plan gratuito de Neon es realmente útil para el desarrollo. Ofrece 100 proyectos (cada uno con 10 ramas, 0.5 GB de almacenamiento y 100 horas-CU de cómputo al mes) y se suspende automáticamente tras 5 minutos de inactividad.
Un espacio de trabajo de Webflow con acceso a Cloud
Confirma que tienes acceso a la sección Cloud en tu panel de control de Webflow. Webflow Cloud está disponible en planes de sitio de pago.
Tu proyecto Cloud se montará como una subruta de tu sitio Webflow, por ejemplo, yoursite.webflow.io/app o en un dominio personalizado. Establecerás esta ruta de montaje al crear el entorno en un paso posterior, así que decídela antes de inicializar el proyecto.
Si tu espacio de trabajo está en un plan gratuito, actualízalo a un plan de sitio de pago antes de continuar. Webflow Cloud no está disponible en el nivel gratuito y la CLI te pedirá un sitio con acceso a Cloud durante webflow cloud init.
Node.js 22.0.0 o superior y npm
Tanto el entorno de compilación de Webflow Cloud como la vista previa local requieren Node.js 22. Si tienes una versión anterior, utiliza un gestor de versiones como nvm o fnm para cambiar: nvm install 22 && nvm use 22.
Webflow Cloud solo admite npm. Si tu proyecto actual utiliza pnpm o yarn, convierte el archivo de bloqueo a package-lock.json y elimina los otros archivos de bloqueo antes de inicializar. Un proyecto con un yarn.lock o pnpm-lock.yaml fallará durante el paso de compilación de Webflow Cloud.
La CLI de Webflow
La CLI de Webflow gestiona la creación de la estructura del proyecto, la vista previa local y el despliegue en Webflow Cloud. Se publica en npm y requiere una cuenta de Webflow para autenticarse.
La CLI utiliza las credenciales de tu cuenta de Webflow para vincular el proyecto local después de crear un sitio. La autenticación se gestiona de forma integrada durante webflow cloud init. No necesitas autenticarte por separado antes de ejecutar el comando init.
Instálala globalmente y autentícate antes de inicializar el proyecto:
npm install -g @webflow/webflow-cli
Confirma con webflow --version.
Una cuenta y un proyecto de Neon
Crea una cuenta en neon.com.
El nivel gratuito de Neon es suficiente para el desarrollo y un tráfico de producción ligero. Una vez que hayas iniciado sesión, crea un proyecto. Neon aprovisiona una base de datos Postgres y crea automáticamente una rama, una base de datos y un rol predeterminados.
Después de crear tu proyecto de Neon, la implementación lleva unos 30 minutos. Aquí te explicamos cómo.
5 pasos para conectar Neon Postgres como backend de base de datos para Webflow Cloud
Estos cinco pasos cubren la inicialización del proyecto en Webflow Cloud, la configuración de la cadena de conexión de Neon, la configuración del controlador, las consultas desde componentes de servidor y manejadores de rutas, y el despliegue en producción.
Si has seguido alguna de nuestras guías de Webflow Cloud anteriores, la estructura del paso 1 es idéntica. La configuración de Webflow Cloud es coherente en todas las integraciones.
1. Inicializa el proyecto de Webflow Cloud
Instala la CLI de Webflow y ejecuta webflow cloud init para crear la estructura del proyecto.
La autenticación se solicita de forma integrada durante la inicialización:
npm install -g @webflow/webflow-cli
webflow cloud init
El asistente de inicialización te pedirá que selecciones un framework (elige Next.js), establezcas una ruta de montaje y te autentiques. Webflow Cloud lee tu package.json, detecta el framework y genera la configuración de despliegue en el momento de la compilación, por lo que gran parte de lo que habrás visto descrito como estructura necesaria no lo es.
No es necesario incluir un adaptador, una ruta base o un modo de salida. Solo se necesita un wrangler.json para declarar enlaces de almacenamiento, y una aplicación Neon no tiene ninguno, por lo que esta pila no necesita ninguna configuración de wrangler.
Esto es lo que hace que @neondatabase/serverless funcione, ya que el controlador utiliza internamente las API de buffer y crypto de Node.js:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "nextjs",
"main": ".open-next/worker.js",
"compatibility_date": "2025-03-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"binding": "ASSETS",
"directory": ".open-next/assets"
},
"observability": { "enabled": true }
}
El archivo opcional webflow.json fija el framework. La detección es automática, así que solo añádelo si quieres que la elección sea explícita:
{
"cloud": {
"framework": "nextjs"
}
}
Luego, instala el adaptador OpenNext y añade el script de vista previa:
npm install @opennextjs/cloudflare
{
"scripts": {
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview"
}
}
Ejecuta npm run preview antes de cada despliegue para detectar problemas de tiempo de ejecución localmente antes de que lleguen a producción. La simulación de Wrangler es lo suficientemente parecida al entorno de ejecución de Workers en producción como para detectar la mayoría de los fallos de conexión de Neon antes de desplegar.
Resultado esperado: El proyecto se estructura correctamente. npm run preview inicia una simulación local de Wrangler sin errores. Ahora tienes un proyecto de Next.js funcional listo para conectarse a Neon.
2. Obtén la cadena de conexión agrupada de Neon
Haz clic en Connect en el panel de control de tu proyecto Neon para abrir el modal de conexión a tu base de datos. Selecciona tu rama, base de datos y rol.
Activa el interruptor de agrupación de conexiones (Connection pooling) si no está ya encendido.
Esto genera una cadena de conexión con -pooler en el nombre de host:
postgresql://username:password@ep-xxx-pooler.us-east-1.aws.neon.tech/dbname?sslmode=require&channel_binding=require
La cadena de conexión agrupada se enruta a través de PgBouncer, que mantiene conexiones persistentes con tu motor de cómputo Postgres subyacente.
Ten cuidado con lo que la agrupación te aporta y lo que no, porque esto se suele explicar mal. El agrupador evita el agotamiento de las ranuras de conexión cuando muchas invocaciones de corta duración solicitan una conexión, que es precisamente el patrón serverless.
No oculta un arranque en frío (cold start) de escalado a cero: el agrupador reside en el motor de cómputo, así que cuando este se suspende, no hay una conexión de backend activa que ofrecer. La lista de mitigaciones de arranques en frío de Neon cubre configuraciones de escalado a cero, ubicación regional, tiempos de espera del cliente, reintentos y caché, pero la agrupación no está entre ellas.
Siempre uso la cadena agrupada para despliegues serverless. Usa la cadena de conexión directa sin agrupar solo para migraciones de esquema y pg_dump.
Copia la cadena de conexión completa. En el siguiente paso, añádela a Settings → Variables de Webflow Cloud y a tu .env.local local.
Cadena de conexión directa vs. agrupada
La cadena de conexión directa (sin -pooler) se conecta directamente al motor de cómputo de Postgres a través de WebSockets. Usa esta cadena para migraciones de esquema (e.g., drizzle-kit push o pg_dump) que requieran una conexión basada en sesión.
Nunca uses la cadena directa para consultas de aplicaciones serverless. Cada invocación de Worker crea una nueva conexión, y las conexiones directas consumen ranuras de conexión de Postgres.
Resultado esperado: Tienes la cadena de conexión agrupada copiada en el portapapeles. El nombre de host contiene -pooler, y la cadena incluye sslmode=require.
3. Instala el controlador y crea la fábrica de clientes de base de datos
El paquete @neondatabase/serverless es el controlador que funciona en el entorno de ejecución de Workers sin una capa de proxy intermedia, por eso esta guía lo utiliza. Instálalo como una dependencia de producción; reemplaza a pg en esta pila.
No es la única opción, y el motivo es importante. pg falla aquí porque el entorno de ejecución de Workers no le proporciona un socket TCP de Node para abrir, no por problemas con el ciclo de vida de la conexión. Si pones un proxy en el camino que termine el TCP por ti, pg funciona perfectamente: la propia guía de Cloudflare Workers de Neon recomienda Cloudflare Hyperdrive con un controlador nativo como pg como primera opción, y especifica usar un controlador nativo en lugar del controlador serverless cuando Hyperdrive está en juego.
Elige el controlador serverless si no quieres infraestructura adicional; elige Hyperdrive plus pg si prefieres mantener un controlador de Postgres estándar.
Instala @neondatabase/serverless:
npm install @neondatabase/serverless
Crea lib/db.ts con una función de fábrica que devuelva una neon() función de consulta:
// lib/db.ts
import { neon } from "@neondatabase/serverless";
export function getDb() {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("Missing DATABASE_URL environment variable");
}
return neon(databaseUrl);
}
La neon() función devuelve una función de consulta de plantilla etiquetada (sql) que envía consultas a través de HTTP. Cada llamada a getDb() crea una nueva sql función vinculada a la cadena de conexión.
Dado que Webflow Cloud inyecta variables de entorno por solicitud en el tiempo de ejecución de Workers, leer process.env.DATABASE_URL dentro de la función (en lugar de hacerlo durante la inicialización del módulo) garantiza que el valor esté disponible cuando se ejecute la función, y no cuando el módulo se carga por primera vez.
Añade DATABASE_URL a tu .env.local local:
DATABASE_URL=postgresql://username:password@ep-xxx-pooler.us-east-1.aws.neon.tech/dbname?sslmode=require&channel_binding=require
En el paso 5, añadirás la misma cadena a las variables de entorno de Webflow Cloud para el despliegue en producción.
Resultado esperado: lib/db.ts existe y exporta getDb(). DATABASE_URL está configurado en .env.local. Ejecutar npm run preview con una cadena de conexión válida consulta Neon sin errores.
Opcional: Añade Drizzle ORM para consultas con seguridad de tipos
Si prefieres consultas con seguridad de tipos y gestión de esquemas en lugar de SQL sin procesar, Drizzle ORM se integra directamente con @neondatabase/serverless a través del neon-http adaptador:
npm install drizzle-orm drizzle-kit
Actualiza lib/db.ts para que devuelva una instancia de Drizzle:
// lib/db.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
export function getDb() {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("Missing DATABASE_URL environment variable");
}
const sql = neon(databaseUrl);
return drizzle({ client: sql });
}
El drizzle-orm/neon-http adaptador envuelve la neon() función, ofreciéndote el constructor de consultas y la gestión de esquemas de Drizzle sobre el transporte HTTP. Todo lo demás en el artículo funciona igual: el patrón de fábrica, la variable de entorno y los pasos de despliegue.
4. Crea una tabla y ejecuta consultas desde componentes de servidor y manejadores de rutas
Crea tu primera tabla en el editor SQL de Neon y, a continuación, añade consultas de componentes de servidor y manejadores de rutas a tu aplicación Next.js. El controlador funciona de forma idéntica en los tres contextos de servidor de Next.js: componentes de servidor, manejadores de rutas y Server Actions.
Creación de una tabla en Neon
En la consola de Neon, abre el editor SQL de tu proyecto y crea una tabla con la que trabajar:
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
published BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW()
);
INSERT INTO posts (title, content, published)
VALUES
('First post', 'Hello from Neon and Webflow Cloud', true),
('Draft post', 'Not published yet', false);
Después de ejecutar esto, tendrás dos filas en la posts tabla para consultar en los siguientes pasos.
Consultas desde un componente de servidor
En un componente de servidor de Next.js, llama a getDb() y utiliza la sintaxis de plantilla etiquetada para ejecutar una consulta parametrizada:
// app/posts/page.tsx
import { getDb } from "@/lib/db";
type Post = {
id: number;
title: string;
content: string | null;
published: boolean;
created_at: string;
};
export default async function PostsPage() {
const sql = getDb();
// Note: the tagged template takes no type argument. `sql<Post[]>`
// is a TypeScript error, so assert on the result instead.
const posts = (await sql`
SELECT id, title, content, published, created_at
FROM posts
WHERE published = true
ORDER BY created_at DESC
`) as Post[];
return (
<main>
<h1>Posts</h1>
{posts.map((post) => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</main>
);
}
La sintaxis de plantilla etiquetada parametriza los valores automáticamente.
Las ${value} interpolaciones se convierten en $1, $2, etc., en la sentencia preparada. Esto evita la inyección SQL sin necesidad de un paso de escape independiente. Utilizo este patrón como predeterminado para todas las consultas de lectura en los componentes del servidor: sin la sobrecarga de un ORM, con SQL claro y total seguridad de tipos gracias al parámetro de tipo genérico.
El componente del servidor se renderiza en el momento de la solicitud en el entorno de ejecución Workers de Webflow Cloud. La consulta a Neon se envía como una solicitud HTTP desde la infraestructura de Cloudflare hasta el punto final HTTP de Neon.
Neon se ejecuta en regiones de nube específicas en lugar de junto a la red de Workers, que es precisamente la razón por la que la recomendación de latencia de Neon es alojar tu aplicación y tu base de datos en la misma región. Los números de ida y vuelta en el momento de la publicación caducan rápido, así que mide los tuyos en lugar de confiar en la cifra de un artículo.
Ejecución de mutaciones desde un gestor de rutas
Para operaciones de escritura (inserciones, actualizaciones, eliminaciones), utiliza gestores de rutas para que las mutaciones pasen por tu API en lugar de estar integradas en los componentes del servidor:
// app/api/posts/route.ts
import { getDb } from "@/lib/db";
import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest) {
const { title, content } = await request.json();
if (!title) {
return NextResponse.json({ error: "Title is required" }, { status: 400 });
}
const sql = getDb();
const [post] = await sql`
INSERT INTO posts (title, content, published)
VALUES (${title}, ${content ?? null}, false)
RETURNING id, title, created_at
`;
return NextResponse.json(post, { status: 201 });
}
export async function GET() {
const sql = getDb();
const posts = await sql`
SELECT id, title, content, published, created_at
FROM posts
ORDER BY created_at DESC
`;
return NextResponse.json(posts);
}
La RETURNING cláusula devuelve la fila recién creada en la misma consulta, evitando una segunda ida y vuelta para obtener el ID. La [post] desestructuración en el resultado toma la primera (y única) fila devuelta, el patrón estándar para inserciones de una sola fila.
Ejecución de transacciones a través de HTTP
Para transacciones de múltiples consultas (inserción + actualización en una operación atómica), la neon() función admite transacciones basadas en HTTP mediante el transaction() método:
const sql = getDb();
const [[newPost]] = await sql.transaction([
sql`INSERT INTO posts (title, content) VALUES (${"New post"}, ${"Content"}) RETURNING id`,
sql`UPDATE posts SET published = true WHERE id = (SELECT MAX(id) FROM posts)`,
]);
Las transacciones HTTP en Neon no son interactivas. Todas las consultas del lote se ejecutan en una sola ida y vuelta. Admiten niveles de aislamiento y modo de solo lectura como opciones en el segundo argumento. Para transacciones interactivas (donde el resultado de una consulta determina la siguiente), utiliza Pool/Client con WebSockets en su lugar.
Resultado esperado: Los componentes del servidor consultan y devuelven datos de Neon en /posts. Las solicitudes POST a /api/posts insertan filas y devuelven 201. La simulación de vista previa confirma que el controlador funciona en el entorno de ejecución de Workers antes de la implementación.
5. Implementar en Webflow Cloud y configurar la DATABASE_URL de producción
Antes de implementar, configura la DATABASE_URL en Configuración → Variables de tu proyecto de Webflow Cloud:
DATABASE_URL=postgresql://username:password@ep-xxx-pooler.us-east-1.aws.neon.tech/dbname?sslmode=require&channel_binding=require
Utiliza la cadena de conexión agrupada (con -pooler en el nombre de host) para producción, no la cadena de conexión directa. El .env.local valor nunca se implementa en Webflow Cloud; el panel de Configuración → Variables es el único lugar donde se leen las variables de producción.
Luego despliega:
webflow auth login
webflow cloud deploy
Después de la implementación, prueba una consulta a la base de datos desde la URL en vivo y revisa los registros de implementación de Webflow Cloud en busca de Missing DATABASE_URL o errores de conexión.
Resultado esperado: La URL en vivo devuelve datos de Neon. No aparecen errores de conexión en los registros de implementación. Se confirma la pila completa de extremo a extremo.
¿Qué causa que las conexiones de Neon Postgres fallen en Webflow Cloud?
La mayoría de los fallos de Neon en Webflow Cloud provienen de cuatro fuentes: una DATABASE_URL incorrecta o faltante, el uso de una cadena de conexión directa en lugar de una agrupada, tiempos de espera de arranque en frío en instancias inactivas de Neon y el uso accidental del paquete estándar <a href="https://www.npmjs.com/package/pg" target="_blank" rel="noopener noreferrer">pg</a> en lugar de @neondatabase/serverless.
Aquí tienes el diagnóstico para cada uno.
Las consultas fallan con "Missing DATABASE_URL" o devuelven datos indefinidos
Causa: La DATABASE_URL variable de entorno existe en .env.local, pero no se agregó a Configuración → Variables de Webflow Cloud. En Webflow Cloud, las variables en .env.local son de solo lectura al ejecutar npm run dev o npm run preview localmente. Nunca se implementan en el trabajador de producción.
Solución: En tu proyecto de Webflow Cloud, abre Configuración → Variables y agrega DATABASE_URL con la cadena de conexión agrupada completa, incluyendo sslmode=require. Vuelve a implementar después de guardar. La cláusula de protección en getDb() (la if (!databaseUrl) throw new Error(...) verificación) muestra esto como un error claro en los registros de implementación en lugar de una referencia nula silenciosa más adelante.
La primera solicitud tras un periodo de inactividad es notablemente lenta
Causa: El proceso de cómputo de Neon se reduce a cero; la suspensión automática se activa tras 5 minutos de inactividad por defecto en los planes Free y Launch (los planes Scale permiten configurar esto o desactivarlo por completo). La primera consulta debe esperar a que el proceso se reactive antes de ejecutarse. Esto es un arranque en frío de Neon, no un problema de Webflow Cloud.
Solución: Esto es el escalado a cero, y Neon documenta que la reactivación toma "unos pocos cientos de milisegundos", no segundos. El pooling no ayudará, por la razón dada en el paso 2. Lo que sí ayuda es uno de los enfoques documentados de Neon: ajustar o desactivar el ajuste de escalado a cero en un plan de pago, alojar la aplicación y la base de datos en la misma región, implementar gestión de reintentos en el cliente o usar caché a nivel de aplicación.
Ten en cuenta que connect_timeout es un parámetro de libpq y no hace nada para el controlador HTTP, que emite llamadas fetch sin fase de conexión libpq. Si quieres limitar una consulta HTTP, pasa una señal AbortController a través de fetchOptions en su lugar:
const controller = new AbortController()
setTimeout(() => controller.abort(), 10_000)
const sql = neon(process.env.DATABASE_URL!, {
fetchOptions: { signal: controller.signal },
})
Esto evita errores de tiempo de espera prematuros durante el ciclo de reactivación del cómputo. Si tu caso de uso requiere una latencia constante de menos de 100 ms en la primera consulta, actualiza a un plan de Neon con mayor capacidad de cómputo o desactiva la suspensión automática.
Las consultas fallan con "connection refused" o error de SSL
Causa: Una de estas tres cosas: la cadena de conexión está mal formada (falta sslmode=require), estás usando la cadena de conexión directa donde debería usarse la cadena agrupada (pooled), o el parámetro channel_binding=require está causando un conflicto con una versión antigua del controlador.
Solución: Confirma que la DATABASE_URL en Ajustes → Variables es la cadena de conexión agrupada (el nombre de host contiene -pooler). Confirma que incluye sslmode=require.
Si sigues recibiendo errores de SSL, elimina channel_binding=require y prueba solo con sslmode=require. Algunas combinaciones de entorno y versiones de controlador gestionan la negociación de enlace de forma distinta.
La aplicación funciona localmente pero falla tras el despliegue con un error del controlador
Causa: Se instaló el paquete estándar pg en lugar de @neondatabase/serverless, o la aplicación tiene una ruta de importación alternativa que llega a pg. El pg estándar abre conexiones TCP persistentes que esperan sobrevivir a múltiples consultas.
En el entorno de ejecución de Cloudflare Workers, cada solicitud se ejecuta en un contexto nuevo. No existe un grupo de conexiones persistentes entre invocaciones. La conexión `pg` abierta al inicio de un manejador se termina cuando este finaliza, dejando estados de transacción pendientes y causando errores en solicitudes posteriores.
Solución: Confirma que @neondatabase/serverless es el único cliente de Postgres en package.json. Busca cualquier require('pg') o import { Pool } from 'pg' en tu código y reemplázalo con importaciones de @neondatabase/serverless.
Si usas un ORM, confirma que está configurado con el adaptador neon-http o neon-serverless, no con el adaptador genérico pg.
Las transacciones fallan silenciosamente o devuelven resultados incorrectos
Causa: Uso de la función HTTP neon() para transacciones interactivas, donde el resultado de una consulta determina los parámetros de la siguiente. Las transacciones HTTP mediante sql.transaction([]) no son interactivas: todas las consultas se envían en un solo viaje de ida y vuelta.
Si la lógica de tu transacción requiere leer de una consulta antes de escribir con otra, el modelo de transacción HTTP no puede expresarlo correctamente.
Solución: Para transacciones interactivas, usa Pool o Client de @neondatabase/serverless con transporte WebSocket.
Crea y cierra la conexión dentro del mismo manejador de solicitudes:
import { Pool } from "@neondatabase/serverless";
export async function POST(request: NextRequest) {
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
try {
const client = await pool.connect();
await client.query("BEGIN");
const { rows } = await client.query("SELECT balance FROM accounts WHERE id = $1 FOR UPDATE", [userId]);
await client.query("UPDATE accounts SET balance = $1 WHERE id = $2", [rows[0].balance - amount, userId]);
await client.query("COMMIT");
await client.query('COMMIT');
return NextResponse.json({ success: true });
} catch (err) {
await client.query('ROLLBACK');
return NextResponse.json({ error: 'Transaction failed' }, { status: 500 });
} finally {
// release() returns the client to the pool; it does NOT close the
// pool. On Workers the WebSocket cannot outlive the request, so
// the pool itself has to be closed too, on every path.
client.release();
await pool.end();
}
}
Sé preciso con estas dos llamadas, porque tratarlas como intercambiables es lo que provoca fugas de conexiones. client.release() devuelve el cliente al grupo. pool.end() cierra el grupo y su WebSocket.
En el entorno de ejecución de Workers, debes crear, usar y cerrar un Pool o Client dentro de un mismo controlador de solicitudes, por lo que necesitas ambos en un finally bloque para asegurar que también se ejecuten en la ruta de error. También es importante revertir los cambios antes de liberar: devolver un cliente al pool a mitad de una transacción es la forma en que el estado se filtra a la siguiente solicitud.
Sigue construyendo sobre tu base de Neon + Webflow Cloud
Esta guía cubrió la conexión completa a la base de datos: @neondatabase/serverless con transporte HTTP, la cadena de conexión con pool, el patrón de función de fábrica para la inyección de variables en tiempo de ejecución de Webflow Cloud, y cómo realizar consultas desde componentes de servidor y controladores de rutas.
Para combinar Neon con funciones de IA, la extensión pgvector permite realizar búsquedas de similitud nativas en tu base de datos Neon. Almacena embeddings como vectores y ejecuta consultas de búsqueda semántica junto a tus consultas habituales de Postgres.
Explora Webflow + Neon para ver casos de uso adicionales, incluyendo pgvector para búsqueda con IA, pipelines de SEO programático y filtrado de datos financieros.
Preguntas frecuentes
¿Cómo gestiono las migraciones de esquema de base de datos con Neon en Webflow Cloud?
Ejecuta las migraciones desde tu máquina local usando la cadena de conexión directa, no desde Webflow Cloud. Configura una DATABASE_MIGRATION_URL separada en .env.local que apunte a la cadena directa. Ejecuta drizzle-kit push o tu comando de migración preferido localmente antes de desplegar. Los cambios de esquema surten efecto inmediatamente en Neon, y los workers desplegados verán el esquema actualizado en su siguiente solicitud.
¿Puedo usar Drizzle ORM o Prisma en lugar de SQL puro?
Drizzle ORM funciona directamente con @neondatabase/serverless a través de drizzle-orm/neon-http. Configura lib/db.ts para usar drizzle({ client: sql }) como se muestra en el Paso 3. Ambos funcionan. La configuración actual documentada de Prisma para Neon es el adaptador de controlador @prisma/adapter-neon , que ejecuta Prisma sobre @neondatabase/serverless sin Data Proxy ni Accelerate. El Data Proxy está retirado, por lo que el antiguo argumento de que "Prisma necesita un proxy" ya no sirve para diferenciarlos. Elige según tu comodidad: Drizzle es más ligero y cercano a SQL; Prisma aporta su propio esquema y herramientas de migración.
¿Cuál es el impacto en el rendimiento de la suspensión automática de Neon en Webflow Cloud?
El escalado a cero se activa tras 5 minutos de inactividad en los planes Free y Launch, y Neon documenta que la reactivación toma unos pocos cientos de milisegundos en lugar de segundos. Los planes de pago pueden desactivar el escalado a cero por completo, incluido el plan Launch; configurar el umbral es una función del plan Scale. Las mitigaciones efectivas son la colocación en la misma región, el manejo de reintentos y el almacenamiento en caché de la aplicación, no el pooling de conexiones.
¿Puedo usar la función de ramificación (branching) de Neon con despliegues de Webflow Cloud?
Sí. Las ramas de Neon proporcionan copias aisladas de la base de datos que comparten el almacenamiento principal. Apunta la DATABASE_URL de cada entorno de Webflow Cloud a su cadena de conexión de rama. Como Neon no tiene una operación de fusión (merge) al padre, confía en el restablecimiento desde el padre, la restauración instantánea o las consultas de "viaje en el tiempo" en lugar de fusionar. Normalmente, ejecutas las migraciones por rama y restableces desde el padre para empezar de cero, logrando un aislamiento total por despliegue sin duplicar datos. Copia cada cadena de conexión desde el modal de conexión de la consola de Neon.





