Cómo crear una aplicación generadora de facturas en Webflow Cloud con Next.js y SQLite

Cómo crear una aplicación generadora de facturas en Webflow Cloud con Next.js y SQLite

Aprende a crear una aplicación generadora de facturas en Webflow Cloud con un proyecto de Next.js, una base de datos SQLite y generación de PDF compatible con el edge mediante pdf-lib.

Cómo crear una aplicación generadora de facturas en Webflow Cloud con Next.js y SQLite

Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Índice de contenidos

Puedes generar, almacenar y descargar un PDF de factura finalizado desde tu sitio de Webflow sin necesidad de configurar un backend independiente.

Generar un PDF de factura con tu propia marca a partir de tus datos suele requerir la configuración de un servidor independiente, ya que Webflow no ejecuta lógica de backend por sí solo. Webflow Cloud cierra esa brecha: despliegas una aplicación Next.js en la misma infraestructura que tu sitio, almacenas los registros de las facturas en una base de datos SQLite y renderizas el PDF en el edge, todo ello sin necesidad de un servicio de impresión externo.

Como la aplicación se ejecuta en el mismo origen que tu sitio de Webflow, el navegador realiza una llamada a una ruta relativa, por lo que no hay que configurar ninguna solicitud de origen cruzado.

En esta guía, crearemos todo el flujo: un esquema para las facturas y sus partidas, una ruta que las cree y las enumere, y un gestor de PDF que convierta una factura almacenada en un archivo descargable.

¿Qué necesitas para crear una aplicación generadora de facturas en Webflow Cloud?

Necesitas una aplicación de Webflow Cloud que ejecute Next.js 15 o superior, un enlace a una base de datos SQLite para los registros y una biblioteca de PDF de JavaScript puro que se ejecute en el edge. Nada de esto requiere un host de backend independiente.

Aquí tienes la lista completa antes de escribir una sola línea de código:

  • Un sitio de Webflow en cualquier plan de pago, con Webflow Cloud disponible en la configuración del sitio
  • Una cuenta de GitHub, ya que Webflow Cloud se despliega desde un repositorio conectado
  • Una aplicación Next.js 15+ (la plantilla de inicio de Next.js para Webflow Cloud es la forma más rápida de empezar)
  • Node.js 22.0.0 o superior y npm instalados localmente (npm es el único gestor de paquetes compatible)
  • drizzle-orm para consultas, además de drizzle-kit, tsx, y better-sqlite3 como dependencias de desarrollo para el esquema y las migraciones locales
  • , and pdf-lib para generar el PDF de la factura en el entorno de ejecución de Workers

La única elección que merece la pena hacer con cuidado es la biblioteca de PDF. Yo uso <a href="https://pdf-lib.js.org/" target="_blank" rel="noopener noreferrer">pdf-lib</a> porque es JavaScript puro y se ejecuta dentro del entorno de ejecución de Workers sin binarios nativos, que es exactamente lo que necesita el entorno edge.

Bibliotecas como PDFKit dependen de los flujos de Node.js y del sistema de archivos, y eso falla en Webflow Cloud. Con los requisitos previos listos, la construcción se divide en siete pasos.

7 pasos para crear una aplicación generadora de facturas en Webflow Cloud

El flujo tiene la misma forma que cualquier pequeña aplicación CRUD, con una adición. Preparas y configuras el proyecto, añades una base de datos y un esquema, escribes los gestores de rutas que crean y listan las facturas, añades un gestor que renderiza un PDF, creas el formulario y despliegas. La ruta del PDF es la única pieza exclusiva de la facturación, y es la que más se ve afectada por el entorno de ejecución edge.

Cada paso a continuación se basa en el anterior, así que síguelos en orden en lugar de saltar directamente al gestor de PDF.

1. Crea y configura un proyecto de Next.js en Webflow Cloud

Inicia el proyecto desde la plantilla de inicio de Next.js en el asistente de despliegue de Webflow Cloud, que clona un repositorio listo para desplegar en tu cuenta de GitHub y configura el primer entorno. Abre el asistente desde tu panel de control de Webflow, conecta GitHub, elige la plantilla de inicio de Next.js y selecciona una ruta de montaje como cuando la adjuntes a un sitio existente./app

Clona el nuevo repositorio localmente y abre .next.config.ts

La plantilla de inicio establece y en tu ruta de montaje, y deben coincidir exactamente:basePathassetPrefix

