Webflow Form POST to Webhook shows JSON response instead of Success message

Does anyone know why a POST request to my webhook opens a new tab and shows the json response, instead of showing the success message in webflow?

Thank you!

I can’t share a read-only at this time, since it’s client work and not to be seen from the outside.

Hi @miguelst :wave: welcome!

The opening of a new tab part I’m not clear on. But I do understand the showing of a json response, instead of showing the success message.

I’m assuming you’ve added the Webhook URL to your forms “Action” field, yes?

When you add your own URLs to the forms action field you are telling Webflow that you don’t want them to handle form submissions for you.

What that means is the built in functionality that Webflow provides with forms stops working.

The success/error messages are part of the built-in functionality.

On a bright note, you also get to bypass the monthly form submit thresholds Webflow limits you to.

You’ll notice that you did not receive an email notifying you of a form submit and the forms tab, in your project settings, did not capture the form submit.

Again, you’re telling Webflow that you’re advanced enough to handle all of this yourself.

But, back to your json response…

So you’ve submitted a form to a Webhook URL and thats it. Since Webflow is no longer handling the form submit, it’s up to you to handle the response from that POST request.

The JSON blob you’re seeing is simply what your Webhook endpoint is returning.

I do this often, and sometimes I’ll return a JSON blob in the response that triggers some Javascript to flip on either the success or error message depending on what’s returned (this is fairly straightforward).

Another approach is to just return a 302 response with a “Location” header and redirect the user to another page.

Either work.

If you’re interested in learning more here’s a screencast walking through exactly this using Make (Integromat) Webhooks. It’ll explain a lot of the details about what I’ve mentioned:

Hope that helps!

1 Like

Hi @ChrisDrit ,

Thanks again for all the tutorials you make, they are very helpful.
Thanks to your explanation I managed to configure a Webflow form to fill a Google Sheet and send emails with a webhook in Make. But I’m still stuck to make the visitor stay on the form page and have the success or error message displayed.

Could you help with the “JSON blob in the response that triggers some Javascript” as you wrote?

Thanks a lot

Hi @vianneypercq glad it’s helpful.


The “Body” field is where I stick the JSON blob, in fact what’s in that screenshot is just that.

The difference is I’ll add some custom text instead, something like:

"success": true,
 "message": "This is a success, here is your discount code: <insert code dynamically>"

Then you can grab that JSON in the response. I do that already in the example code for this tutorial, here’s the line of code that does it.

But instead of redirecting the web browser, as that code does, I’d just assign that to your success message. You grab that on this line of code.

Then something along the lines of:

successMessage.text = data.message

Stuffs your JSON blob response into the success message that is displayed to the user keeping them on the same page.

Making it better would be something like (pseudocode):

if(data.success) === true{
 successMessage.text = data.message
 failureMessage.text = data.message
1 Like

Hi @ChrisDrit
Thanks a lot for your response. I have followed your advices and that works.
After submitting the form:

  • Checking the status of the answer returned by the Make scenario
  • Stay on the form page
  • Display the success or error message configured in Webflow
  • Insert a Loading Indicator animation before the success or error message

Here is my configuration.

In Make:

And my Javascript Code:

var Webflow = Webflow || [];
Webflow.push(function() {

	// function to display error message
	function displayError() {
		hideLoading(); // hide loading indicator
		failureMessage.style.display = 'block'; // show error message

	// function to hide the loading indicator
	function hideLoading() {
		showForm(); // show the form
		loadingIndicator.style.display = 'none'; // hide the loading indicator

	// function to hide the form
	function hideForm() {
		form.style.display = 'none'; // hide the form

	// function to show the loading indicator
	function showLoading() {
		hideForm(); // hide the form
		loadingIndicator.style.display = 'flex'; // show the loading indicator

	// function to show the form
	function showForm() {
		form.style.display = 'grid'; // show the form

	// function to trigger form submission 
	function triggerSubmit(event) {
		// prevent default form submission behavior

		showLoading(); // show loading indicator

		// setup + send xhr request
		let formData = new FormData(event.target);
		let xhr = new XMLHttpRequest();
		xhr.open('POST', event.srcElement.action);

		// capture xhr response
		xhr.onload = function() {
			setTimeout(function() {
				hideLoading(); // hide loading indicator
				if (xhr.status === 200) {
					let data = JSON.parse(xhr.responseText);
					if (data.success) {
						hideForm(); // hide the form
						successMessage.style.display = 'block'; // show success message
					} else {
						displayError(); // show error message
				} else {
					displayError(); // show error message
			}, 2000); // delay of 2000ms added

	// Retrieve the HTML form element with the ID "profile-form" and store it in the constant variable "form"
	const form = document.getElementById('profile-form');

	// set the Webflow Error Message Div Block ID to 'error-message'
	let failureMessage = document.getElementById('error-message');

	// set the Webflow Success Message Div Block ID to 'success-message'
	let successMessage = document.getElementById('success-message');

	// set the Webflow Loading Indicator Div Block ID to 'loading-indicator'
	let loadingIndicator = document.getElementById('loading-indicator');

	// capture form submission event
	form.addEventListener('submit', triggerSubmit);