Manage Customer Addresses in the Storefront

Create, update, and delete customer addresses.

On this page

In this guide, you'll learn how to manage a customer's addresses in a storefront. This is useful in the customer's profile page, or when the customer adds an address during checkout and you want to save it for future orders.

List Customer Addresses

To retrieve the list of customer addresses, send a request to the List Customer Addresses API route:

Tip: - Learn how to install and configure the JS SDK in the Getting started guide.

  • Since only authenticated customers can view their addresses, this example assumes that the JS SDK is already configured for authentication and the customer's authentication token was set as explained in the Login in Storefront and Third-Party Login guides.

React

tsx

tsxCopy
"use client" // include with Next.js 13+
import { HttpTypes } from "@aiminaabeejs/types"
import { useEffect, useState } from "react"
import { sdk } from "@/lib/sdk"
export default function Addresses() {
const [addresses, setAddresses] = useState<
HttpTypes.StoreCustomerAddress[]
>([])
const [loading, setLoading] = useState(true)
const limit = 20
const [currentPage, setCurrentPage] = useState(1)
const [hasMorePages, setHasMorePages] = useState(false)
useEffect(() => {
if (!loading) {
return
}
const offset = (currentPage - 1) * limit
sdk.store.customer.listAddress("us", {
limit,
offset,
})
.then(({ addresses: addressesData, count }) => {
setAddresses((prev) => {
if (prev.length > offset) {
// addresses already added because
// the same request has already been sent
return prev
}
return [
...prev,
...addressesData,
]
})
setHasMorePages(count > limit * currentPage)
})
.finally(() => setLoading(false))
}, [loading])
return (
<div>
{loading && <span>Loading...</span>}
{!loading && !addresses.length && (
<span>You have no addresses</span>
)}
<ul>
{addresses.map((address) => (
<li key={address.id}>
{address.address_name && `${address.address_name} - `}
City: {address.city} -
Country: {address.country_code}
</li>
))}
</ul>
{!loading && hasMorePages && (
<button
onClick={() => {
setCurrentPage((prev) => prev + 1)
setLoading(true)
}}
disabled={loading}
>
Load More
</button>
)}
</div>
)
}

JS SDK

ts

tsCopy
sdk.store.customer.listAddress("us", {
limit,
offset,
})
.then(({ addresses, count }) => {
// use addresses...
console.log(addresses, count)
})

The List Customer Addresses API route accepts pagination parameters to paginate the address.

The request returns in the response the addresses field, which is an array of addresses. You can check its structure in the customer schema.

The request also returns the count field, which is the total number of addresses in the Aiminaabee application. You can use it to check if there are more addresses to retrieve.


Add Customer Address

To add a new address for the customer, send a request to the Add Customer Address API route:

Tip: - This example uses the useRegion hook defined in the Region Context guide.

  • This example uses the useCustomer hook defined in the Customer Context guide.
  • Since only authenticated customers can add addresses, this example assumes that the JS SDK is already configured for authentication and the customer's authentication token was set as explained in the Login in Storefront and Third-Party Login guides.

React

tsx

tsxCopy
"use client" // include with Next.js 13+
import { useState } from "react"
import { useRegion } from "@/providers/region"
import { useCustomer } from "@/providers/customer"
import { sdk } from "@/lib/sdk"
export default function AddAddress() {
const { region } = useRegion()
const { setCustomer } = useCustomer()
const [loading, setLoading] = useState(false)
const [addressName, setAddressName] = useState("")
const [firstName, setFirstName] = useState("")
const [lastName, setLastName] = useState("")
const [address1, setAddress1] = useState("")
const [company, setCompany] = useState("")
const [postalCode, setPostalCode] = useState("")
const [city, setCity] = useState("")
const [countryCode, setCountryCode] = useState("")
const [province, setProvince] = useState("")
const [phoneNumber, setPhoneNumber] = useState("")
const handleAdd = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault()
setLoading(false)
sdk.store.customer.createAddress("us", {
address_name: addressName,
first_name: firstName,
last_name: lastName,
address_1: address1,
company,
postal_code: postalCode,
city,
country_code: countryCode,
province,
phone: phoneNumber,
})
.then(({ customer }) => {
setCustomer(customer)
})
.finally(() => setLoading(false))
}
return (
<form>
<input
type="text"
placeholder="Address Name"
value={addressName}
onChange={(e) => setAddressName(e.target.value)}
/>
<input
type="text"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
<input
type="text"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
<input
type="text"
placeholder="Address Line"
value={address1}
onChange={(e) => setAddress1(e.target.value)}
/>
<input
type="text"
placeholder="Company"
value={company}
onChange={(e) => setCompany(e.target.value)}
/>
<input
type="text"
placeholder="Postal Code"
value={postalCode}
onChange={(e) => setPostalCode(e.target.value)}
/>
<input
type="text"
placeholder="City"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
<select
value={countryCode}
onChange={(e) => setCountryCode(e.target.value)}
>
{region?.countries?.map((country) => (
<option
key={country.iso_2}
value={country.iso_2}
>
{country.display_name}
</option>
))}
</select>
<input
type="text"
placeholder="Province"
value={province}
onChange={(e) => setProvince(e.target.value)}
/>
<input
type="tel"
placeholder="Phone Number"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
/>
<button
disabled={loading}
onClick={handleAdd}
>
Add
</button>
</form>
)
}

