Skip to main content

Order

Order management components for displaying and managing customer orders in e-commerce applications.

Purpose​

This library provides components for displaying and managing customer orders, including order details, order history, and order status tracking. It's designed as a headless component that provides all the order logic while allowing complete UI customization. Use this library when you need to display order confirmation details, order history, or allow customers to view their past orders.

Features​

  • Order details display with loading and error states
  • Order line item management via integrated OrderLines components
  • Order totals and pricing calculations
  • Shipping lines display with method names and prices
  • Shipping and billing address display
  • Order summary with subtotal, shipping, and total calculations
  • Generic field component for displaying any order property

Installation​

npm install @haus-storefront-react/order

Note: This is not a public package. Contact the Haus Tech Team for access.

API Reference​

Order.Root​

Root component that fetches order data and provides context for all child components. Must be used as the wrapper for all other Order components.

Props

PropTypeRequiredDefaultDescription
orderCodestringYes-The order code to fetch order details
childrenChildrenProps<OrderContextValue>No-Render prop function that receives order data and loading states

Order.Field​

Generic component for displaying any order property. Must be used within Order.Root.

Props

PropTypeRequiredDefaultDescription
fieldkeyof OrderTypeYes-The order field to display (e.g., 'code', 'state', 'totalQuantity')
formatter(value: OrderType[keyof OrderType]) => stringNo-Optional function to format the value
childrenReact.ReactNode | ((props: { value, formattedValue }) => React.ReactNode)No-Optional render prop or content
asChildbooleanNofalseRender as a child element instead of a div

Order.Items​

Container component for displaying order items. Must be used within Order.Root.

Order.Items.Root​

Container that provides order lines context. Uses the order code from Order.Root context automatically. Provides order lines via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: { orderLines: OrderLine[] | undefined }) => React.ReactNode)No-Render prop that receives order lines array

Order.Items.Item​

Individual order item component. Must be used within Order.Items.Root.

Props

PropTypeRequiredDefaultDescription
orderLineOrderLineYes-The order line data to display
asChildbooleanNofalseRender as a child element instead of default element

Order.Items.Image​

Product image display component. Must be used within Order.Items.Item. Inherits from OrderLines.Image component, from @haus-storefront-react/order-lines.

Order.Items.Price​

Price display component for order lines. Must be used within Order.Items.Item. Inherits from OrderLines.Price component, from @haus-storefront-react/order-lines.

Order.ShippingLines​

Container component for shipping lines. Must be used within Order.Root. Provides shipping lines array to children via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: { shippingLines }) => React.ReactNode)No-Render prop that receives shipping lines array
asChildbooleanNofalseRender as a child element instead of a div

Order.ShippingLine​

Individual shipping line component. Must be used within Order.ShippingLines. Provides shipping method name, price, price with tax, and currency code to children via render prop.

PropTypeRequiredDefaultDescription
shippingLineShippingLineYes-The shipping line data to display
childrenReact.ReactNode | ((props: { name, price, priceWithTax, currencyCode }) => React.ReactNode)No-Render prop that receives shipping data
asChildbooleanNofalseRender as a child element instead of a div

Order.Summary​

Summary component for displaying order totals. Must be used within Order.Root. Provides order summary data to children via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: OrderSummaryData) => React.ReactNode)No-Render prop that receives order summary data
asChildbooleanNofalseRender as a child element instead of a div

Render Prop Data

PropertyTypeDescription
totalPricenumberOrder total price (without tax)
totalWithTaxnumberOrder total price (with tax)
subTotalnumberOrder subtotal (without tax)
subTotalWithTaxnumberOrder subtotal (with tax)
shippingnumberShipping cost (without tax)
shippingWithTaxnumberShipping cost (with tax)
taxSummaryOrderTaxSummary[]Array of tax summary entries
currencyCodeCurrencyCodeCurrency code for the order

Order.Addresses​

Container component for displaying shipping and billing addresses. Must be used within Order.Root.

Order.Addresses.Root​

