Skip to main content

Overview

Each seller gets their own branded subdomain on the platform:
This is handled via Next.js middleware that detects the subdomain and routes to the appropriate store data.

How It Works

1. Middleware Detection

The middleware runs on every request and extracts the subdomain:
middleware.ts

2. Database Lookup

Supabase query to find store by subdomain:

3. Store Context

The store data is passed to pages via URL params or React Context:
app/layout.tsx

Local Development

Hosts File Setup

To test subdomains locally, add entries to /etc/hosts:
Add these lines:

Access Stores

Then visit:
  • http://teststore.localhost:3000 → Test Store
  • http://myshop.localhost:3000 → My Shop
  • http://demo.localhost:3000 → Demo Store
Note: Use .localhost (not just localhost) for subdomain routing to work locally.

Production Setup

DNS Configuration

Wildcard DNS Record:
Or with Cloudflare:

Cloudflare Pages

Cloudflare automatically supports wildcard subdomains with Pages:
  1. Deploy to Cloudflare Pages
  2. Add custom domain: mypopup.shop
  3. Wildcard *.mypopup.shop works automatically ✅
Some hosting providers don’t support wildcard subdomains on free tiers. Cloudflare Pages does!

Subdomain Validation

Rules

Subdomains must:
  • Be 3-30 characters long
  • Contain only lowercase letters, numbers, and hyphens
  • Start with a letter or number
  • Not start or end with a hyphen
  • Be unique across all stores

Reserved Subdomains

These are not available for stores:
  • www, api, admin, app
  • blog, docs, help, support
  • mail, email, smtp, ftp
  • cdn, static, assets
  • test, staging, dev

Multi-Tenant Data Isolation

Database Queries

All queries must filter by store_id:

Row-Level Security (RLS)

Supabase RLS policies enforce data isolation:

Performance Optimization

Caching Strategy

Edge Middleware

Middleware runs on the edge (Cloudflare/Vercel), making subdomain detection blazing fast:

Troubleshooting

Make sure:
  1. You added the subdomain to /etc/hosts
  2. You’re using .localhost (e.g., test.localhost:3000)
  3. Middleware is enabled in middleware.ts
  4. Clear browser cache
Check:
  1. Wildcard DNS record is set (*.mypopup.shop)
  2. Store exists in database with that subdomain
  3. Store status is active
  4. Cloudflare proxy is enabled (orange cloud)
This is a critical bug - ensure:
  1. All database queries filter by store_id
  2. RLS policies are enabled
  3. Store context is passed correctly
  4. No caching issues (clear Redis/cache)

Example Flow


Next Steps

Learn how payments are processed per store