Shopify

Frontend Customer

useCustomerState

The useCustomerState hook can be used to get the current state of the customer.

import { useCustomerState } from 'frontend-customer'

const state: {
  id: string | null
  firstName: string | null
  lastName: string | null
  displayName: string | null
  email: string | null
  phone: string | null
  acceptsMarketing: boolean | null // Does the current user accepts marketing emails
  createdAt: string | null // timestamp when the user created
  updatedAt: string | null // timestamp when the user updated
  addresses: Address[] | null // array of the current user's mailing addresses
  defaultAddress: Address | null // default user's mailing addresses
  orders: Order[] | null // array of the current user's orders
  tags: string[] | null // array of current user's tags
  isLoggedIn: boolean // Check if the current user is authorized
  status: 'initial' | 'loading' | 'loaded' | 'error' // Status of loading user's data
} = useCustomerState()

useCustomerActions

Customer actions SDK based on Shopify Storefront API.

import { useCustomerActions } from 'frontend-customer'

register

📘

Make sure the Customers Accounts are not disabled. Check Shopify documentation on how to enable if needed.

/**
 * Register user
 * Returns the registered `customer`
 * or an array of `errors` in case something went wrong.
 *
 * register: ({ email: string; password: string, acceptsMarketing?: boolean }) => Promise<{ customer: Customer } | { errors: CustomerUserError[] }>
 */
const { register } = useCustomerActions()

const { customer, errors } = await register({
  email: '[email protected]',
  password: 'test123',
  // Optionally you can set whether the customer
  // has consented to receive marketing material via email.
  acceptsMarketing: true,
})

login

📘

Heads up

Check this instructions to prevent users from being logged out when they go to the checkout page.

/**
 * Authorize user
 * Returns the logged in `customer`
 * or an array of `errors` in case something went wrong.
 *
 * login: ({ email: string; password: string }) => Promise<{ customer: Customer } | { errors: CustomerUserError[] }>
 */
const { login } = useCustomerActions()

const { customer, errors } = await login({
  email: '[email protected]',
  password: 'test123',
})

You can also login a customer with multipass token.

/**
 * Authorize user using multipass token
 * Returns the logged in `customer`
 * or an array of `errors` in case something went wrong.
 *
 * login: ({ token: string }) => Promise<{ customer: Customer } | { errors: CustomerUserError[] }>
 */
const { login } = useCustomerActions()

const { customer, errors } = await login({
  token: 'multipassToken',
})

logout

/**
 * Logout user
 * Returns an array of `errors` in case something went wrong.
 *
 * logout: () => Promise<{ errors?: UserError[] }>
 */
const { logout } = useCustomerActions()

const { errors } = await logout()

recoverPassword

/**
 * Send email with password recovery link to the user,
 * e.g `https://test.com/account/reset/3576705087584/d05ef926f45c0efe72347536cf5767f0-1606825507`
 * the link url will opens a page `/account/reset` where should
 * be used the `resetPassword` action
 * Returns an array of `errors` in case something went wrong.
 *
 * recoverPassword: (email: string) => Promise<{ errors?: CustomerUserError[] }>
 */
const { recoverPassword } = useCustomerActions()

const { errors } = await recoverPassword('[email protected]')

resetPassword

/**
 * Reset user's password
 * Should be placed in `/account/reset` page.
 * The page will be opened from the recovery link on url `/account/reset/.../...`
 * Reset url: 'https://mystore.com/account/reset/3576705089584/4704e55f92d6be209828e2caf228499e-1606814922'
 * Returns the authenticated `customer`
 * or an array of `errors` in case something went wrong.
 * 
 * resetPassword: ({ resetUrl: string; password: string }) => Promise<{ customer?: Customer } | { errors: CustomerUserError[] }>
 */
const { resetPassword } = useCustomerActions()

const { customer, errors } = await resetPassword({
  resetUrl: window.location.href,
  password: 'test321',
})

getCustomer

/**
 * Fetch user data (except orders and addresses)
 * Returns the authenticated `customer`.
 *
 * getCustomer: ({ syncWithShopify: boolean }) => Promise<{ customer: Customer } | null>
 */
const { getCustomer } = useCustomerActions()

const { customer } = await getCustomer({ syncWithShopify: true })

activateCustomer

/**
 * Activates customer using password + url or password + id + token.
 * Should be placed in `/account/activate` page.
 * Returns the authenticated `customer`
 * or an array of `errors` in case something went wrong.
 *
 * activateCustomer: ({ password: string; url: string; id: string; token: string }) => Promise<{ customer: Customer } | { errors: CustomerUserError[] }>
 */
const { activateCustomer } = useCustomerActions()

const { customer, errors } = await activateCustomer({
  password: 'string',
  url: 'https://your-store-url.com/account/activate/customer_id/activation_token',
})
import React from 'react'
import { useCustomerActions, useCustomerState } from 'frontend-customer'
import { useRouter } from 'frontend-router'

