---
title: 'In the box'
description: 'Every integration that ships pre-wired in the default profile so a Cartwright shop can go live in an afternoon — and the one thing a plain site needs.'
canonical: 'https://cartwright.app/docs/in-the-box'
---

# In the box (/docs/in-the-box)



<Callout type="info" title="Which profile is this page about?">
  This tour describes the default `light` profile and `full&#x60;. The database-free &#x2A;*`site`** profile (`npx create-cartwright@latest my-site --profile site`) needs none of these keys: hosting is Vercel, the Sentry hooks ship dormant (no DSN → no-op), and the only service it calls is Resend for the optional contact form. It ships designed pages (8 design packs), SEO/JSON-LD, sitemap, `llms.txt`, locale routing and an OG-image route, boots with zero environment variables and builds with plain `next build` — ~22 s to scaffold, ~27 s to build. See [Build a plain website](/docs/getting-started/plain-website). And the default profile itself scaffolds in **website mode** (the `website-corporate` template): no cart, no Stripe checkout until you choose a shop template or switch `mode` — a contact or quote form lands as a lead in `/admin/leads` either way. The Payments section below applies to shop templates.
</Callout>

A Cartwright shop ships with the integrations that normally take a sprint each to wire — payments, email, auth, hosting, database, storage, observability, rate limiting, i18n, and the AI providers. Paste a key in `/admin/setup` and the storefront is already calling the right SDK behind it. The CLI scaffolds the wiring; the wizard collects the keys; the deploy happens on Vercel; the first real order is possible in an afternoon, not a quarter.

This page is the integration-by-integration tour. The [Feature Grid](/) on the home page lists capabilities; this page lists the platforms underneath them.

## Payments → Stripe [#payments--stripe]

Stripe is the default payment processor. Cartwright ships with Stripe Elements (Payment Element, not the legacy Checkout page) so the checkout UI lives inside your storefront, styled by `brand.config.ts:stripeAppearance`. Webhook handling is wired at `/api/stripe/webhook` with signature verification and idempotency keys; payment-intent state transitions land in `Order` rows and the audit log in the same transaction.

For local development there's a mock-mode fallback — the test key prefix toggles a stubbed processor that produces realistic success and failure paths without sending real traffic. Test mode vs live mode is a switch in `/admin/integrations`; no redeploy.

Keys are DB-first via `lib/secret-encryption.ts` (AES-256-GCM). Paste them into the setup wizard, rotate them whenever. The Vercel env var only holds the encryption seed.

## Email → Resend [#email--resend]

Resend handles every transactional email a shop sends — order confirmation, shipping update, magic-link sign-in, customer service replies. Templates live in `lib/email/templates/` as React components; preview them in dev at `.mail-previews/` without burning credits.

Custom domain setup is part of the same setup wizard that handles Vercel DNS: pick a domain, Cartwright generates the SPF, DKIM, and DMARC records, then polls Resend until verification reports green. From the merchant's seat it's "fill in a domain, wait a minute"; the underlying flow is the same one you'd otherwise read three blog posts to assemble.

Beyond transactional mail, an opt-in `marketingAutomations` flag turns Resend into the shop's lifecycle email engine: Cartwright emits welcome, abandoned-cart, and post-purchase events to [Resend Automations](https://resend.com/features/automations), which runs the drip sequences you wire in its dashboard. Cartwright emits events only — it stays the source of truth without becoming a marketing-automation platform — and emission is consent-gated to confirmed newsletter subscribers. Default-off; inert without a Resend key.

## Authentication → NextAuth + Resend [#authentication--nextauth--resend]

Magic-link sign-in via NextAuth (Auth.js). Resend ships the actual email; NextAuth runs the token machinery. No password store, no third-party identity vendor, no SOC 2 dependency on someone else's auth provider. Your `User` and `Session` tables live in your own database; users own their accounts.

For shops that want OAuth providers added (Google, GitHub, Apple), the NextAuth `providers` array in `app/api/auth/[...nextauth]/route.ts` is the one place to extend. The rest of the auth surface — middleware, route protection, admin gating — keeps working as-is.

## Hosting → Vercel [#hosting--vercel]

One Next.js app, one deploy. The storefront, admin, agent endpoints, MCP server, and ACP routes all compile into the same Vercel project. Preview branches deploy automatically — every PR gets a URL. Production promotes by merge.

Custom domains are handled by the setup wizard: paste the domain, Cartwright prints the DNS records (`A` + `CNAME` + the Vercel verification record), and waits until both Vercel and Resend report verified. Source-map upload to Sentry happens in the same build.

Fluid Compute is the default runtime — Node.js everywhere, including middleware. No edge-runtime compatibility dance, no separate function bundles for different routes.

## Database → Turso [#database--turso]

Turso is the default database (managed libSQL — a fork of SQLite). Edge-replicated, point-in-time restore, sub-50ms reads from a Vercel function cold start. `DATABASE_URL` + `TURSO_AUTH_TOKEN` is the entire setup; Prisma uses the libSQL adapter so the schema and migrations look exactly like a standard Prisma project.

For local development a file-based SQLite database is the canonical fallback — `prisma migrate dev` works against `dev.db` without any network. Switching to Turso for production is two env vars and a `prisma migrate deploy`.

## File storage → Vercel Blob [#file-storage--vercel-blob]

Product images, category covers, generated Luma video clips, OG images — all land in Vercel Blob via signed-URL uploads from the admin. Image variants (thumbnail, card, hero) are produced on demand; you don't pre-render every size at upload time.

The integration with `next/image` is direct — Blob URLs are recognised as remote patterns automatically, so optimisation, format conversion, and CDN delivery come for free.

## Observability → Sentry [#observability--sentry]

Error tracking and performance traces are pre-wired. Builds upload source maps via `SENTRY_AUTH_TOKEN` so production stack traces resolve to your actual TypeScript. Server-side, every API route is wrapped; client-side, the React error boundary integrates with Sentry's session replay.

Cost-control sampling is configured by default (`tracesSampleRate: 0.1` in production). The dev environment doesn't send to Sentry at all unless you explicitly opt in — local errors stay on your machine.

## Rate limiting → Upstash [#rate-limiting--upstash]

Upstash Redis backs `lib/rate-limit.ts:createRateLimiter()`. Per-IP and per-API-key throttling is already applied to storefront chat, agent endpoints, admin write actions, and the negotiation surface. The limits are configurable per route; the defaults are tuned for typical shops with one or two attached buyer agents.

For shops that don't want managed Redis, the limiter falls back to a process-local LRU cache — single-instance correctness, multi-instance approximate. The Upstash env vars being absent is fine for the limiter; it just downgrades silently. It is **not** fine for admin-managed redirects: the redirect table lives in Redis, so without `UPSTASH_REDIS_REST_URL` / `UPSTASH_REDIS_REST_TOKEN` nothing at `/admin/redirects` fires.

## i18n → i18nexus [#i18n--i18nexus]

i18nexus is the cloud strings platform for storefront copy. UI labels, error messages, and category-page templates live in i18nexus; the Cartwright app pulls them at build time and falls back to the source locale at runtime. No manual locale-JSON file management, no missing-translation crashes in production.

For dynamic content — product descriptions, page bodies, vibe-pushed HTML — the [Vibe Coding](/docs/features/vibe-coding) translation pipeline takes over: Gemini auto-translates per locale and stores the result on the entity. The two together cover both UI strings and AI-generated body content.

## AI & agents → Anthropic, Gemini, Ollama, MCP [#ai--agents--anthropic-gemini-ollama-mcp]

`lib/ai/client.ts:chatModel()` is the single accessor for every text-generating path in the app. The provider is chosen by one field in `IntegrationSettings` — `aiProvider: "anthropic"` (default), `"local"` (Ollama), or any other OpenAI-compatible endpoint. Storefront chat, admin AI features, and tool-orchestration calls all follow the same toggle.

Gemini is wired separately for image-aware tasks: palette extraction, Vibe translation, reference-image-driven composition. There's no "swap Gemini for X" knob — the image-specific paths stay on Gemini.

The MCP server at `/api/mcp` exposes a typed tool registry to external agents — discover by `/.well-known/mcp.json`, connect with any MCP-speaking client. Auth is API-key based with per-key scopes; rate limiting is already on.

## Migration & import → Firecrawl [#migration--import--firecrawl]

`FIRECRAWL_API_KEY` powers three things. `lib/scrape/` scrapes product data from a URL into a structured product (`/admin/produkter/scrape`). `lib/design-import/` pulls a colour palette from any site into a live theme (`/admin/design-import`). And **Hoptify** (`/admin/hoptify`, `--profile full` only — the module is pruned from the default profile) is the tongue-in-cheek "import from Shopify" onboarding — with a key it lifts your palette and brings products across from the product URLs you list, fail-soft to a demo otherwise. Design import and Hoptify are default-off flags (`designImport`, `hoptify`), so an upgrade adds nothing visible until you turn them on; the product scraper needs only an admin sign-in.

## Tax & VAT → Stripe Tax (or built-in) [#tax--vat--stripe-tax-or-built-in]

`stripeTax` toggles between managed multi-country VAT via Stripe Tax (EU OSS, VAT-ID validation, invoicing) and the built-in single-rate (`policies.vatRatePct`, `pricesIncludeVat`). VAT is computed correctly at checkout either way; configured in `/admin/integrations`.

## Shipping & fulfillment → built-in [#shipping--fulfillment--built-in]

`shippingZones` turns on zone/weight-based rates with delivery-time estimates and optional dropship-supplier routing (`Supplier` + `FulfillmentOrder` models, manual + email modes). Off = a single flat rate. Managed in `/admin/shipping`.

## Content → Blog + Resolvable Genome [#content--blog--resolvable-genome]

`blog` mounts `/blog` + an RSS feed + `BlogPosting` JSON-LD + sitemap entries, edited from `/admin/blog`. Separately, the **Resolvable Genome** (`genomeResolve`) makes copy fields render `override ?? resolved-cache ?? brand anchor`, harmonised against your identity anchors — render never calls an LLM; resolution is triggered in `/admin/genome`. Respawn a shop's whole voice from a sentence.

## Growth → SEO/GEO Lab (beta, Pro) [#growth--seogeo-lab-beta-pro]

`seoAutopilot` (needs `cartwrightPlus`) is the SEO/GEO Lab, currently in beta: AI-citation share-of-voice (GEO) measurement runs today at `/admin/seo-performance`. Google Search Console measurement and automated genome experiments (apply → measure → keep or revert) are scaffolded but still in development. Per-shop `seoIndexing` (public/noindex) + `aiCrawlers` (allow/block) wire into robots.txt + meta robots.

## Compliance & ops → GDPR/DSAR, backup [#compliance--ops--gdprdsar-backup]

`lib/gdpr/` ships data-subject export + soft-erasure, retention crons, and a processor register at `/admin/processors`. A DB backup cron runs on `CRON_SECRET`. The WooCommerce-parity set (`wishlist`, `abandonedCart`, admin redirects (Upstash Redis required), product CSV import/export, translation management) rounds out the migration toolkit — there is no dedicated WooCommerce importer yet; products move by CSV (simple products). A Gemini logo generator (`logoGenerator`) needs `BLOB_READ_WRITE_TOKEN`.

## How fast can you actually go live? [#how-fast-can-you-actually-go-live]

The path looks like this:

1. `npx create-cartwright my-shop` scaffolds the template.
2. `vercel link && vercel deploy` ships a build with mock keys.
3. Open `/admin/setup` on the preview URL. Step through brand → theme → API keys → first category. Keys go into the encrypted store: Anthropic (or Ollama), Stripe (test mode pre-filled), Resend, Vercel Blob (auto-issued by Vercel), Sentry optional.
4. Add a domain in the wizard. DNS records are printed; verification polls; you wait a minute.
5. First product, first category, first order possible.

That's an afternoon of work for a developer who's seen this stack once before (default profile). A team that hasn't will spend a day; a team setting up Stripe + Resend + Turso + Vercel + Sentry from scratch usually spends a sprint.

For a `site` scaffold, only step 1 and the Vercel import apply — there is no admin wizard, no keys to collect, no domain wizard and no products. Push to GitHub, import the repo in Vercel with no environment variables (Resend keys only if the contact form should deliver mail), and the build is the whole path.

Honest about what's **not** in the box: your product catalogue, your brand assets (logo, photography, copy), your team's hiring pipeline, your tax-jurisdiction-specific accounting. Cartwright ships the rails; the train is yours.

Want the integration story visually? [`/integrations`](/integrations) shows every brand with logos and live links. Premium MCP integrations (Klaviyo, HubSpot, Slack, Zapier, and six others) are planned for the Plus tier — see [`/pricing`](/pricing).

<Cards>
  <Card title="Setup wizard" href="/docs/features/setup-wizard" />

  <Card title="Deployment → Vercel" href="/docs/deployment/vercel" />

  <Card title="Configuration → env vars" href="/docs/configuration/env-vars" />

  <Card title="FAQ" href="/docs/faq" />
</Cards>