Container for address components.

Props

PropTypeRequiredDefaultDescription
asChildbooleanNofalseRender as a child element instead of a div
childrenReact.ReactNodeNo-Child components

Order.Addresses.Shipping​

Component that provides shipping address to children via render prop. Must be used within Order.Addresses.Root.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((address: OrderAddress | null) => React.ReactNode)No-Render prop that receives shipping address or null
asChildbooleanNofalseRender as a child element instead of a div

Order.Addresses.Billing​

Component that provides billing address to children via render prop. Must be used within Order.Addresses.Root.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((address: OrderAddress | undefined | null) => React.ReactNode)No-Render prop that receives billing address, undefined, or null
asChildbooleanNofalseRender as a child element instead of a div

useOrderContext​

Internal hook for accessing Order context. Used internally by Order components. Not typically needed by consumers, but exported for advanced use cases.

Parameters

ParameterTypeRequiredDescription
componentNamestringYesComponent name for error messaging
scopeScopeNoOptional scope for context isolation

Returns

OrderContextValue - Order context value with order data and loading states

createOrderScope​

Creates a new scope for Order context. Used for advanced use cases when multiple Order instances need to be nested.

Returns

Scope - A new scope identifier for Order context

Basic Usage​

Simple Order Display​

import { Order } from '@haus-storefront-react/order'
import { Price } from '@haus-storefront-react/common-ui'

function OrderConfirmation({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, error, isError, isSuccess }) => (
<div>
{isLoading && <div>Loading...</div>}
{isError && error && <div>Error: {error.message}</div>}

{isSuccess && order && (
<div>
<h2>Thank you for your order!</h2>
<p>Order #{order.code}</p>
<p>
Placed on {new Date(order.orderPlacedAt).toLocaleDateString()}
</p>
<p>Status: {order.state}</p>

<Order.Items.Root>
{({ orderLines }) =>
orderLines?.map((line) => (
<Order.Items.Item key={line.id} orderLine={line}>
<Order.Items.Image />
<Order.Items.Price />
<span>{line.quantity} x</span>
</Order.Items.Item>
))
}
</Order.Items.Root>

<Order.Summary>
{({ totalPrice, currencyCode }) => (
<div>
<p>
Total: {totalPrice} {currencyCode}
</p>
</div>
)}
</Order.Summary>
</div>
)}
</div>
)}
</Order.Root>
)
}

Basic Hook Usage​

The Order component uses hooks internally via useOrderProps. For direct order fetching, use hooks from @haus-storefront-react/hooks:

import { useOrderByCode } from '@haus-storefront-react/hooks'

function MyComponent({ orderCode }) {
const { data: order, isLoading, error } = useOrderByCode(orderCode)

if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
if (!order) return <div>Order not found</div>

return (
<div>
<h1>Order #{order.code}</h1>
<p>Status: {order.state}</p>
</div>
)
}

Advanced Usage​

Using Order.Field for Custom Display​

import { Order } from '@haus-storefront-react/order'

function OrderWithCustomFields({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, isSuccess }) => {
if (!isSuccess || !order) return null

return (
<div>
<Order.Field field='code'>
{({ value, formattedValue }) => (
<h1>Order #{formattedValue}</h1>
)}
</Order.Field>

<Order.Field
field='orderPlacedAt'
formatter={(value) => new Date(value).toLocaleDateString()}
>
{({ formattedValue }) => <p>Placed on {formattedValue}</p>}
</Order.Field>

<Order.Field field='state'>
{({ value }) => (
<span className={`status status-${value?.toLowerCase()}`}>
{value}
</span>
)}
</Order.Field>

<Order.Field field='totalQuantity'>
{({ value }) => <p>Total items: {value}</p>}
</Order.Field>
</div>
)
}}
</Order.Root>
)
}

Order History List​

import { Order } from '@haus-storefront-react/order'
import { useActiveCustomerOrders } from '@haus-storefront-react/hooks'
import { Price } from '@haus-storefront-react/common-ui'

