How to add a privacy policy and terms checkbox in WordPress registration form

Jul 1, 2020

Ever since EU GDPR came into an action in 2018 developers all over the world have needed to add consent checkboxes into forms that processes any kind of personal data.

Luckily it’s relatively easy to add such checkbox into the WordPress default registration form.

First create the checkbox by using the register_form action (remember to replace the PAGE_ID_HERE with correct page IDs and YOUR-TEXT-DOMAIN strings with the text domain of your plugin/theme):

function wpa_registration_privacy_policy_checkbox() {
	// Let's make sure everything is escaped properly
	$terms_text = esc_html__( 'Terms of Use', 'YOUR-TEXT-DOMAIN' );
	$terms_url = esc_url( get_permalink( PAGE_ID_HERE ) );
	$terms_link_html = sprintf( '<a href="%s">%s</a>', $terms_url, $terms_text );

	$privacy_policy_text = esc_html__( 'Privacy Policy', 'YOUR-TEXT-DOMAIN' );
	$privacy_policy_url = esc_url( get_permalink( PAGE_ID_HERE ) );
	$privacy_policy_link_html = sprintf ( '<a href="%s">%s</a>', $privacy_policy_url, $privacy_policy_text );

	/* translators: 1 is a link with the text "Terms of Use" and 2 is a link with the text "Privacy Policy" */
	$text = sprintf( esc_html__( 'I undestand and agree with the %1$s and %2$s.', 'YOUR_TEXT_DOMAIN' ), $terms_link_html, $privacy_policy_link_html );

	// We are using PHP heredoc syntax.
	// The lack of indentation for EOT; is intentional.
	// Read more: https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
	$field = <<<EOT
		<label for="privacy_policy_terms_of_service">
			<input type="checkbox" name="privacy_policy_terms_of_service" class="checkbox" required />
			${text}
		</label>
		<br><br>
EOT;

	echo $field; // xss safe.
}

add_action( 'register_form', 'wpa_registration_privacy_policy_checkbox', 1, 10 );

Then add validation check via the registration_errors filter (remember to replace YOUR-TEXT-DOMAIN strings with the text domain of your plugin/theme):

function wpa_privacy_policy_validation( $errors, $sanitized_user_login, $user_email ) {
	if ( ! isset( $_POST['privacy_policy_terms_of_service'] ) ) {
		$errors->add( 'empty_privacy_policy_terms', '<strong>' . esc_html__( 'Error', 'YOUR-TEXT-DOMAIN' ) . '</strong>: ' . esc_html__( 'Please accept the Privacy Policy and the Terms of Service.', 'YOUR-TEXT-DOMAIN' ) );
	}

	return $errors;
}

add_filter( 'registration_errors', 'wpa_privacy_policy_validation', 10, 3 );

Done. Now you should have a working checkbox that you can customize as you wish 🙂