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:
| Route | Purpose |
|---|---|
/ | Homepage with featured products and categories |
/shop | Product grid with filtering and sorting |
/shop/product/[slug] | Product detail with images, description, variations |
/shop/category/[slug] | Products filtered by category |
/cart | Shopping cart with quantity management |
/checkout | Checkout form with dynamic shipping and payment |
/order-complete | Order confirmation after payment |
/search | Product search by name, description, SKU |
/login | Customer sign-in |
/register | Customer registration |
/forgot-password | Request password reset email |
/reset-password | Set new password (from email link) |
/account | Account dashboard with quick links |
/account/orders | Full order history |
/account/addresses | Manage billing and shipping addresses |
/account/settings | Update 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 categoriessrc/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/loginwhich authenticates via the JWT pluginregister({ 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:
- User submits email on
/forgot-password - API route looks up the customer via WooCommerce REST API
- A signed JWT token (1 hour expiry) is generated with the customer ID
- An email is sent with a link to
/reset-password?token=... - The reset page validates the token and updates the password via
PUT /wc/v3/customers/{id}
API Routes
| Route | Method | Purpose |
|---|---|---|
/api/auth/login | POST | Authenticate via WordPress JWT |
/api/auth/register | POST | Create a WooCommerce customer |
/api/auth/validate | POST | Validate a JWT token |
/api/auth/forgot-password | POST | Send password reset email |
/api/auth/reset-password | POST | Verify 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
- Customer fills in the checkout form
- Stock is validated via
/api/stock/check - Order is created via
/api/orders/create - Customer is redirected to the payment gateway (Stripe/PayPal)
- After payment, the customer lands on
/order-complete - 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
| Route | Method | Purpose |
|---|---|---|
/api/customer/me | GET | Get current customer profile |
/api/customer/orders | GET | Get order history |
/api/customer/addresses | GET/PUT | Read or update addresses |
/api/customer/settings | PUT | Update name or password |
Components
Astro Components (src/components/shop/)
| Component | Purpose |
|---|---|
ProductCard.astro | Product card with image, price, add-to-cart |
ProductImage.astro | Resolves local/remote images with fallback |
AddToCartButton.astro | Button that adds product to cart |
CartDrawer.astro | Wrapper for the React cart drawer |
React Components (src/components/react/)
These need client:load for hydration:
| Component | Purpose |
|---|---|
CartDrawer.tsx | Slide-out cart with item management |
AddToCartButton.tsx | Interactive add-to-cart with quantity selector |
ProductCard.tsx | Client-side product card variant |
ProductImage.tsx | Image with loading states |
RecentOrders.tsx | Displays 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
- WooCommerce Setup - How to connect your store
- Deploying to Vercel - Deploy your headless store to production