// next.config.ts
module.exports = {
  basePath: '/app',
  assetPrefix: '/app',
}

Esta configuración es la que permite que cada recurso y ruta de API se resuelva correctamente una vez que la aplicación se sirve desde en lugar de la raíz del dominio. La plantilla también incluye , , y , por lo que no tienes que montar la configuración de OpenNext y Wrangler manualmente.yourdomain.com/appwebflow.jsonopen-next.config.tswrangler.json

Ejecuta , luego confirma que la aplicación se compile localmente antes de añadirle nada.npm install

2. Añade una base de datos SQLite y define el esquema de facturas

Añade un enlace a una base de datos SQLite en para que Webflow Cloud proporcione una base de datos para la aplicación.wrangler.json

Decláralo en el array , y deja el como marcador de posición, ya que Webflow Cloud genera el valor real en tu primer despliegue:d1_databasesdatabase_id

"d1_databases": [
  {
    "binding": "DB",
    "database_name": "invoices_db",
    "database_id": "placeholder",
    "migrations_dir": "drizzle"
  }
]

El valor de , , es el nombre de la variable que usas para acceder a la base de datos en el código, así que mantenlo consistente con el asistente en el siguiente paso.bindingDB

Con el enlace declarado, instala Drizzle y sus herramientas de migración local con y , luego define las tablas.npm i drizzle-ormnpm i -D drizzle-kit tsx better-sqlite3

Una factura consta de dos registros relacionados: el encabezado de la factura y sus partidas, por lo que el esquema utiliza dos tablas:

// src/db/schema/index.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'

export const invoices = sqliteTable('invoices', {
  id: integer().primaryKey({ autoIncrement: true }),
  number: text().notNull().unique(),
  clientName: text('client_name').notNull(),
  clientEmail: text('client_email').notNull(),
  status: text().notNull().default('draft'),
  currency: text().notNull().default('USD'),
  issuedAt: text('issued_at').notNull(),
  dueAt: text('due_at'),
  createdAt: text('created_at').notNull(),
})

export const invoiceItems = sqliteTable('invoice_items', {
  id: integer().primaryKey({ autoIncrement: true }),
  invoiceId: integer('invoice_id')
    .notNull()
    .references(() => invoices.id),
  description: text().notNull(),
  quantity: integer().notNull(),
  unitAmount: integer('unit_amount').notNull(),
})

El detalle que nunca paso por alto es almacenar el dinero como centavos enteros en , no como un valor de punto flotante. La primera herramienta de facturación que construí usaba flotantes, y el redondeo se desviaba un centavo con la frecuencia suficiente como para que un cliente lo señalara. Los enteros eliminan toda esa clase de errores.unitAmount

Genera y aplica la migración usando y ; la base de datos local está lista.npm run db:generatenpm run db:apply:local

3. Crea un asistente de base de datos para tus manejadores de rutas

Centraliza la conexión a la base de datos en un asistente para que cada manejador de rutas acceda a la misma instancia de Drizzle con el esquema adjunto.

En Webflow Cloud, el enlace reside en el contexto de Cloudflare en lugar de , por lo que lo lees a través de desde el adaptador de OpenNext:process.envgetCloudflareContext

// src/db/getDb.ts
import { drizzle } from 'drizzle-orm/d1'
import { getCloudflareContext } from '@opennextjs/cloudflare'
import * as schema from './schema'

export function getDb() {
  const { env } = getCloudflareContext()
  return drizzle(env.DB, { schema })
}

La referencia se resuelve en el mismo enlace que nombraste en , y pasar proporciona a Drizzle las tablas tipadas para que las consultas mantengan la seguridad de tipos. Ejecuta una vez para generar el archivo de modo que TypeScript sepa que el enlace existe en el entorno de Cloudflare.env.DBDBwrangler.json{ schema }wrangler typesworker-configuration.d.tsDB

En una aplicación de Next.js, actualiza también los tipos en para que coincidan, o TypeScript marcará el enlace como desconocido aunque funcione en tiempo de ejecución.cloudflare-env.d.ts

Mantengo este asistente pequeño a propósito porque cada ruta lo importa, y cualquier lógica añadida aquí se ejecuta en cada solicitud. Con la conexión establecida, los manejadores pueden empezar a escribir y leer facturas.

4. Crea el Route Handler para la generación de facturas

Añade un Route Handler que acepte el payload de una factura, escriba el encabezado y luego sus partidas.

