Skip to main content
RapidDev - Software Development Agency
weweb-tutorial

WeWeb Webhooks: Outgoing Requests, Automation, and Realtime Data

WeWeb can send outgoing webhooks to any URL using the REST API Request workflow action. It cannot receive incoming webhooks directly — WeWeb is a frontend SPA with no server. For realtime data from external systems, use Supabase Realtime subscriptions or Xano Realtime as your backend intermediary. WeWeb's built-in After Deploy Hook fires automatically after every publish.

What you'll learn

  • How to send outgoing HTTP webhooks from WeWeb workflows using the REST API Request action
  • How to structure JSON payloads with dynamic data from WeWeb variables and form inputs
  • Why WeWeb cannot receive incoming webhooks and what the architectural limitations are
  • How to use Supabase Realtime as a backend intermediary to receive webhook data in WeWeb
  • How to configure WeWeb's built-in After Deploy Hook to trigger external systems on publish
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced11 min read30-45 minWeWeb Free plan and above; backend service required for incoming webhook handlingMarch 2026RapidDev Engineering Team
TL;DR

WeWeb can send outgoing webhooks to any URL using the REST API Request workflow action. It cannot receive incoming webhooks directly — WeWeb is a frontend SPA with no server. For realtime data from external systems, use Supabase Realtime subscriptions or Xano Realtime as your backend intermediary. WeWeb's built-in After Deploy Hook fires automatically after every publish.

Outgoing Webhooks and Realtime Data in WeWeb

WeWeb is a Vue.js single-page application running entirely in the user's browser. This means it can make outgoing HTTP requests to any URL, but it cannot receive incoming HTTP requests — there is no server to receive a POST from Stripe, Zapier, or any other system. This architectural reality shapes everything about how webhooks work in WeWeb. This tutorial covers sending outgoing webhooks from workflow actions, building dynamic JSON payloads, handling webhook responses, working around the incoming webhook limitation using Supabase Realtime or polling, and using WeWeb's native After Deploy Hook for CI/CD automation.

Prerequisites

  • A WeWeb project with at least one workflow set up
  • A REST API data source plugin installed (Plugins → Data sources → REST API)
  • An external service to receive webhooks (Zapier Catch Hook, Make Custom Webhook, n8n, or your own endpoint) for testing
  • Optional: A Supabase project connected to WeWeb for the realtime workaround section

Step-by-step guide

1

Add a REST API Request action to a workflow

Open any workflow in WeWeb by selecting an element and clicking its workflow trigger (e.g., a button's 'On click' trigger in the Workflows panel). Click the '+' to add a new action. Scroll down to 'REST API' and select 'REST API Request'. This is the action that sends HTTP requests — including webhooks. In the action configuration panel, set Method to POST. Paste your webhook URL in the URL field (for example, your Zapier Catch Hook URL or your own server's endpoint). Under the Body tab, set the body format to JSON. This single action is the foundation of every outgoing webhook you send from WeWeb.

Expected result: A REST API Request action appears in the workflow with POST method and your webhook URL configured.

2

Build a dynamic JSON webhook payload

In the REST API Request action body editor, click the 'Add key-value pair' button or switch to the raw JSON editor. You can bind any field value to WeWeb data sources using the formula editor (the plug icon next to any field). Structure your payload with an event identifier, timestamp, and relevant data. Bind form fields from a Form Container using `formContainer.formData.fieldName`. Reference page variables using the variable name directly. Reference current user data from your auth plugin. Use the formula `new Date().toISOString()` in a Custom JavaScript step before the request to generate the current timestamp and store it in a variable, then reference that variable in the payload.

typescript
1// JSON body for the REST API Request action
2// Each value on the right side can be bound using the formula editor
3// Injection point: Workflow → REST API Request → Body (JSON)
4{
5 "event": "form_submission",
6 "source": "weweb_app",
7 "timestamp": "{{variables.currentTimestamp}}",
8 "user": {
9 "id": "{{plugins['supabase-auth'].user.id}}",
10 "email": "{{plugins['supabase-auth'].user.email}}"
11 },
12 "data": {
13 "name": "{{formContainer.formData.name}}",
14 "email": "{{formContainer.formData.email}}",
15 "message": "{{formContainer.formData.message}}",
16 "page": "{{wwPage.name}}"
17 }
18}