JS SDK

ts

tsCopy
sdk.store.customer.createAddress("us", {
address_name: addressName,
first_name: firstName,
last_name: lastName,
address_1: address1,
company,
postal_code: postalCode,
city,
country_code: countryCode,
province,
phone: phoneNumber,
})
.then(({ customer }) => {
// use customer
console.log(customer)
})

In this example, you send a request to the Add Customer Address API route to add a new address for the customer.

The response of the request has a customer field, which is a customer object. You can access the new address in the addresses property of the customer object.


Edit an Address

To edit an address, send a request to the Update Customer Address API route:

Tip: - This example uses the useRegion hook defined in the Region Context guide.

  • This example uses the useCustomer hook defined in the Customer Context guide.
  • Since only authenticated customers can edit their addresses, this example assumes that the JS SDK is already configured for authentication and the customer's authentication token was set as explained in the Login in Storefront and Third-Party Login guides.

React

tsx

tsxCopy
"use client" // include with Next.js 13+
import { useState } from "react"
import { useRegion } from "@/providers/region"
import { useCustomer } from "@/providers/customer"
import { sdk } from "@/lib/sdk"
type Props = {
id: string
}
export default function EditAddress(
{ id }: Props
) {
const { customer, setCustomer } = useCustomer()
const { region } = useRegion()
const address = customer?.addresses.find(
(address) => address.id === id
)
const [loading, setLoading] = useState(false)
const [addressName, setAddressName] = useState(
address?.address_name || ""
)
const [firstName, setFirstName] = useState(
address?.first_name || ""
)
const [lastName, setLastName] = useState(
address?.last_name || ""
)
const [address1, setAddress1] = useState(
address?.address_1 || ""
)
const [company, setCompany] = useState(
address?.company || ""
)
const [postalCode, setPostalCode] = useState(
address?.postal_code || ""
)
const [city, setCity] = useState(
address?.city || ""
)
const [countryCode, setCountryCode] = useState(
address?.country_code || ""
)
const [province, setProvince] = useState(
address?.province || ""
)
const [phoneNumber, setPhoneNumber] = useState(
address?.phone || ""
)
const handleEdit = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault()
if (!customer || !address) {
return
}
setLoading(true)
sdk.store.customer.updateAddress("us", address.id, {
address_name: addressName,
first_name: firstName,
last_name: lastName,
address_1: address1,
company,
postal_code: postalCode,
city,
country_code: countryCode,
province,
phone: phoneNumber,
})
.then(({ customer }) => {
setCustomer(customer)
})
.finally(() => setLoading(false))
}
return (
<form>
<input
type="text"
placeholder="Address Name"
value={addressName}
onChange={(e) => setAddressName(e.target.value)}
/>
<input
type="text"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
<input
type="text"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
<input
type="text"
placeholder="Address Line"
value={address1}
onChange={(e) => setAddress1(e.target.value)}
/>
<input
type="text"
placeholder="Company"
value={company}
onChange={(e) => setCompany(e.target.value)}
/>
<input
type="text"
placeholder="Postal Code"
value={postalCode}
onChange={(e) => setPostalCode(e.target.value)}
/>
<input
type="text"
placeholder="City"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
<select
value={countryCode}
onChange={(e) => setCountryCode(e.target.value)}
>
{region?.countries?.map((country) => (
<option
key={country.iso_2}
value={country.iso_2}
>
{country.display_name}
</option>
))}
</select>
<input
type="text"
placeholder="Province"
value={province}
onChange={(e) => setProvince(e.target.value)}
/>
<input
type="tel"
placeholder="Phone Number"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
/>
<button
disabled={loading}
onClick={handleEdit}
>
Add
</button>
</form>
)
}

JS SDK

ts

tsCopy
sdk.store.customer.updateAddress("us", address.id, {
address_name: addressName,
first_name: firstName,
last_name: lastName,
address_1: address1,
company,
postal_code: postalCode,
city,
country_code: countryCode,
province,
phone: phoneNumber,
})
.then(({ customer }) => {
// use customer...
console.log(customer)
})

In this example, you send a request to the Update Customer Address API route to edit an address.

The response of the request has a customer field, which is a customer object. You can access the updated address in the addresses property of the customer object.


Delete Customer Address

To delete a customer's address, send a request to the Delete Customer Address API route:

Tip: Since only authenticated customers can delete their addresses, this example assumes that the JS SDK is already configured for authentication and the customer's authentication token was set as explained in the Login in Storefront and Third-Party Login guides.

ts

tsCopy
sdk.store.customer.deleteAddress("us", addrId)
.then(({ parent: customer }) => {
// use customer...
console.log(customer)
})

In this example, you send a request to the Delete Customer Address API route to delete an address.

The response of the request has a parent field, which is a customer object. You can access the updated customer in the parent property of the response.