const CustomerActivation = () => {
  const { activateCustomer } = useCustomerActions()
    const { status } = useCustomerState()
  const { push, location } = useRouter()
    const { href } = location // https://your-store-url.com/account/activate/customer_id/activation_token

    const isLoading = status === 'loading'

  async function onSubmit(event) {
    event.preventDefault()
    const { password } = event.target.elements

    const { customer, errors } = await activateCustomer({ url: href, password })

    if (errors) {
      // show validations
      return
    }

    // redirect the user
    push('/')
  }

  return (
    <form onSubmit={onSubmit}>
      <label>Password
        <input name="password" type="password" disabled={isLoading} required />
      </label>
      <button type="submit" disabled={isLoading}>Activate</button>
    </form>
  )
}

export default CustomerActivation

getAllAddresses

/**
 * Fetch all user's addresses
 * Returns all customer `addresses`.
 *
 * getAllAddresses: () => Promise<Customer['addresses'] | null>
 */
const { getAllAddresses } = useCustomerActions()

const addresses = await getAllAddresses()

createAddress

/**
 * AddressInput = {
 *   address1?: string
 *   address2?: string
 *   city?: string
 *   company?: string
 *   country?: string
 *   firstName?: string
 *   lastName?: string
 *   phone?: string
 *   province?: string
 *   zip?: string
 * }
 *
 * Address = AddressInput & {
 *   id: string
 * }
 *
 * Create user's address
 * Returns the recently created `customerAddress`
 * or an array of `errors` in case something went wrong.
 *
 * createAddress: (address: AddressInput) => Promise<{ customerAddress: Address } | { errors: CustomerUserError[] }>
 */
const { createAddress } = useCustomerActions()

const { customerAddress, errors } = await createAddress({
  firstName: 'John', // optional
  lastName: 'Lennon', // optional
  address1: 'string', // optional
  address2: 'string', // optional
  country: 'United States', // optional
  province: 'New York', // optional
  phone: '', // optional
  zip: '', // optional
  city: '', // optional
})

updateAddress

/**
 * Update user's address
 * Returns the recently updated `customerAddress`
 * or an array of `errors` in case something went wrong.
 *
 * updateAddress: ({ id: string; address: AddressInput }) => Promise<{ customerAddress: Address } | { errors: CustomerUserError[] }>
 */
const { updateAddress } = useCustomerActions()

const { customerAddress, errors } = await updateAddress({
  id: '123',
  address: {
    firstName: 'John', // optional
    lastName: 'Lennon', // optional
    address1: 'string', // optional
    address2: 'string', // optional
    country: 'United States', // optional
    province: 'New York', // optional
    phone: '', // optional
    zip: '', // optional
    city: '', // optional
  },
})

updateDefaultAddress

/**
 * Update user's default address
 *
 * updateDefaultAddress: (id: string) => Promise<{ customer: Customer } | { errors: CustomerUserError[] }>
 */
const { updateDefaultAddress } = useCustomerActions()

const { customerAddress, errors } = await updateDefaultAddress('newDefaultAddressId') // Address['id']

deleteAddress

/**
 * Delete user's address given an address id
 * Returns the recently deleted `deletedCustomerAddressId`
 * or an array of `errors` in case something went wrong.
 *
 * deleteAddress: (id: string) => Promise<{ deletedCustomerAddressId?: string } | { errors: CustomerUserError[] }>
 */
const { deleteAddress } = useCustomerActions()

const { deletedCustomerAddressId, errors } = await deleteAddress('123')

getAllOrders

/**
 * Fetch all customer's orders
 *
 * getAllOrders: () => Promise<Customer['orders'] | null>
 */
const { getAllOrders } = useCustomerActions()

const orders = await getAllOrders()

getOrder

/**
 * Fetch order by id
 * Returns the requested `order`
 * or an array of `errors` in case something went wrong.
 *
 * getOrder: (id: string) => Promise<{ order: Order | null } | { errors: { message: string }[] }>
 */
const { getOrder } = useCustomerActions()

const { order, errors } = await getOrder('123')

getCustomerMetafield

🚧

Important

  • We are only capable of providing read functionality for these metafields and not able to write/expose metafields.
  • Ensure your store metafields are exposed; otherwise, getCustomerMetafield won't work correctly.
/**
 * Retrieve one metafield with a given namespace and key (required)
 *
 * getCustomerMetafield: ({namespace: string; key: string}) => Promise<ShopifySdkGetCustomerMetafieldsPayload>
 */
const { getCustomerMetafield } = useCustomerActions()

const metafield = await getCustomerMetafield({ namespace: 'recipe', key: 'vegan' })

getCustomerMetaFields

🚧

Important

  • We are only capable of providing read functionality for these metafields and not able to write/expose metafields.
  • Ensure your store metafields are exposed; otherwise, getCustomerMetafields won't work correctly.
/**
 * Retrieve all metafields, or all metafields by namespace
 *
 * getCustomerMetafields: ({ namespace?: string; key: string }) => Promise<ShopifySdkGetCustomerMetafieldsPayload>
 */
const { getCustomerMetafields } = useCustomerActions()

const allMetafields = await getCustomerMetafields()
const allRecipeMetafields = await getCustomerMetaFields({ namespace: 'recipe' })