Expected result: The webhook payload includes dynamic data from forms and variables, confirmed by inspecting the request in browser dev tools Network tab.

3

Handle the webhook response and errors

After the REST API Request action sends its payload, the response is available to subsequent workflow steps. Reference the response using the formula `actions[N]` where N is the zero-based index of the REST API Request action. For example, if it's the first action, use `actions[0].status` to check the HTTP status code or `actions[0].body` to access the response body. Add a 'Branching' action after the request to handle success and error paths. In the 'If' condition, check `actions[0].status === 200` or `actions[0].status >= 200 && actions[0].status < 300`. In the success branch, show a success toast or navigate to a confirmation page. In the error branch, display an error message. Also click the 'On error' tab in the workflow editor to add a fallback for network failures.

Expected result: Workflow displays success or error feedback based on the webhook endpoint's HTTP response.

4

Understand why WeWeb cannot receive incoming webhooks

When Stripe, GitHub, or Zapier tries to send a webhook, they POST to a URL and expect a server to answer. WeWeb apps run entirely in the user's browser — there is no server listening at your WeWeb URL. The WeWeb Cloud host serves static files; it does not execute server-side code. This means you cannot create a Stripe webhook that posts to your-app.weweb.app/webhooks and have WeWeb handle it. There is no WeWeb equivalent of a Next.js API route or an Express.js server. This is a fundamental architectural limitation of all frontend-only SPA frameworks. The solution is always to put a backend service in between: Supabase Edge Functions, Xano, a Vercel serverless function, or any backend that can receive the webhook, process it, and then make the processed data available to WeWeb.

Expected result: Understanding that WeWeb → external (outgoing) always works, but external → WeWeb (incoming) requires a backend intermediary.

5

Use Supabase Realtime to receive webhook-driven data

The practical workaround for incoming webhooks in WeWeb is: 1) Receive the webhook in a Supabase Edge Function (outside WeWeb), 2) Write the data to a Supabase database table, 3) Subscribe to that table in WeWeb using Supabase Realtime. In Supabase Dashboard (outside WeWeb): create an Edge Function at supabase/functions/webhook-receiver/index.ts, deploy it, and copy its URL. Configure your external service (Stripe, GitHub, etc.) to POST to that Edge Function URL. The Edge Function validates the webhook, processes the payload, and inserts a record into a Supabase table. Back in WeWeb: In the Data panel, set up a Supabase collection on that table with Realtime enabled. Add a workflow with trigger 'On realtime - database change' to react when new records arrive. This entire flow means external systems effectively push data to your WeWeb frontend via the database.

typescript
1// Injection point: Supabase Edge Function (outside WeWeb)
2// File: supabase/functions/webhook-receiver/index.ts
3// Deploy via Supabase CLI: supabase functions deploy webhook-receiver
4
5import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
6import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
7
8serve(async (req: Request) => {
9 if (req.method !== 'POST') {
10 return new Response('Method not allowed', { status: 405 });
11 }
12
13 // Verify webhook signature (example for generic HMAC)
14 const body = await req.text();
15 const signature = req.headers.get('x-webhook-signature') || '';
16
17 // TODO: validate signature using crypto.subtle.verify()
18
19 const payload = JSON.parse(body);
20
21 // Initialize Supabase client with service role key
22 const supabase = createClient(
23 Deno.env.get('SUPABASE_URL') ?? '',
24 Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
25 );
26
27 // Write event to database — WeWeb will pick this up via Realtime
28 const { error } = await supabase
29 .from('webhook_events')
30 .insert({
31 event_type: payload.event || 'unknown',
32 payload: payload,
33 received_at: new Date().toISOString()
34 });
35
36 if (error) {
37 return new Response(JSON.stringify({ error: error.message }), {
38 status: 500,
39 headers: { 'Content-Type': 'application/json' }
40 });
41 }
42
43 return new Response(JSON.stringify({ received: true }), {
44 status: 200,
45 headers: { 'Content-Type': 'application/json' }
46 });
47});