Crea src/app/api/invoices/route.ts y márcalo para el edge runtime, algo necesario para las rutas de API de Next.js en Webflow Cloud:

// src/app/api/invoices/route.ts
export const runtime = 'edge'

import { NextResponse, type NextRequest } from 'next/server'
import { getDb } from '@/db/getDb'
import { invoices, invoiceItems } from '@/db/schema'

type LineItem = { description: string; quantity: number; unitAmount: number }
type CreateInvoiceBody = {
  clientName: string
  clientEmail: string
  currency?: string
  dueAt?: string
  items: LineItem[]
}

export async function POST(request: NextRequest) {
  const body = (await request.json()) as CreateInvoiceBody

  if (!body.clientName || !body.items?.length) {
    return NextResponse.json(
      { error: 'A client name and at least one line item are required' },
      { status: 400 }
    )
  }

  const db = getDb()
  const now = new Date().toISOString()
  const number = `INV-${now.slice(0, 10).replace(/-/g, '')}-${Math.floor(1000 + Math.random() * 9000)}`

  const [invoice] = await db
    .insert(invoices)
    .values({
      number,
      clientName: body.clientName,
      clientEmail: body.clientEmail,
      currency: body.currency ?? 'USD',
      issuedAt: now,
      dueAt: body.dueAt ?? null,
      createdAt: now,
    })
    .returning()

  await db.insert(invoiceItems).values(
    body.items.map((item) => ({
      invoiceId: invoice.id,
      description: item.description,
      quantity: item.quantity,
      unitAmount: item.unitAmount,
    }))
  )

  return NextResponse.json({ id: invoice.id, number: invoice.number }, { status: 201 })
}

El manejador valida primero el payload y luego genera un número de factura legible combinando la fecha con un sufijo aleatorio para evitar colisiones si se crean dos facturas el mismo día. La llamada devuelve la fila insertada, incluyendo el .returning()id autoincremental, que el segundo insert utiliza como clave foránea para cada partida.

La respuesta se mantiene deliberadamente mínima, devolviendo solo el y idnumber que el cliente necesita para obtener el PDF después.

5. Lista las facturas con un manejador GET

Añade un endpoint de lectura para que la aplicación pueda mostrar facturas anteriores y puedas confirmar que los registros se están guardando.

Extiende el mismo archivo con una exportación route.tsGET que devuelva las facturas empezando por la más reciente:

// src/app/api/invoices/route.ts (continued)
import { desc } from 'drizzle-orm'

export async function GET() {
  const db = getDb()
  const rows = await db.select().from(invoices).orderBy(desc(invoices.createdAt))
  return NextResponse.json(rows)
}

Como Next.js asigna cada método HTTP del archivo a su exportación correspondiente, este convive con el del paso anterior y comparte el mismo ayudante y la misma declaración GETPOSTgetDbexport const runtime = 'edge' al principio del archivo.

La consulta devuelve solo los encabezados de las facturas, no las partidas, lo que mantiene la respuesta de la lista ligera. Cuando necesites ver las partidas de una factura específica, recupéralas en una ruta dedicada mediante invoiceId. Llegados a este punto, ya puedes crear y listar facturas, así que el siguiente paso es convertir un registro almacenado en un documento.

6. Genera el PDF de la factura en el edge con pdf-lib

Añade un Route Handler dinámico que cargue una factura con sus partidas y genere un PDF en memoria.

Instala la librería con , luego crea npm install pdf-libsrc/app/api/invoices/[id]/pdf/route.ts:

// src/app/api/invoices/[id]/pdf/route.ts
export const runtime = 'edge'

import { type NextRequest } from 'next/server'
import { eq } from 'drizzle-orm'
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
import { getDb } from '@/db/getDb'
import { invoices, invoiceItems } from '@/db/schema'

export async function GET(
  _request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params
  const db = getDb()

  const [invoice] = await db.select().from(invoices).where(eq(invoices.id, Number(id)))
  if (!invoice) return new Response('Invoice not found', { status: 404 })

  const items = await db
    .select()
    .from(invoiceItems)
    .where(eq(invoiceItems.invoiceId, invoice.id))

  const pdf = await PDFDocument.create()
  const page = pdf.addPage([595, 842]) // A4 in points
  const font = await pdf.embedFont(StandardFonts.Helvetica)
  const bold = await pdf.embedFont(StandardFonts.HelveticaBold)

  const money = (cents: number) =>
    new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: invoice.currency,
    }).format(cents / 100)

  page.drawText('INVOICE', { x: 50, y: 780, size: 24, font: bold })
  page.drawText(invoice.number, { x: 50, y: 758, size: 12, font })
  page.drawText(`Bill to: ${invoice.clientName}`, { x: 50, y: 720, size: 12, font })

  let y = 670
  page.drawText('Description', { x: 50, y, size: 11, font: bold })
  page.drawText('Qty', { x: 360, y, size: 11, font: bold })
  page.drawText('Amount', { x: 470, y, size: 11, font: bold })
  page.drawLine({
    start: { x: 50, y: y - 6 },
    end: { x: 545, y: y - 6 },
    thickness: 1,
    color: rgb(0.8, 0.8, 0.8),
  })

  let total = 0
  for (const item of items) {
    y -= 24
    const lineTotal = item.quantity * item.unitAmount
    total += lineTotal
    page.drawText(item.description, { x: 50, y, size: 11, font })
    page.drawText(String(item.quantity), { x: 360, y, size: 11, font })
    page.drawText(money(lineTotal), { x: 470, y, size: 11, font })
  }

  page.drawText('Total', { x: 360, y: y - 30, size: 12, font: bold })
  page.drawText(money(total), { x: 470, y: y - 30, size: 12, font: bold })

  const bytes = await pdf.save()

  return new Response(bytes, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${invoice.number}.pdf"`,
    },
  })
}

El manejador lee la factura y sus elementos, y luego construye el documento completamente en memoria, lo cual es ideal para el runtime de Workers ya que no hay un sistema de archivos donde escribir. Ten en cuenta que params se espera con await, ya que Next.js 15 hizo que los parámetros de ruta dinámica sean asíncronos.

Calculo el total de cada línea y el total general a partir de los céntimos enteros y solo aplico el formato de moneda al dibujar con , para que los cálculos nunca toquen números decimales. devuelve un , que el acepta directamente, y los encabezados y Intl.NumberFormatpdf.save()Uint8ArrayResponseContent-TypeContent-Disposition le indican al navegador que lo descargue como un archivo con nombre.

Al acceder a /app/api/invoices/1/pdf ahora se obtiene una factura terminada.

7. Crea el formulario de facturas y despliega

Añade un formulario como Client Component para que el usuario pueda introducir las partidas en lugar de enviar JSON manualmente, y luego despliega. La única regla que suele confundir es la ruta de fetch: las llamadas desde el lado del cliente deben incluir la ruta de montaje, porque un /api/invoices simple apunta a la raíz del dominio, no a tu aplicación:

// src/app/components/InvoiceForm.tsx
'use client'

import { useState } from 'react'

const BASE_PATH = '/app' // must match your Webflow Cloud mount path

export function InvoiceForm() {
  const [clientName, setClientName] = useState('')
  const [clientEmail, setClientEmail] = useState('')
  const [items, setItems] = useState([{ description: '', quantity: 1, unitAmount: 0 }])

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    const res = await fetch(`${BASE_PATH}/api/invoices`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clientName, clientEmail, items }),
    })
    const { id } = await res.json()
    window.location.href = `${BASE_PATH}/api/invoices/${id}/pdf`
  }

  // ... inputs that update clientName, clientEmail, and items ...
  return <form onSubmit={handleSubmit}>{/* fields and a submit button */}</form>
}

El formulario envía la factura, lee el devuelto y redirige al navegador directamente a la ruta del PDF, para que un solo envío genere una factura descargable. Captura los idunitAmount en céntimos en los campos de entrada, o multiplícalos por 100 antes de enviarlos, para que coincidan con el esquema.

Para publicar, haz commit y push a la rama de GitHub conectada, o ejecuta seguido de webflow auth loginwebflow cloud deploy. Webflow Cloud aplica la migración de la base de datos automáticamente al desplegar, y la aplicación estará disponible en tu dominio más la ruta de montaje en unos dos minutos.

¿Qué es lo que hace que una aplicación generadora de facturas falle en Webflow Cloud?

La mayoría de los fallos se deben al entorno de ejecución (edge runtime) o a la ruta de montaje: una API de Node.js que el entorno de ejecución de Workers no admite, una petición fetch que olvidó la ruta base, una migración que nunca se ejecutó en producción o cálculos monetarios realizados con números de punto flotante. Cada uno produce un síntoma reconocible y tiene una solución directa.

