> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Storefront Starter

> Start from a self-hosted Next.js storefront with Shoppex products, cart, checkout, customer portal links, and webhook fulfillment already wired.

The Shoppex Storefront Starter is for merchants who want a custom storefront without rebuilding commerce.

Simple example:

```txt theme={"system"}
yourdomain.com          -> your Next.js storefront
checkout.shoppex.io     -> Shoppex hosted checkout
account.yourdomain.com  -> Shoppex customer portal
```

<Info>
  Use this starter when you want to own the frontend. Use a hosted Shoppex theme when you want Shoppex to own the storefront UI too.
</Info>

## Create a Storefront

```bash theme={"system"}
bunx create-shoppex-storefront my-store
cd my-store
bun install
bun run dev
```

For non-interactive setup:

```bash theme={"system"}
bunx create-shoppex-storefront my-store \
  --shop-slug your-shop \
  --customer-portal-url https://account.yourdomain.com \
  --checkout-mode cart
```

The command creates a Next.js app, writes `.env.local`, and points the starter at your Shoppex shop.

## What Is Included

<CardGroup cols={2}>
  <Card title="Storefront UI" icon="store">
    Homepage, product grid, product detail pages, product images, variants, stock count, and sold-out states.
  </Card>

  <Card title="Cart and Checkout" icon="cart-shopping">
    Browser-local cart, checkout review, email capture, coupon field, terms acknowledgement, and Shoppex invoice handoff.
  </Card>

  <Card title="Customer Portal Link" icon="user">
    Link buyers to orders, downloads, license keys, and support through the Shoppex customer portal.
  </Card>

  <Card title="Webhook Example" icon="webhook">
    Signed webhook route for paid order events, with a Discord notification example for fulfillment visibility.
  </Card>
</CardGroup>

## Configure Shoppex

Set these values in `.env.local`:

```txt theme={"system"}
NEXT_PUBLIC_SHOPPEX_SHOP_SLUG=your-shop
NEXT_PUBLIC_CUSTOMER_PORTAL_URL=https://account.yourdomain.com
SHOPPEX_WEBHOOK_SECRET=whsec_your_secret
SHOPPEX_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
```

Then edit:

```txt theme={"system"}
shoppex.config.ts
theme.config.ts
```

Simple example:

```ts theme={"system"}
export const shoppexConfig = {
  shopSlug: process.env.NEXT_PUBLIC_SHOPPEX_SHOP_SLUG ?? "demo",
  checkoutMode: "cart",
  showStockCount: true,
  customerPortal: {
    mode: "branded-subdomain",
    url: process.env.NEXT_PUBLIC_CUSTOMER_PORTAL_URL ?? "https://demo.myshoppex.io/dashboard",
  },
};
```

## Checkout Modes

| Mode      | Use it for                                                               |
| --------- | ------------------------------------------------------------------------ |
| `cart`    | Normal stores with multiple products and a cart drawer                   |
| `buy-now` | One-product stores where the product page should go straight to checkout |
| `embed`   | Simple product-button flows that use the Checkout Embed SDK              |

The default is `cart`.

## Cart Model

The starter cart lives in the buyer's browser until checkout.

At checkout, Shoppex rechecks:

* product availability
* selected variants
* quantity limits
* prices
* coupons
* stock

If something changed, the checkout page shows a recovery state instead of a generic error.

Simple example:

```txt theme={"system"}
Buyer has 5 items in cart
Shop stock changes to 2
Checkout asks the buyer to reduce the quantity before payment
```

<Warning>
  The starter does not reserve stock when a buyer adds an item to the cart. Stock is validated when the Shoppex invoice is created.
</Warning>

## Customer Portal

For a fully self-hosted storefront, use a branded account subdomain:

```txt theme={"system"}
yourdomain.com          -> Next.js storefront
account.yourdomain.com  -> Shoppex customer portal
```

Fastest setup:

```txt theme={"system"}
https://your-shop.myshoppex.io/dashboard
```

Use `/dashboard` only when the storefront domain is routed through the Shoppex Storefront Worker.

## Moving from Another Platform

Treat this as a fresh storefront cutover.

Move these into Shoppex:

* products
* prices
* variants
* stock
* checkout settings
* fulfillment webhooks

The starter does not automatically import old order history, old customer accounts, or previous platform-specific embeds.

## Deploy

Deploy the generated project to Vercel and set the same environment variables there.

```txt theme={"system"}
NEXT_PUBLIC_SHOPPEX_SHOP_SLUG
NEXT_PUBLIC_CUSTOMER_PORTAL_URL
SHOPPEX_WEBHOOK_SECRET
SHOPPEX_DISCORD_WEBHOOK_URL
```

After deploy, create a Shoppex webhook endpoint:

```txt theme={"system"}
https://yourdomain.com/api/shoppex/webhook
```

Subscribe it to paid order events such as `order:paid` and `order:paid:product`.

## Next Steps

<CardGroup cols={2}>
  <Card title="Headless Overview" icon="sitemap" href="/headless/overview">
    Understand the three integration shapes: Dev API, Storefront SDK, and Checkout Embed SDK.
  </Card>

  <Card title="Checkout Embed SDK" icon="window-maximize" href="/guides/embeds">
    Add modal checkout to existing pages or product buttons.
  </Card>

  <Card title="Storefront SDK" icon="browser" href="/sdk/introduction">
    Read public product and storefront data from your custom frontend.
  </Card>

  <Card title="Webhooks" icon="bolt" href="/api-reference/webhooks/overview">
    Verify paid order events and run fulfillment after payment.
  </Card>
</CardGroup>
