Unclassified

Quick Start: Tenant Routing System

What's New

Your IntegrateWise app now has multi-tenant support via subdomains. Each tenant gets:

  • ✅ Branded landing page at their own subdomain
  • ✅ Customizable colors, logo, and copy
  • ✅ Industry-specific content (SaaS/Healthcare/Fintech)
  • ✅ Automatic tenant scoping for all features

Test It Locally

Start the dev server

cd apps/web
npm run dev

Visit the demo workspaces

Open these URLs in your browser (on localhost:3000):

URLWorkspaceIndustryColor
http://saas-corp.localhost:3000SaaS CorpSaaSBlue 🚀
http://healthtech.localhost:3000HealthTech IncHealthcareGreen ⚕️
http://fintech-solutions.localhost:3000Fintech SolutionsFintechPurple 💰
http://app.localhost:3000Workspace PickerHubDefault

Try it out

Each landing page has:

  1. Navigation with tenant logo and sign-in
  2. Hero section with industry-specific headline
  3. Features grid showing key capabilities
  4. Industry section with relevant stats
  5. Call-to-action buttons
  6. Footer with links

Test flows

Not signed in:

  • Click "Get Started" or "Sign In" → redirects to /auth/sign-in

Signed in, not onboarded:

  • Click any CTA → redirects to /onboarding

Signed in, onboarded:

  • Click any CTA → redirects to /work

Try tenant picker:

How It Works

Subdomain Resolution

Request: saas-corp.localhost:3000
    ↓
Middleware reads Host header
    ↓
Extracts "saas-corp" subdomain
    ↓
Looks up tenant in DataProvider
    ↓
Injects X-Tenant-Slug & X-Tenant-Id headers
    ↓
Routes to (tenant) route group
    ↓
TenantProvider loads tenant data
    ↓
Landing page gets branding from tenant.branding
    ↓
CSS variables apply colors & logo
    ↓
Page renders with industry-specific copy

Available Hooks

// In any client component inside (tenant) route group:

  const tenant = useTenant();

  return (
    <div>
      <h1>{tenant?.name}</h1>
      <p>{tenant?.branding?.tagline}</p>
      <button style={{ background: tenant?.branding?.primaryColor }}>
        Click me
      </button>
    </div>
  );
}

File Structure

apps/web/
├── middleware.ts                          # Subdomain routing
├── lib/
│  ├── context/
│  │  └── tenant-context.tsx              # React context for tenant
│  ├── data/
│  │  ├── types.ts                        # Extended Tenant type
│  │  └── in-memory-provider.ts           # Seed data + methods
│  └── tenant-lookup.ts                   # (Optional) Lookup utility
├── components/
│  └── tenant/
│     ├── landing-page.tsx                # Per-tenant landing page
│     └── tenant-picker.tsx               # Workspace picker
└── app/
   ├── (tenant)/
   │  ├── layout.tsx                      # Tenant context wrapper
   │  ├── page.tsx                        # Landing route
   │  └── onboarding/                     # Tenant-scoped
   │  └── work/                           # Tenant-scoped
   └── app/
      └── page.tsx                        # Workspace picker

Customizing Tenants

Add a new tenant

Edit lib/data/in-memory-provider.ts:

const SEED_TENANTS: Record<string, Omit<Tenant, "id">> = {
  "my-company": {
    name: "My Company",
    slug: "my-company",
    industry: "saas",
    environment: "customer-zero",
    status: "active",
    branding: {
      logoUrl: "🎉",
      primaryColor: "#EC4899",
      backgroundColor: "#FCE7F3",
      tagline: "Custom tagline here",
    },
    landing: {
      headline: "Custom headline",
      subhead: "Custom subheading",
      featuredPluginIds: [],
      featuredAgentIds: [],
    },
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  },
  // ... other tenants
};

Then restart dev server and visit:

http://my-company.localhost:3000

Customize branding

Update the branding object:

  • logoUrl: emoji or image URL
  • primaryColor: hex color (e.g., "#3B82F6")
  • backgroundColor: hex color (e.g., "#F0F9FF")
  • tagline: short tagline

Customize landing copy

Update the landing object:

  • headline: main heading
  • subhead: subheading
  • featuredPluginIds: array of plugin IDs to highlight
  • featuredAgentIds: array of agent IDs to highlight

Slug Requirements

Slugs must be:

  • ✅ Lowercase alphanumeric + hyphens: my-company, saas-corp
  • ✅ 2-63 characters long
  • ✅ No leading/trailing hyphens
  • ❌ Not reserved: www, app, api, admin, docs, localhost, staging, dev
  • ❌ Not already taken

Use the validation method:

const provider = getDataProvider();
const isValid = await provider.tenants.validateSlug("my-company");
// Returns true if valid and available

Production Readiness

What's ready for production:

  • ✅ Subdomain routing
  • ✅ Tenant context propagation
  • ✅ Branding system
  • ✅ Landing page components
  • ✅ Error handling & fallbacks

What needs work for production:

  • ⚠️ Move to persistent database (Neon PostgreSQL)
  • ⚠️ Add admin UI for tenant provisioning
  • ⚠️ Implement custom domain support (CNAME)
  • ⚠️ Add caching layer (Redis) for slug lookups
  • ⚠️ Set up RLS policies on database for tenant isolation
  • ⚠️ Add audit logging for tenant operations

See TENANT_ROUTING_IMPLEMENTATION.md for full details.

Troubleshooting

Subdomain not resolving

  1. Check /etc/hosts on Mac/Linux or C:\Windows\System32\drivers\etc\hosts on Windows
  2. Add: 127.0.0.1 saas-corp.localhost
  3. Restart browser

Or use the browser's developer tools to test:

// In console:
console.log(window.location.hostname); // should show subdomain

Branding not applying

  1. Check browser DevTools → Elements tab
  2. Look for --primary-color CSS variable on root element
  3. Verify tenant data loaded: check useTenant() return value
  4. Check network tab: confirm X-Tenant-Slug header sent

Tenant not found

  1. Check DataProvider has tenant slug: npm run dev and check console
  2. Verify slug matches exactly (case-sensitive)
  3. Check reserved list in middleware.ts
  4. Try accessing tenant picker first: http://app.localhost:3000

Next Features to Build

Suggested Enhancements

  1. Admin Dashboard

    • Create/edit/delete tenants
    • Manage branding
    • View usage stats
    • Team member management
  2. Custom Domains

    • Support CNAME mappings (acme.com → acme.integratewise.com)
    • DNS validation
    • SSL certificate provisioning
  3. Database Integration

    • Migrate from in-memory to Neon
    • Add Redis caching
    • Implement RLS policies
  4. Advanced Branding

    • Upload custom fonts
    • Design theme builder
    • Custom CSS injection
  5. Analytics

    • Workspace creation tracking
    • Usage metrics per tenant
    • Admin reporting dashboard

Documentation

  • Full Details: See TENANT_ROUTING_IMPLEMENTATION.md
  • Architecture: See TENANT_ARCHITECTURE.md
  • Delivery: See DELIVERY_SUMMARY.md

Support

For questions or issues:

  1. Check the architecture diagrams in TENANT_ARCHITECTURE.md
  2. Review the data flow section in DELIVERY_SUMMARY.md
  3. Check component source code (well-commented)
  4. Test with the seed data tenants first

Happy multi-tenant building! 🚀