Developer Guides
  • Introduction
    • Welcome
  • Core
    • Overview
    • Frontend
      • Implementation & Testing
      • Using the API endpoints
      • Gift cards
        • Gift Card validation API (Optional)
      • Check stock
      • Sibling products
      • Rewards program
      • Customer signatures
      • Retail transactions
      • Shopify Local Pick-up
  • API
    • Overview
    • Quick Start
    • Accounts
    • Changelog
    • Reference
      • Customers
      • Inventory
      • Orders
      • Products
      • Rewards
      • Stores
      • Vouchers
      • Staff
Powered by GitBook
On this page
  • Headless Stores
  • Prerequisites
  • The Hook
  • Example Implementation
  • Links

Was this helpful?

Export as PDF
  1. Core
  2. Frontend

Shopify Local Pick-up

Learn how to configure Local Pickup in your Merchants Shopify store, and customise pickup options.

Headless Stores

Prerequisites

While there are no FE prerequisites for the checkout, to be able to query stock levels on the FE, you need the following:

  • Shopify Storefront API version 2023-04 or above

  • Stores set up in Shopify that allow in-store pickup

The Hook

To handle this, we’re best to create a useFindInStore hook — this would power a few parts:

  • Fetching user location

  • Fetching the product variant data

  • Handling errors

The GraphQL Query

The storeAvailability connection is available on the variant, so before you can run the query, the user should have already selected a variant (see 2 in need to knows).

We can then present the user with the option to search for store stock. An example would be:

query FindInsStoreVariantsAndLocations($handle: String!, $latitude: Float!, $longitude: Float!) {
	product(handle: $handle) {
		variantBySelectedOptions(selectedOptions: $selectedOptions) {
			storeAvailability(first:250, near: { latitude: $latitude, longitude: $longitude }) {
				edges {
					node {
						available
                        pickUpTime
						location {
							name
							id
							address {
								formatted
								latitude
								longitude
							}
						}
					}
				}
			}
		}
	}
}

With the following variables:

variables: {
  handle: product?.handle,
	selectedOptions: product?.activeVariant?.selectedOptions,
  latitude: coords.lat,
  longitude: coords.lng,
}

This will return this response:

{
    "data": {
        "product": {
            "variantBySelectedOptions": {
                "storeAvailability": {
                    "edges": [
                        {
                            "node": {
                                "available": true,
                                "pickUpTime": "Usually ready in 24 hours",
                                "location": {
                                    "name": "Doncaster Store",
                                    "id": "gid://shopify/Location/60903817288",
                                    "address": {
                                        "formatted": [
                                            "619 Doncaster Road",
                                            "Shop 1013",
                                            "Doncaster VIC 3108",
                                            "Australia"
                                        ],
                                        "latitude": -37.7851115,
                                        "longitude": 145.1262028
                                    }
                                }
                            }
                        },
                        {
                            "node": {
                                "available": true,
                                "pickUpTime": "Usually ready in 24 hours",
                                "location": {
                                    "name": "Armadale Store",
                                    "id": "gid://shopify/Location/60898607176",
                                    "address": {
                                        "formatted": [
                                            "1080 High Street",
                                            "Armadale VIC 3143",
                                            "Australia"
                                        ],
                                        "latitude": -37.855974,
                                        "longitude": 145.023201
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

From this response, you could flatten the array then sort by the distance:

const getDistance = useCallback((pos1: any, pos2: any) => {
  if (!pos1 || !pos2) {
    return 0
  }

  const R = 6371 // Radius of the earth in km
  const dLat = deg2rad(pos2.lat - pos1.lat) // deg2rad below
  const dLon = deg2rad(pos2.lng - pos1.lng)
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(deg2rad(pos1.lat)) * Math.cos(deg2rad(pos2.lat)) * Math.sin(dLon / 2) * Math.sin(dLon / 2)
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
  return R * c
}, [])

const availability = edgeNormaliser(data?.product?.variantBySelectedOptions?.storeAvailability)
const sortedAvailability = availability?.map(location => ({...location, distance: getDistance(userCoords, {lat:location?.location?.latitude, lng:location?.location?.longitude})}))?.sort((a: any, b: any) => parseInt(a?.distance) - parseInt(b?.distance))

return storeAvailability

Example Implementation

Whilst it is outdated, Tony Bianco is a good reference for how to implement native Shopify Pickup.

On the PDP, the drawer uses Google Maps API to search for the user's location with autocomplete, or the Find My Location uses navigator.geolocation to get the user's current position.

Links

PreviousRetail transactionsNextOverview

Last updated 1 year ago

Was this helpful?

PDP:

useFindStore Hook: (not the best reference because it’s outdated, but an okay-ish reference for how it all pieces together)

Find In Store Components:

https://www.tonybianco.com/au/products/marcel-black-patent-10-5cm-heels
https://gitlab.com/dotdevv/clients/tonybianco/tony-bianco-website/-/blob/main/app/src/hooks/useFindStore.tsx
https://gitlab.com/dotdevv/clients/tonybianco/tony-bianco-website/-/tree/main/app/src/components/FindInStore