Expected result: External webhooks are received by the Supabase Edge Function, stored in the database, and WeWeb's Realtime subscription triggers a workflow action when new events arrive.

6

Set up polling as a simpler realtime alternative

If Supabase Realtime is too complex, implement polling: fetch a collection on a regular interval. In the Data panel, select your collection and go to its settings. Enable 'Auto-fetch on interval' (if available) or build a polling workflow manually. For manual polling: create an App-level workflow (Workflows panel → App workflows → New), trigger 'On app load'. Add a 'Fetch collection' action for your data collection. Add a 'Time delay' action set to 30,000 milliseconds (30 seconds). Add another 'Fetch collection' action. Add another 'Time delay'. Wrap the delay-fetch cycle in a loop or duplicate the steps. This is a simple approach but inefficient — it fires regardless of whether data changed. Use Supabase Realtime for production apps with real-time requirements.

Expected result: The collection refreshes every 30 seconds automatically, pulling in any new data written to the backend by external webhook handlers.

7

Configure the WeWeb After Deploy Hook

WeWeb has one built-in incoming/outgoing webhook: the After Deploy Hook. Go to your project settings by clicking the gear icon at the top of the left sidebar → 'Project Settings'. Scroll to find 'After Deploy Hook'. Enter a URL in the URL field. After every WeWeb publish (from the Publish button top-right), WeWeb will send a GET request to your URL with query parameters: `type` (build type), `version` (version number), `name` (project name), `env` (environment), `built-zip` (URL to built files), `raw-zip` (URL to raw files), `github` (GitHub push URL if sync enabled). Use this to trigger CI/CD pipelines, notify your team via Slack, invalidate a CDN cache, or trigger a Prerender.io recrawl after new content is published.

Expected result: After clicking Publish in WeWeb, your configured URL receives a GET request with deployment metadata within seconds.

Complete working example

outgoing-webhook.js
1// Injection point: Workflow → Custom JavaScript action (runs BEFORE the REST API Request)
2// Purpose: Prepare the webhook payload with timestamp and computed values
3// The return value is accessible in subsequent workflow steps as actions[N]
4
5// Get current user info from the auth plugin (adjust to your auth plugin)
6const user = window.wwLib?.wwPlugins?.supabaseAuth?.user || null;
7
8// Generate ISO timestamp
9const timestamp = new Date().toISOString();
10
11// Get page information
12const pageName = window.location.pathname;
13
14// Compute a simple event ID for deduplication
15const eventId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
16
17// Build the complete webhook payload object
18// The REST API Request action in the next step will use this via actions[0]
19const webhookPayload = {
20 event_id: eventId,
21 event_type: 'user_action',
22 timestamp: timestamp,
23 source: {
24 app: 'weweb',
25 page: pageName,
26 environment: window.location.hostname.includes('localhost') ? 'development' : 'production'
27 },
28 user: user ? {
29 id: user.id,
30 email: user.email
31 } : null
32 // Note: Add your actual form/event data in the REST API Request action body
33 // by referencing the formContainer.formData variables directly
34};
35
36return webhookPayload;

Common mistakes

Why it's a problem: Trying to receive incoming webhooks directly at a WeWeb URL

How to avoid: WeWeb is a static SPA with no server-side request handling. Incoming webhooks must go to a backend endpoint (Supabase Edge Function, Xano, Vercel API route). The backend processes the webhook and writes to a database; WeWeb reads from that database.

Why it's a problem: Not handling CORS errors when posting to webhook endpoints

How to avoid: Some webhook receivers (especially custom servers) block browser requests due to CORS policy. Enable the 'Proxy the request to bypass CORS issues' checkbox in the REST API Request action settings. This routes the request through WeWeb's servers, adding a slight latency but resolving CORS issues.

