Handling Form Submissions

The following mainly applies to AMP plugin v1.2 which is scheduled for release by June 20th, 2019.

The AMP plugin does all that it can to ensure that your existing forms work as expected in AMP. For one thing, forms with a GET method need nothing special as they behave as the same in AMP as they do normally in HTML. When the POST method is used, then things work a bit differently. In regular HTML forms, a form with a POST method will cause a full page navigation to the URL defined in the action. AMP does things differently with its amp-form component. In AMP, when submitting a POST form the form data is submitted via Ajax (XHR/fetch) to the URL defined in an action-xhr attribute. If desiring to redirect the user to a success page, then a special AMP-Redirect-To response header must be sent. Otherwise, the response of the POST request must be a JSON object containing data that should be rendered in the submit-success or submit-error templates.

If a form rendered by WordPress uses an action attribute, then the AMP plugin will try to upgrade it to an amp-form. When redirecting to a success page via wp_redirect(), the AMP plugin will automatically send the AMP-Redirect-To response header with a 200 status code instead of sending the Location response header with a 302 status code.

On the other hand, if the success/failure message is intended to be displayed in the response to the POST request without doing any redirect, then a bit more is involved for AMP-converted forms. First of all, converted forms will automatically get templates added for submitting, submit-error, and submit-success. If the form processor fails a submission with wp_die() (with a non-success error code), then the message provided will be rendered in the submit-error template. Likewise, if wp_die() is used with a 200 status code, then its message will be displayed in the submit-success template. However, if wp_die() is not being used to render the success/failure message then the AMP plugin provides some generic messages based on the status code:

Generic success message response has an apparent OK response.
Generic error message when response has an error code.

In order to avoid showing these generic messages (and styling), your form submission handler should check to see if amp-form is submitting the request and then either use wp_die() or use wp_send_json(). Naturally you’ll need to do this before the template has been rendered, such as at the template_redirect action (or another action prior to template rendering). An easy way to detect for amp-form doing the submission is to use wp_is_json_success().

Given an existing form processing logic that happens at template_redirect, where the method sets a $success variable based on whether or not the submission was accepted, you can incorporate the following example code using wp_send_json():

if ( wp_is_json_request() ) {
	if ( $success ) {
		$message = __( 'Success! Thanks for your submission.', 'my-textdomain' );
	} else {
		$message = __( 'Sorry, your submission is incomplete.', 'my-textdomain' );
	}
	wp_send_json( compact( 'message' ), $success ? 200 : 400 );
}

Or using wp_die():

if ( wp_is_json_request() ) {
	if ( $success ) {
		$message = __( 'Success! Thanks for your submission.', 'my-textdomain' );
	} else {
		$message = __( 'Sorry, your submission is incomplete.', 'my-textdomain' );
	}
	wp_die(
		$message,
		'',
		[ 'response' => $success ? 200 : 400 ]
	);
}

A custom wp_die handler is registered when processing an amp-form submission to automatically invoke wp_send_json().

If you are developing an AMP-compatible form from the start, it is recommended to supply the action-xhr attribute on the form instead of the action attribute to prevent the auto-conversion and so that you have full control over the behavior, including the form submission templates. In this case, you should consider using a REST API endpoint for the action-xhr URL.

For more information, please read the amp-form component documentation, as well as the examples.