function OrderHistory() {
const {
data: orders,
isLoading,
error,
} = useActiveCustomerOrders({
take: 20,
})

if (isLoading) return <div>Loading orders...</div>
if (error) return <div>Error: {error.message}</div>
if (!orders?.items.length) return <div>No orders found</div>

return (
<div className='order-history'>
<h1>Order History</h1>

{orders.items.map((order) => (
<Order.Root key={order.id} orderCode={order.code}>
{({ order: orderData, isLoading: orderLoading, isSuccess }) => (
<div className='order-history-item'>
{orderLoading && <div>Loading order details...</div>}

{isSuccess && orderData && (
<>
<div className='order-header'>
<h3>Order #{orderData.code}</h3>
<span className='order-date'>
{new Date(orderData.orderPlacedAt).toLocaleDateString()}
</span>
</div>

<div className='order-summary'>
<div className='order-items-count'>
{orderData.totalQuantity} items
</div>

<div className='order-total'>
<Price.Root
price={orderData.total}
priceWithTax={orderData.totalWithTax}
currencyCode={orderData.currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>

<div className='order-status'>
<span
className={`status-badge status-${orderData.state.toLowerCase()}`}
>
{orderData.state}
</span>
</div>
</div>

<div className='order-actions'>
<a href={`/orders/${orderData.code}`}>View Details</a>
</div>
</>
)}
</div>
)}
</Order.Root>
))}
</div>
)
}

Conditional Rendering Patterns​

import { Order } from '@haus-storefront-react/order'
import { Price } from '@haus-storefront-react/common-ui'

function ConditionalOrderDisplay({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, isError, isSuccess }) => {
if (isLoading) {
return (
<div className='order-loading'>
<div className='spinner' />
<p>Loading order details...</p>
</div>
)
}

if (isError || !isSuccess) {
return (
<div className='order-error'>
<p>Unable to load order details.</p>
<button onClick={() => window.location.reload()}>
Try Again
</button>
</div>
)
}

if (!order) {
return (
<div className='order-not-found'>
<p>Order not found.</p>
</div>
)
}

return (
<div className='order-display'>
<div className='order-header'>
<h1>Order #{order.code}</h1>
<Order.Field field='state'>
{({ value }) => (
<span className={`badge badge-${value?.toLowerCase()}`}>
{value}
</span>
)}
</Order.Field>
</div>

<Order.Items.Root>
{({ orderLines }) =>
orderLines && orderLines.length > 0 ? (
orderLines.map((line) => (
<Order.Items.Item key={line.id} orderLine={line}>
<Order.Items.Image />
<div className='item-info'>
<h3>{line.productVariant.product.name}</h3>
<p>Quantity: {line.quantity}</p>
</div>
<Order.Items.Price />
</Order.Items.Item>
))
) : (
<p>No items in this order</p>
)
}
</Order.Items.Root>

{order.shippingLines && order.shippingLines.length > 0 ? (
<Order.ShippingLines>
{({ shippingLines }) => (
<div className='shipping-section'>
<h2>Shipping</h2>
{shippingLines.map((shippingLine) => (
<Order.ShippingLine
key={shippingLine.id || shippingLine.shippingMethod.id}
shippingLine={shippingLine}
>
{({ name, price, priceWithTax, currencyCode }) => (
<div className='shipping-line'>
<span>{name}</span>
<Price.Root
price={price}
priceWithTax={priceWithTax}
currencyCode={currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>
)}
</Order.ShippingLine>
))}
</div>
)}
</Order.ShippingLines>
) : (
<p>No shipping information available</p>
)}

<Order.Summary>
{({ totalPrice, totalWithTax, currencyCode }) => (
<div className='order-total'>
<h2>Total</h2>
<Price.Root
price={totalPrice}
priceWithTax={totalWithTax}
currencyCode={currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>
)}
</Order.Summary>
</div>
)
}}
</Order.Root>
)
}

Made with ❤️ by Haus Tech Team