How to make a Shopify Function only run at checkout

How to make a Shopify Function only run at checkout

a_zelinsky
Shopify Partner
27 0 5

I have a Shopify function created, as a cart and checkout validation extension. It's attempting to require first name, last name, and phone number input fields. I know there's a native way to do this in the Shopify admin settings, however, if you enable ship to any address in Shopify B2B, it overrides this setting.

The issue with the function is that it's running at other cart actions, outside of checkout. This poses an issue when the customer is logged in, and they don't have a first name or phone number associated with them, and it throws the error when adding a product to the cart.

I have tried adding various conditionals in my run.js file, such as checking for deliveryAddress, deliveryOptions, selectedDeliveryOption, etc, as a way of determining whether we're at the checkout step, however, all of them are also returned/accessible before checkout for some reason.

Is there a way to make this function only execute at checkout?

You can see my shopify.extension.toml below:

api_version = "2024-10"

[[extensions]]
name = "t:name"
handle = "required-input-field-validations"
type = "function"

description = "t:description"

  [[extensions.targeting]]
  target = "purchase.validation.run"
  input_query = "src/run.graphql"
  export = "run"

  [extensions.build]
  command = ""
  path = "dist/function.wasm"

Here is my run.js file:

// @ts-check

/**
 * @typedef {import("../generated/api").RunInput} RunInput
 * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
 */

/**
 * The entry point for the Shopify Function
 *
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  const errors = [];

  // Access delivery address information from the input
  const deliveryGroups = input.cart.deliveryGroups || [];
  const deliveryAddress = deliveryGroups[0]?.deliveryAddress || {};

  const firstName = deliveryAddress.firstName || '';
  const lastName = deliveryAddress.lastName || '';
  const phone = deliveryAddress.phone || '';

  // Debugging logs
  console.log('First Name:', firstName);
  console.log('Last Name:', lastName);
  console.log('Phone:', phone);

  // Validate First Name
  if (!firstName.trim()) {
    errors.push({
      localizedMessage: 'Please enter your first name.',
      target: 'deliveryAddressFirstName',
    });
  }

  // Validate Last Name
  if (!lastName.trim()) {
    errors.push({
      localizedMessage: 'Please enter your last name.',
      target: 'deliveryAddressLastName',
    });
  }

  // Validate Phone Number
  if (!phone.trim()) {
    errors.push({
      localizedMessage: 'Please enter your phone number.',
      target: 'deliveryAddressPhone',
    });
  }

  return { errors };
}

Thank you.

Replies 0 (0)