Docs/Store Features

Store Features

Overview of all features in the PhantomWP headless WooCommerce storefront.

Store Features

⚠️

WooCommerce integration is experimental. Features listed here are functional but may change as we refine the experience.

This page covers everything the headless storefront includes out of the box.

Architecture

The storefront follows a hybrid approach:

  • Product pages are pre-rendered at build time from synced JSON data (fast, static)
  • Cart is client-side using nanostores and localStorage (no server needed)
  • Checkout, orders, and auth use server-side API routes that call WooCommerce's REST API in real-time

This means product browsing is instant (served from CDN) while transactional features stay connected to your live WooCommerce backend.

Pages

The template generates these pages:

RoutePurpose
/Homepage with featured products and categories
/shopProduct grid with filtering and sorting
/shop/product/[slug]Product detail with images, description, variations
/shop/category/[slug]Products filtered by category
/cartShopping cart with quantity management
/checkoutCheckout form with dynamic shipping and payment
/order-completeOrder confirmation after payment
/searchProduct search by name, description, SKU
/loginCustomer sign-in
/registerCustomer registration
/forgot-passwordRequest password reset email
/reset-passwordSet new password (from email link)
/accountAccount dashboard with quick links
/account/ordersFull order history
/account/addressesManage billing and shipping addresses
/account/settingsUpdate name and change password

Product Data

Products are synced from WooCommerce and stored locally:

  • src/data/products.json - All product data (name, price, images, categories, variations, stock, etc.)
  • src/data/categories.json - Product categories
  • src/media/products/ - Downloaded product images (optimized by Astro at build time)
  • src/lib/product-media-map.json - Maps WooCommerce image URLs to local paths

Data Access

All product data functions are async:

import {
    getLocalProducts,
    getLocalProduct,
    getLocalCategories,
    getLocalVisibleCategories,
    getLocalProductsByCategory,
    getLocalFeaturedProducts,
    getLocalRelatedProducts,
} from '../lib/local-product-data';

Helpers

import { formatPrice, isInStock, getDiscountPercentage, stripHtml } from '../lib/woocommerce';

Cart

The cart is entirely client-side using nanostores for reactive state. No server round-trips for adding/removing items.

import {
    $cart, $cartCount, $cartTotal,
    addToCart, removeFromCart, updateQuantity, clearCart,
    openCartDrawer, closeCartDrawer,
} from '../lib/cart';

Cart data persists in localStorage across page navigations and browser sessions.

Authentication

Customer authentication uses the WordPress JWT Authentication plugin. The WordPress admin panel (wp-login.php) is assumed to be locked down - all auth flows go through the Astro API routes.

Login and Registration

import {
    $isLoggedIn, $user, $token,
    login, register, logout,
    getToken, initAuth,
    requestPasswordReset,
} from '../lib/auth';
  • login(email, password) calls /api/auth/login which authenticates via the JWT plugin
  • register({ email, password, firstName?, lastName? }) creates a WooCommerce customer
  • Auth state (token + user info) is stored in localStorage

Password Reset

The forgot password flow is self-contained and does not depend on WordPress's wp-login.php:

  1. User submits email on /forgot-password
  2. API route looks up the customer via WooCommerce REST API
  3. A signed JWT token (1 hour expiry) is generated with the customer ID
  4. An email is sent with a link to /reset-password?token=...
  5. The reset page validates the token and updates the password via PUT /wc/v3/customers/{id}

API Routes

RouteMethodPurpose
/api/auth/loginPOSTAuthenticate via WordPress JWT
/api/auth/registerPOSTCreate a WooCommerce customer
/api/auth/validatePOSTValidate a JWT token
/api/auth/forgot-passwordPOSTSend password reset email
/api/auth/reset-passwordPOSTVerify token and set new password

Checkout

The checkout page dynamically loads configuration from your WooCommerce store:

  • Payment gateways - Reads enabled gateways from WooCommerce
  • Shipping zones and methods - Loads zones, methods, and costs
  • Customer addresses - Pre-fills billing/shipping if logged in
  • Stock validation - Checks availability before order submission

Order Flow

  1. Customer fills in the checkout form
  2. Stock is validated via /api/stock/check
  3. Order is created via /api/orders/create
  4. Customer is redirected to the payment gateway (Stripe/PayPal)
  5. After payment, the customer lands on /order-complete
  6. Webhook from the payment provider marks the WooCommerce order as paid

Payment Gateways

Two gateways are built in:

Stripe - Uses Stripe Checkout (redirect flow). Requires Stripe keys in .env and a webhook endpoint for payment confirmation.

PayPal - Uses the PayPal Orders API. Supports both sandbox and live modes.

Additional gateways (like cash on delivery or bank transfer) appear at checkout if enabled in WooCommerce, but redirect-based payment is only handled for Stripe and PayPal. To test the checkout flow without setting up a payment provider, enable Direct bank transfer (BACS) in WooCommerce -- orders will be created with a "Pending payment" status without needing any API keys.

Customer Account

Logged-in customers can:

  • View order history (/account/orders)
  • Manage billing and shipping addresses (/account/addresses)
  • Update their name and password (/account/settings)

All account operations use the WooCommerce REST API with JWT token authentication.

API Routes

RouteMethodPurpose
/api/customer/meGETGet current customer profile
/api/customer/ordersGETGet order history
/api/customer/addressesGET/PUTRead or update addresses
/api/customer/settingsPUTUpdate name or password

Components

Astro Components (src/components/shop/)

ComponentPurpose
ProductCard.astroProduct card with image, price, add-to-cart
ProductImage.astroResolves local/remote images with fallback
AddToCartButton.astroButton that adds product to cart
CartDrawer.astroWrapper for the React cart drawer

React Components (src/components/react/)

These need client:load for hydration:

ComponentPurpose
CartDrawer.tsxSlide-out cart with item management
AddToCartButton.tsxInteractive add-to-cart with quantity selector
ProductCard.tsxClient-side product card variant
ProductImage.tsxImage with loading states
RecentOrders.tsxDisplays customer order history

Limitations

Since this feature is experimental, there are some current limitations:

  • No real-time inventory - Product stock is from the last sync, not live. Stock is validated at checkout time, but the product page may show outdated availability.
  • No product variations UI - Variable products are supported in data, but the product page does not yet show a variation picker (e.g. size/color dropdowns).
  • No coupons - Coupon code entry at checkout is not yet implemented.
  • No order tracking - Customers can see order status but there is no shipment tracking integration.
  • Image sync is manual - Product data auto-syncs, but product images in development need to be re-synced manually after adding new images in WooCommerce.
  • Email delivery - The forgot password flow relies on being able to send email from the server. This works well on hosted platforms but may need configuration in development.

Next Steps