La siguiente lista relaciona el síntoma que verás con su causa, empezando por el fallo durante el despliegue que más suele confundir a los usuarios.

La aplicación desplegada devuelve un error 500, pero funciona localmente

La ausencia de una export const runtime = 'edge' directiva en un Route Handler suele hacer que la compilación falle directamente en lugar de desplegarse y fallar después. Si la compilación tiene éxito pero una ruta da error 500 solo en producción, la causa más probable es que un paquete esté intentando acceder a una API de Node.js que el entorno de ejecución de Workers no admite.

El entorno de ejecución de Workers admite muchos módulos de Node a través de nodejs_compat, incluidos Buffer y crypto, pero no tiene sistema de archivos, por lo que cualquier intento de acceder a fs o path fallará.

Revisa los registros de compilación en el panel de control de Webflow Cloud buscando un mensaje como Could not resolve 'fs', y luego sustituye la librería problemática por una compatible con el entorno edge. Esta es precisamente la razón por la que la guía utiliza pdf-lib en lugar de una librería de PDF basada en streams de Node.

Las peticiones del lado del cliente devuelven un error 404 en producción

A la ruta de la petición fetch le falta el prefijo de la ruta de montaje. En Next.js sobre Webflow Cloud, tus rutas de API se sirven bajo la ruta base, por lo que un componente de cliente que llame a /api/invoices accede a la raíz del dominio y no encuentra tu aplicación.

Añade el prefijo de la ruta de montaje a cada petición fetch del cliente, tal como hace el formulario con ${BASE_PATH}/api/invoices. Las definiciones de rutas del lado del servidor se montan automáticamente y no necesitan el prefijo, razón por la cual esto solo aparece en las llamadas del navegador y nunca en los registros del servidor local.

Una consulta falla con el error "no such table: invoices"

La migración se ejecutó localmente pero no en la base de datos desplegada. El desarrollo local aplica las migraciones a través de npm run db:apply:local, que solo afecta al archivo SQLite local.

Webflow Cloud aplica las migraciones desde tu directorio drizzle al desplegar, así que la solución es generar la migración con npm run db:generate, confirmar los archivos generados en drizzle, y hacer push.

Si los archivos de migración no se confirman, la base de datos de producción nunca recibe el esquema y cualquier consulta a una tabla inexistente arrojará un error.

Los totales del PDF fallan por un céntimo

Los importes se están almacenando o sumando como dólares en punto flotante. JavaScript no puede representar valores como 0.1 con total exactitud, por lo que sumar varias partidas genera desviaciones. Almacena cada importe como céntimos enteros en la base de datos, suma los enteros y divide por 100 solo en el momento de formatear con Intl.NumberFormat.

Si las filas existentes ya contienen dólares en punto flotante, migralas multiplicando por 100 y redondeando una vez, y luego cambia la columna para que admita enteros de ahora en adelante.

Amplía tu generador de facturas en Webflow Cloud

Hasta ahora, la aplicación crea, almacena y renderiza facturas, lo cual constituye el ciclo principal. Las extensiones naturales la convierten de un simple generador en un flujo de trabajo de facturación, y cada una encaja en un Route Handler que ya conoces.

La incorporación más solicitada es el pago. Una vez que existe una factura, puedes configurar Stripe Checkout en Webflow y marcar la factura como paid desde un webhook, o seguir el patrón de esta guía para crear una aplicación full-stack en Webflow Cloud con Supabase, Auth0 y Stripe cuando necesites gestionar cuentas y pagos a la vez.

Para enviar facturas en lugar de depender de descargas manuales, puedesenviar correos electrónicos de confirmación de pedido desde Webflow usando SendGrid.

Si los clientes necesitan ver sus propias facturas, protege las rutas añadiendo autenticación Auth0 a un sitio de Webflow en lugar de ocultar el contenido en el navegador, y supervisa la aplicación en vivo con el seguimiento de errores de Sentry en una aplicación de Webflow Cloud.

Cuando estés listo para obtener una visión general de los saldos pendientes, el enfoque detrás de un panel de control en tiempo real con Supabase y Webflow se adapta perfectamente a los datos de facturación.

Preguntas frecuentes

¿Puede Webflow Cloud generar archivos PDF sin un servicio externo?

