Full-stack e-commerce built with Next.js + Strapi + Stripe + Clerk + Tailwind CSS. Browse products, manage carts, check out securely, and administer catalog/content with a Strapi-powered admin. Media is hosted on Cloudinary; design is fully responsive.
- Tech Stack
- Architecture
- Data Model
- Core Flows
- Features
- Getting Started
- Environment Variables
- Scripts
- Project Structure
- Testing
- Operational Notes
- Roadmap
- License
- Frontend: Next.js (App Router), React, TypeScript (if enabled), Tailwind CSS
- Backend: Strapi (Headless CMS), REST/GraphQL (depending on Strapi config)
- Auth: Clerk
- Payments: Stripe Checkout / Payment Intents
- Media: Cloudinary
- Infra: Vercel (frontend), Strapi host (Render/Railway/DigitalOcean—configure as applicable)
- State/Data: React Query / SWR (adjust if different), local storage for carts (guest), server cart for authed users
flowchart LR
subgraph Client["Next.js (Vercel)"]
UI[UI / Pages]
Cart[Cart State]
Fetch[Data Fetching]
end
subgraph Strapi["Strapi CMS/API"]
AuthZ[Role & Permissions]
Webhooks[Webhooks]
end
subgraph Integrations
Stripe[(Stripe)]
Clerk[(Clerk)]
Cloudinary[(Cloudinary)]
end
UI --> Fetch
Fetch --> Strapi
UI --> Clerk
Cart --> UI
Strapi --> Cloudinary
UI --> Stripe
Stripe --> Strapi
Strapi --> Webhooks --> UI
Align table/collection names and fields with your actual Strapi schema.
erDiagram
USERS {
uuid id PK
string email
string clerk_id
string name
string avatar_url
timestamp created_at
timestamp updated_at
}
PRODUCTS {
uuid id PK
string title
text description
uuid category_id FK
decimal price
string currency
string slug
string sku
int inventory
boolean featured
json metadata
timestamp created_at
timestamp updated_at
}
CATEGORIES {
uuid id PK
string name
string slug
uuid parent_id FK
timestamp created_at
timestamp updated_at
}
MEDIA {
uuid id PK
uuid product_id FK
string url
string alt
int position
}
CARTS {
uuid id PK
uuid user_id FK
string session_id
timestamp created_at
timestamp updated_at
}
CART_ITEMS {
uuid id PK
uuid cart_id FK
uuid product_id FK
int quantity
decimal unit_price
decimal line_total
}
ORDERS {
uuid id PK
uuid user_id FK
string status
decimal subtotal
decimal tax
decimal shipping
decimal total
string currency
string stripe_payment_intent
string stripe_checkout_id
timestamp placed_at
timestamp created_at
timestamp updated_at
}
ORDER_ITEMS {
uuid id PK
uuid order_id FK
uuid product_id FK
int quantity
decimal unit_price
decimal line_total
}
ADDRESSES {
uuid id PK
uuid user_id FK
string type
string line1
string line2
string city
string state
string postal_code
string country
boolean is_default
}
USERS ||--o{ CARTS : owns
USERS ||--o{ ORDERS : places
USERS ||--o{ ADDRESSES : has
CATEGORIES ||--o{ PRODUCTS : contains
PRODUCTS ||--o{ MEDIA : has
CARTS ||--o{ CART_ITEMS : contains
PRODUCTS ||--o{ CART_ITEMS : referenced
ORDERS ||--o{ ORDER_ITEMS : contains
PRODUCTS ||--o{ ORDER_ITEMS : referenced
sequenceDiagram
participant U as User
participant UI as Next.js
participant Clerk as Clerk
participant API as Strapi API
participant Stripe as Stripe
U->>UI: Review cart & click Checkout
UI->>Clerk: Verify session
UI->>API: Create/Sync cart & request payment intent
API->>Stripe: Create Payment Intent / Checkout Session
Stripe-->>API: PI/Session ID
API-->>UI: Return client secret / redirect URL
UI->>Stripe: Confirm/Redirect
Stripe-->>API: Webhook (payment_succeeded)
API-->>UI: Order confirmation payload
UI-->>U: Show order success
- Upload via Strapi → stored on Cloudinary.
- URLs served directly (opt: image optimization via Next.js
<Image>).
- Manage products, categories, media, and feature flags.
- Role-based permissions for publishing.
- Product listing, detail, search, and category browsing
- Cart (guest + authenticated), quantity updates, persistence
- Secure checkout with Stripe
- Order history and detail pages
- Clerk authentication (email/password, SSO, social where enabled)
- Responsive UI with Tailwind
- Cloudinary-backed media with alt text
- Admin: products/categories/media management (via Strapi)
- SEO-friendly metadata (slugged products/categories)
- Node.js ≥ 18
- Yarn or npm or pnpm
- Stripe account + keys
- Clerk instance + keys
- Cloudinary account + keys
- Strapi instance (local or hosted)
- Clone:
git clone https://github.com/oussamatght/nextlevel.git
cd nextlevel- Install deps:
npm install
# or
yarn install
# or
pnpm install-
Configure environment (see
.env.examplebelow) and ensure Strapi is reachable. -
Run dev:
npm run dev
# or
yarn dev
# or
pnpm dev- Build & start (production):
npm run build && npm run startCreate .env.local (frontend) and .env (Strapi) as needed.
# Frontend (Next.js)
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:1337
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_***
CLERK_SECRET_KEY=sk_test_***
STRIPE_SECRET_KEY=sk_test_***
STRIPE_WEBHOOK_SECRET=whsec_***
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_***
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud
NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET=unsigned_or_preset
Strapi-side env (example—align to your deployment):
APP_KEYS=...
API_TOKEN_SALT=...
ADMIN_JWT_SECRET=...
TRANSFER_TOKEN_SALT=...
STRAPI_URL=http://localhost:1337
CLOUDINARY_NAME=...
CLOUDINARY_KEY=...
CLOUDINARY_SECRET=...
STRIPE_SECRET_KEY=sk_test_***
STRIPE_WEBHOOK_SECRET=whsec_***
CLERK_SECRET_KEY=sk_test_*** # if validating Clerk server-side
dev— start Next.js dev serverbuild— build production bundlestart— start production serverlint— run lint checkstest— (add your test runner, e.g., Jest/Playwright)
nextlevel/
app/ or pages/ # Next.js routes
components/ # UI components
lib/ # API clients, helpers
hooks/ # React hooks (cart, auth, data fetching)
styles/ # Tailwind/global styles
public/ # Static assets
scripts/ # Setup/seed (optional)
tests/ # Unit/e2e tests
- Unit: Jest / Vitest
- E2E: Playwright / Cypress
- API: Supertest or direct fetch against Strapi (staging)
Add test commands once configured (e.g.,
npm run test,npm run test:e2e).
- Webhooks: Ensure Stripe webhooks are configured to notify Strapi (payment success/failure).
- Caching: If using ISR/SSG, revalidate on product/category changes (consider Strapi webhooks to trigger revalidation).
- Security: Keep secrets out of client bundle; use Next.js server routes where needed.
- Performance: Optimize images via Cloudinary transformations or Next.js
<Image>with remote loader.
- Wishlist & product reviews
- Inventory reservations during checkout
- Discount codes / promotions
- Search with filters & sorting
- Accessibility sweeps (WCAG AA)
- Observability (logging, metrics, tracing)
MIT (adjust if different).