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

# Deployment

> Deploy your Crave storefront to Vercel, Netlify, or custom hosting.

Crave storefront templates are standard Next.js apps. Deploy them anywhere that supports Node.js or static hosting. This guide covers Vercel (recommended), Netlify, and custom setups.

## Environment variables

Before deploying, make sure these variables are set in your hosting platform's environment settings:

| Variable                             | Required          | Description                             |
| ------------------------------------ | ----------------- | --------------------------------------- |
| `NEXT_PUBLIC_CRAVEUP_API_KEY`        | Yes               | Production API key from the Dashboard   |
| `NEXT_PUBLIC_LOCATION_ID`            | Yes               | Location ID to serve                    |
| `NEXT_PUBLIC_LOCATION_SLUG`          | Yes               | Location slug for merchant lookups      |
| `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Yes               | Stripe publishable key for payments     |
| `CRAVEUP_WEBHOOK_SECRET`             | If using webhooks | Secret for verifying webhook signatures |

<Warning>
  Use production API keys (`sk_live_...`) for your production deployment. Test keys (`sk_test_...`) do not create real orders.
</Warning>

## Deploy to Vercel

Vercel is the recommended platform for Next.js storefronts. It provides edge caching, serverless functions, and preview deployments.

<Steps>
  <Step title="Push to Git">
    Push your storefront to a GitHub, GitLab, or Bitbucket repository.
  </Step>

  <Step title="Import in Vercel">
    Go to [vercel.com/new](https://vercel.com/new), import your repository, and select the Next.js framework preset.
  </Step>

  <Step title="Set environment variables">
    Add your production environment variables in the Vercel project settings.
  </Step>

  <Step title="Deploy">
    Vercel builds and deploys automatically on every push to your main branch.
  </Step>
</Steps>

Or deploy from the CLI:

```bash theme={null}
npx vercel --prod
```

### Custom domain

Add your domain in Vercel's project settings under **Domains**. For a branded storefront, use a subdomain:

```
order.yourrestaurant.com
```

## Deploy to Netlify

```bash theme={null}
# Install the Netlify CLI
npm install -g netlify-cli

# Build and deploy
netlify deploy --prod --dir=.next
```

Set environment variables in the Netlify dashboard under **Site settings > Environment variables**.

<Note>
  Netlify requires the `@netlify/plugin-nextjs` plugin for full Next.js support. Add it in your `netlify.toml` or install via the Netlify dashboard.
</Note>

## Custom hosting

For Docker, VPS, or other setups, build and start the Next.js production server:

```bash theme={null}
# Build
pnpm build

# Start the production server
pnpm start -p 3000
```

### Docker

```dockerfile filename="Dockerfile" theme={null}
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build

FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]
```

Enable standalone output in your Next.js config:

```ts filename="next.config.ts" theme={null}
const nextConfig = {
  output: 'standalone',
};

export default nextConfig;
```

## Performance checklist

After deploying, verify these optimizations:

* **Images**: Product images should be served through `next/image` for automatic optimization
* **Caching**: Location and menu data changes infrequently — cache it with `revalidate` in server components
* **Bundle size**: Run `npx next build` and check the output for large pages (aim for \< 100kB first load JS)
* **Core Web Vitals**: Test with [PageSpeed Insights](https://pagespeed.web.dev/) — aim for all green scores

```tsx filename="src/app/page.tsx" theme={null}
// Cache merchant data for 5 minutes
export const revalidate = 300;

export default async function HomePage() {
  const merchant = await storefront.merchant.getBySlug('downtown-pizza');
  // ...
}
```

## Monitor in production

Track API errors and storefront health:

```ts theme={null}
import { ApiError } from '@craveup/storefront-sdk';

try {
  await storefront.cart.get(locationId, cartId);
} catch (error) {
  if (error instanceof ApiError) {
    // Send to your error tracking service
    Sentry.captureException(error, {
      extra: { status: error.status, url: error.url },
    });
  }
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Analytics" icon="bar-chart-3" href="/guides/analytics">
    Track storefront events and funnel performance.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Receive real-time order lifecycle notifications.
  </Card>
</CardGroup>