Why it's a problem: Exposing secret API keys in webhook payloads sent from client-side workflows

How to avoid: Never include API keys, signing secrets, or sensitive tokens in outgoing webhook payloads from WeWeb workflows. These are visible in browser dev tools Network tab. If your webhook receiver requires authentication, use a non-secret identifier (user ID, project ID) and validate identity on the receiving server using its own secrets.

Why it's a problem: Using the After Deploy Hook URL as a security-sensitive trigger without validation

How to avoid: The After Deploy Hook sends a public GET request with no authentication. Anyone who discovers your After Deploy Hook URL could trigger it. Validate the incoming request on your webhook receiver by checking the 'version' or 'name' query parameters, or use an obscure URL with a random token segment.

Best practices

  • Always add error handling in workflows that send webhooks — use the 'On error' workflow branch and the 'Branching' action to handle failed requests gracefully
  • Include a unique event_id in every outgoing webhook payload to allow the receiver to deduplicate retried requests
  • For webhook-driven realtime updates, Supabase Realtime is the most reliable WeWeb integration — it provides true push notifications without polling overhead
  • Test outgoing webhooks during development using webhook.site (free) or ngrok to inspect payloads before connecting to real systems
  • Use the WeWeb After Deploy Hook to trigger Prerender.io cache purges after publishing — this is critical for SPA SEO
  • When sending sensitive data via webhooks, always use HTTPS endpoints and verify the receiving server's SSL certificate
  • Log webhook responses to a Supabase table for debugging — store the HTTP status code, response body, and timestamp in each workflow execution

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I'm building a WeWeb app and want to send a webhook when a user submits a form. The webhook should POST to my Zapier Catch Hook URL with the form fields, user ID, and a timestamp. Write the JSON body structure for the REST API Request action and explain how to reference WeWeb form variables in the body.

WeWeb Prompt

In WeWeb, I have a form submission workflow. I want to add a REST API Request action that sends a POST webhook to https://hooks.zapier.com/hooks/catch/xxx/yyy with the form data. My form has fields: name, email, message. My user is logged in via Supabase Auth. Show me the exact action configuration and the JSON body with WeWeb formula bindings.

Frequently asked questions

Can WeWeb receive a POST request from an external service like Stripe or GitHub?

No. WeWeb is a frontend-only SPA running in the browser — there is no server to receive incoming HTTP requests. To handle webhooks from Stripe, GitHub, or any external service, you need a backend endpoint (Supabase Edge Function, Xano, or any server) that receives the webhook, processes it, writes to a database, and makes the result available to WeWeb via a collection or Supabase Realtime subscription.

What is the WeWeb After Deploy Hook and when should I use it?

The After Deploy Hook is a WeWeb-native outgoing webhook that fires after every publish. Configure it in Project Settings → After Deploy Hook with a target URL. WeWeb sends a GET request with query parameters including the build version, environment, and download URLs for your compiled app. Use it to trigger CDN cache invalidation, notify CI/CD systems, purge Prerender.io cache, or send Slack deploy notifications.

How do I debug a failing outgoing webhook in WeWeb?

Open browser dev tools (F12) → Network tab → trigger the workflow action. Find the outgoing POST request and inspect the Request Headers, Request Body (confirm the JSON payload is correct), and Response (check HTTP status and response body). If you see a CORS error instead of the actual response, enable 'Proxy the request to bypass CORS issues' in the REST API Request action settings. For persistent issues, use webhook.site to receive test webhooks and inspect exactly what WeWeb sends.

Is Supabase Realtime the only option for near-realtime data in WeWeb without polling?

Supabase Realtime and Xano Realtime are the two native realtime options in WeWeb. Both use WebSocket connections to push database changes to your frontend. If you use a different backend, you can implement Server-Sent Events (SSE) via a REST API collection configured to stream responses, but this requires custom server setup. Polling (periodic collection refetch) works for less time-sensitive use cases and requires no additional infrastructure.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.