Sí. Una biblioteca de JavaScript puro como pdf-lib se ejecuta dentro del entorno de ejecución de Cloudflare Workers que impulsa Webflow Cloud, creando el documento en la memoria y devolviendo los bytes desde un gestor de rutas. No se requiere ninguna API de impresión externa ni un navegador sin interfaz para documentos estructurados como las facturas.

¿Por qué usar SQLite en lugar de una base de datos externa?

SQLite viene como una opción de almacenamiento nativa de Webflow Cloud, por lo que puedes añadirlo con un enlace en wrangler.json sin necesidad de alojamiento adicional. Drizzle ORM proporciona consultas tipadas. Opta por Neon o Supabase solo cuando necesites acceso compartido a Postgres entre sistemas.

¿Tengo que configurar el entorno de ejecución como "edge" en cada ruta de la API?

Sí, para aplicaciones Next.js en Webflow Cloud. Añade export const runtime = 'edge' al principio de cada gestor de rutas. Webflow Cloud se despliega en el entorno de ejecución "edge" de Workers, y las rutas sin esta directiva no se compilarán correctamente, lo que suele resultar en un error 500 en producción.

¿Por qué mis llamadas fetch del lado del cliente necesitan la ruta de montaje?

Porque la aplicación se sirve desde una ruta de montaje como /app, no desde la raíz del dominio. Next.js monta automáticamente tus rutas de API bajo esa ruta base, pero las llamadas fetch del navegador no lo saben, por lo que una llamada a /api/invoices no encontrará la aplicación. Antepón la ruta de montaje a las llamadas fetch del cliente.

¿Qué tamaño puede alcanzar un PDF de factura en Webflow Cloud?

Lo suficientemente grande para facturar. Un Worker tiene 128 MB de memoria y 30 segundos de tiempo de CPU por solicitud, mientras que pdf-lib mantiene todo el documento en la memoria. Una factura de varias páginas ocupa decenas de kilobytes, por lo que estarás muy lejos de esos límites incluso al generar muchas a la vez.

¿Puedo almacenar los PDF generados en lugar de renderizarlos cada vez?

Sí. Añade un bucket de almacenamiento de objetos de Webflow Cloud y escribe allí los bytes generados, identificados por el número de factura. Renderizar bajo demanda es más sencillo y mantiene una única fuente de verdad en la base de datos, así que guarda copias solo cuando necesites un archivo inmutable o descargas repetidas más rápidas.


Última actualización
July 25, 2026
Categoría

Artículos relacionados

Cómo configurar Stripe Checkout en Webflow usando enlaces de pago o el botón de compra
Cómo configurar Stripe Checkout en Webflow usando enlaces de pago o el botón de compra

Cómo configurar Stripe Checkout en Webflow usando enlaces de pago o el botón de compra

Cómo configurar Stripe Checkout en Webflow usando enlaces de pago o el botón de compra

Desarrollo
Por
Colin Lateano
,
,
Leer artículo
Cómo enviar correos electrónicos transaccionales y SMS desde Webflow Cloud (SendGrid + Twilio + Postmark)
Cómo enviar correos electrónicos transaccionales y SMS desde Webflow Cloud (SendGrid + Twilio + Postmark)

Cómo enviar correos electrónicos transaccionales y SMS desde Webflow Cloud (SendGrid + Twilio + Postmark)

Cómo enviar correos electrónicos transaccionales y SMS desde Webflow Cloud (SendGrid + Twilio + Postmark)

Desarrollo
Por
Colin Lateano
,
,
Leer artículo
La guía definitiva para sincronizar pedidos de Webflow con Airtable mediante Zapier
La guía definitiva para sincronizar pedidos de Webflow con Airtable mediante Zapier

La guía definitiva para sincronizar pedidos de Webflow con Airtable mediante Zapier

La guía definitiva para sincronizar pedidos de Webflow con Airtable mediante Zapier

Desarrollo
Por
Colin Lateano
,
,
Leer artículo
Cómo enviar formularios de Webflow a HubSpot mediante Zapier sin perder datos
Cómo enviar formularios de Webflow a HubSpot mediante Zapier sin perder datos

Cómo enviar formularios de Webflow a HubSpot mediante Zapier sin perder datos

Cómo enviar formularios de Webflow a HubSpot mediante Zapier sin perder datos

Desarrollo
Por
Colin Lateano
,
,
Leer artículo

verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Empieza gratis

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.

Empieza, es gratis
Ver demostración

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.