Shopify Checkout custom fields validation

Hello,

I wrote the checkout extension that collects some additional information at checkout, like gift sender contact information, gift receiver contact information, date to send congratulation message, etc. All this information is collected in order metafields for further use.

Everything is working as it should. But… some of these fields (TextFields and DateField) are mandatory and required validation. The documentation I found and duplicated https://shopify.dev/docs/apps/checkout/validation/client-side-validation?framework=remix&extension=react does not work for this purpose. It does not highlight the error and it does not preventing from jumping to another page of checkout process.

I have noticed that this example may require Remix framework to be used (not sure about it), but I am looking for the simple but robust way of fields’ validation without Remix and just using ReactJS.

I appreciate any hints and source to achieve this functionality.

Hi Taurus73,

To implement validation in your checkout extension using React.js, you can use the useEffect hook to perform field validation and the state to store error messages.

Here is a simple example of how you can achieve this for mandatory fields:

import React, { useEffect, useState } from 'react';

function CheckoutForm() {
  const [formData, setFormData] = useState({
    giftSender: '',
    giftReceiver: '',
    sendMessageDate: '',
  });

  const [formErrors, setFormErrors] = useState({
    giftSender: null,
    giftReceiver: null,
    sendMessageDate: null,
  });

  const handleInputChange = (event) => {
    setFormData({
      ...formData,
      [event.target.name]: event.target.value,
    });
  };

  useEffect(() => {
    // Validates gift sender input
    if (!formData.giftSender) {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        giftSender: 'Gift sender field is required',
      }));
    } else {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        giftSender: null,
      }));
    }

    // Validates gift receiver input
    if (!formData.giftReceiver) {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        giftReceiver: 'Gift receiver field is required',
      }));
    } else {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        giftReceiver: null,
      }));
    }

    // Validates send message date input
    if (!formData.sendMessageDate) {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        sendMessageDate: 'Send message date field is required',
      }));
    } else {
      setFormErrors((prevErrors) => ({
        ...prevErrors,
        sendMessageDate: null,
      }));
    }
  }, [formData]);

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!Object.values(formErrors).every((error) => error === null)) {
      alert('Please correct the errors before submitting the form');
      return;
    }

    // Proceed with form submission
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="giftSender"
        value={formData.giftSender}
        onChange={handleInputChange}
      />
      {formErrors.giftSender && <div>{formErrors.giftSender}</div>}

      <input
        name="giftReceiver"
        value={formData.giftReceiver}
        onChange={handleInputChange}
      />
      {formErrors.giftReceiver && <div>{formErrors.giftReceiver}</div>}

      <input
        name="sendMessageDate"
        value={formData.sendMessageDate}
        onChange={handleInputChange}
      />
      {formErrors.sendMessageDate && <div>{formErrors.sendMessageDate}</div>}

      <button type="submit">Submit</button>
    </form>
  );
}

In this example, we’re storing the form data and the form errors in the state. Each time the form data changes, we’re using useEffect to validate the fields and update the form errors. Before form submission, we’re checking if all form errors are null. If they’re not, we’re displaying an alert and preventing form submission.

This is a simple and straightforward way to implement validation in React.js without using any libraries.

I hope this helps!

Thank you Liam,

This is a really straightforward solution working with the form validation in ReactJS. However, since we are building a Shopify Checkout Extension we would like to use the native shopify functionality of validation and blocking the progress using useBuyerJourneyIntercept.

I am still experimenting and will post here my findings.

Thanks again for your reply!

@Liam How you can perform validation on existing fields such like email, firstname and other?

I have got the same issue. How to perform validation on existing fields?

Hey @marrep did you get any solution for that, I’m stuck in the same problem here!

@carlosrosa not yet unfortunately. This has to be possible, however, since Apps like custom blocks are able to make validations. I guess it is just a poor documentation from shopify and there are API endpoints to solve this.

@marrep I got you, yesterday I just did some testing in my project and got the result that I was looking for, I did the validation in React JS function by myself CreditCardValidation, so for now I will keep that way, the main issue its handled, blocking the form submit event.

Here it’s my example, I hope that can give you some ideas,

import { useState } from "react";

import {
  reactExtension,
  TextField,
  useApplyPaymentMethodAttributesChange,
  useBuyerJourneyIntercept,
  View,
} from "@shopify/ui-extensions-react/checkout";
import type { PaymentMethodAttributesUpdateChange } from "@shopify/ui-extensions/checkout";

reactExtension("Checkout::PaymentMethod::Render", () =>

useBuyerJourneyIntercept Hook is triggered on hover of “continue” button?. How to prevent that?

Thanks for sharing! Can’t believe there is nothing out of the box by shopify