Skip to main content

Tracking Page UI & Display

This document covers the tracking page UI and display logic for presenting order status to customers.

Accessing Tracking Pagesโ€‹

Routesโ€‹

  • Hydrogen: /pages/tracking?o={orderId} or /pages/tracking?order={orderNumber}
  • Theme: Same URL structure, renders via sections/tracking.liquid

Customer Verificationโ€‹

The system determines if a logged-in customer owns the order:

{% for order in customer.orders %}
{% if query_order_id contains order.id %}
{% assign customer_verified = true %}
{% endif %}
{% endfor %}

Verified customers see:

  • Full shipping address with ZIP code
  • Billing address and payment method
  • Account sidebar navigation
  • Breadcrumb navigation

Guest customers see:

  • City and state only (privacy protection)
  • No billing/payment details
  • No account navigation

Shipment Groupingโ€‹

Fulfillment to Shipment Mappingโ€‹

// Each fulfillment becomes a shipment card
shipments = order.fulfillments.map(fulfillment => ({
...matchingAftershipShipment, // matched by tracking_number
line_items: lineItems.filter(item => fulfillment.line_items.includes(item)),
fulfillment: fulfillment
}));

// Unfulfilled items get their own card
const unfulfilled = {
line_items: lineItems.filter(item => !item.fulfillment_status)
};
if (unfulfilled.line_items.length > 0) {
shipments.push(unfulfilled);
}

Business Rule:

  • Each fulfillment = separate shipment card
  • Unfulfilled items = separate card showing "Ordered" status
  • Multiple packages are numbered: "Package 1 of 3", "Package 2 of 3", etc.

"On Time" Indicatorโ€‹

Display Ruleโ€‹

if (shipments.length > 1 && shipment.on_time_status === "on-time") {
display "โ€ข On Time" badge
}

Business Context:

  • Only shown when there are multiple packages
  • Aftership calculates by comparing actual progress vs. carrier's promised delivery date
  • Helps customers know which packages are tracking normally

Checkpoint Filtering Rulesโ€‹

Checkpoints to Excludeโ€‹

The system filters out checkpoints that don't provide value to customers:

// DON'T SHOW checkpoint if ANY of these are true:

// 1. Customs clearance events
checkpoint.subtag === "InTransit_004" ||
checkpoint.subtag === "InTransit_005" ||
checkpoint.subtag === "InTransit_006" ||

// 2. China origin scans
checkpoint.country_iso3 === "CHN" ||
checkpoint.location === "CN" ||
checkpoint.city?.toLowerCase() === "hangzhou" ||

// 3. Generic messages
checkpoint.message === "Departure" ||

// 4. Duplicate timestamps
checkpoint.checkpoint_time === previousCheckpoint.checkpoint_time

Business Contextโ€‹

  • China origin scans: Clutter the timeline without providing value to US customers
  • Customs events: Confusing and not actionable
  • Generic messages: "Departure" is vague and unhelpful
  • Duplicates: Carriers sometimes send multiple status updates simultaneously

Exception Handlingโ€‹

Display Logicโ€‹

if (shipment.tag === "Exception") {
// Show exception UI
displayStatus = "Delivery Exception";
displayMessage = "Your item may be delayed or lost. Contact support.";

// But use previous valid tag for progress stepper
stepperTag = shipment.checkpoints
.findLast(cp => cp.tag !== "Exception")
.tag;
}

Business Context: Shows customer there's a problem, but maintains context of where the package last was. For example, "Exception" after "In Transit" will still show the in-transit checkpoint in the detailed stepper.

Expired Tracking Logicโ€‹

Detectionโ€‹

const isOrderExpired = !aftershipStatus && isFulfilled;

Business Ruleโ€‹

If order was fulfilled in Shopify but Aftership has no status (30+ days of no tracking updates):

  • Assume delivered
  • Show "Delivered" status
  • Don't show tracking details or stepper

Handles These Scenariosโ€‹

  • Very old orders where tracking has expired
  • Carriers that don't provide long-term tracking data
  • Manual fulfillments without tracking numbers
  • Packages delivered but carrier never updated final status

Theme Repositoryโ€‹

  • sections/tracking.liquid - Main tracking page section
  • assets/tracking--order.js - Web Component with business logic
  • assets/tracking--get-order.js - API integration
  • assets/tracking--get-shipment-status.js - Status determination logic
  • assets/tracking--statuses.js - Status definitions and mappings
  • snippets/tracking--order-shipments-v2.liquid - Shipment UI structure
  • snippets/tracking--order-details.liquid - Order header
  • snippets/tracking--order-summary-v2.liquid - Order totals and pricing
  • snippets/global--store-variables.liquid - Timeline configurations