Skip to content

Event listeners are unreliable without preload() and preload has no completion callback #488

@Makhdoom-Sharif

Description

@Makhdoom-Sharif

What area is the issue related to?

Checkout Sheet Kit

What platform does the issue affect?

All platforms

What version of @shopify/checkout-sheet-kit are you using?

3.8.0

Do you have reproducible example code?

Reproducible Example
Problem

When calling present() directly without preload(), checkout listeners are inconsistent and sometimes do not fire.

Example

import React, { useEffect } from 'react'
import {
  ShopifyCheckoutSheetKit,
  CheckoutEvent,
} from '@shopify/checkout-sheet-kit'
import { Button, View } from 'react-native'

const CHECKOUT_URL =
  'https://your-store.myshopify.com/checkouts/...'

export default function App() {
  useEffect(() => {
    const completedSub =
      ShopifyCheckoutSheetKit.addEventListener(
        CheckoutEvent.Completed,
        event => {
          console.log('COMPLETED', event)
        }
      )

    const closeSub =
      ShopifyCheckoutSheetKit.addEventListener(
        CheckoutEvent.Close,
        () => {
          console.log('CLOSED')
        }
      )

    const errorSub =
      ShopifyCheckoutSheetKit.addEventListener(
        CheckoutEvent.Error,
        error => {
          console.log('ERROR', error)
        }
      )

    return () => {
      completedSub.remove()
      closeSub.remove()
      errorSub.remove()
    }
  }, [])

  const openCheckout = async () => {
    // NO PRELOAD
    await ShopifyCheckoutSheetKit.present(
      CHECKOUT_URL
    )
  }

  return (
    <View>
      <Button
        title="Open Checkout"
        onPress={openCheckout}
      />
    </View>
  )
}

Steps to Reproduce

  1. Install @shopify/checkout-sheet-kit in a React Native application.

  2. Register checkout event listeners:

ShopifyCheckoutSheetKit.addEventListener(
  CheckoutEvent.Close,
  () => {
    console.log('CLOSED')
  }
)

ShopifyCheckoutSheetKit.addEventListener(
  CheckoutEvent.Completed,
  event => {
    console.log('COMPLETED', event)
  }
)
  1. Open checkout directly using present() without calling preload():
ShopifyCheckoutSheetKit.present(
  CHECKOUT_URL
)
  1. Complete or close the checkout multiple times.

  2. Observe that checkout listeners sometimes do not fire consistently.

Expected Behavior

Checkout event listeners should fire consistently regardless of whether preload() is used.

If preload() is required for stable listener behavior, the SDK should provide a deterministic way to know when preload has completed before calling present().

For example:

  • Promise-based preload
  • readiness callback/event
  • preload completion state

Currently, developers must rely on arbitrary delays before calling present(), which is unreliable and device-dependent.

Actual Behavior

When checkout is opened directly using:

ShopifyCheckoutSheetKit.present(
  CHECKOUT_URL
)

checkout event listeners behave inconsistently.

Observed issues include:

  • CheckoutEvent.Completed sometimes does not fire
  • listener behavior is inconsistent across devices/platforms

Using preload() followed by an artificial delay before present() significantly improves listener reliability:

ShopifyCheckoutSheetKit.preload(
  CHECKOUT_URL
)

setTimeout(async () => {
  ShopifyCheckoutSheetKit.present()
}, 700)

This suggests a race condition between checkout initialization and listener readiness.

Additionally, preload() is currently fire-and-forget and does not expose any completion mechanism, making it impossible to deterministically know when checkout is ready for presentation.

Storefront domain

squatwolfglobal.myshopify.com

Screenshots/Videos/Log output

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions