SwiftChat Documentation

Version 1.4.2 — Complete Setup, Features & Reference Guide

SwiftChat is a full-featured, self-hostable SaaS messaging and collaboration platform built with React, TypeScript, and Supabase. It combines real-time chat, WebRTC voice/video calls, scheduled meetings, AI-powered features (via Gemini AI), CRM tools, and a powerful admin panel into a single deployable application.

💬

Real-time Messaging

1:1 and group chats with typing indicators, read receipts, reactions, file sharing, voice messages, polls, and more.

📹

Video & Voice Calls

WebRTC-powered calls with screen sharing, virtual backgrounds (MediaPipe/TensorFlow), call recording, and AI call summaries.

🤖

AI-Powered (Gemini)

Gemini AI integration for smart replies, chat summaries, message translation, audio transcription, and an AI assistant chatbot.

📊

CRM & Business

Lead management with scoring and templates, order tracking, 6+ payment gateways, promotions with A/B testing and coupon codes.

🛡️

Admin Panel

Comprehensive dashboard with user management, moderation, media library, app settings, analytics, and system health monitoring.

🌐

Multi-language

13 languages supported with i18next (English, Spanish, French, German, Portuguese, Chinese, Japanese, Korean, Arabic RTL, Hindi, Bengali, Italian, Russian).

Tech Stack

LayerTechnologyPurpose
Frontend FrameworkReact 19 + TypeScriptUI components and type safety
Build ToolViteFast development server and production builds
StylingTailwind CSS 4 + shadcn/uiUtility-first CSS with pre-built accessible components
State ManagementZustand + TanStack React QueryClient state stores and server-state caching
RoutingReact Router v7Client-side SPA routing
BackendSupabase (PostgreSQL + Edge Functions)Database, auth, storage, serverless functions
Real-timeSupabase Realtime (WebSocket)Live message updates, presence, typing indicators
CallsWebRTC + STUN/TURNPeer-to-peer voice and video
AI EngineGemini AISmart replies, summaries, translations, transcription
AnimationsFramer MotionPage transitions and micro-interactions
FormsReact Hook Form + ZodForm handling with schema validation
ChartsRechartsAdmin analytics visualizations
i18ni18next + react-i18nextMulti-language support (13 languages)
PWAvite-plugin-pwaOffline support, install prompt, push notifications
MapsMapbox GLLocation sharing in chats
Bot ProtectionhCaptchaRegistration spam prevention
Drag & Drop@dnd-kitSortable lists and kanban boards

System Requirements

ComponentMinimumRecommended
Node.js18.x20.x LTS
npm9.xLatest
Supabase ProjectFree tier or above at supabase.com
Server (for hosting)512 MB RAM, 500 MB disk1 GB+ RAM, 1 GB+ disk
SSL CertificateRequired for PWA, push notifications, and WebRTC calls
BrowserChrome, Firefox, Safari, Edge (latest versions)
Package Managers: You can also use bun or yarn instead of npm.

📁 Project Structure

swiftchat/
├── docs/                       # Documentation (this file)
├── public/                     # Static assets
│   ├── favicon.png             # App favicon
│   ├── pwa-192x192.png         # PWA icon (192px)
│   ├── pwa-512x512.png         # PWA icon (512px)
│   ├── robots.txt              # Search engine directives
│   └── sw-push.js              # Service worker for push notifications
├── src/
│   ├── assets/                 # Images and media files
│   ├── components/             # React components
│   │   ├── admin/              # Admin panel (40+ components)
│   │   │   └── settings/       # Admin settings sub-components
│   │   ├── auth/               # Authentication (login, signup, reset)
│   │   ├── call/               # Voice & video call UI
│   │   ├── channels/           # Broadcast channels
│   │   ├── chat/               # Messaging components
│   │   ├── communities/        # Community system
│   │   ├── contacts/           # Contact management
│   │   ├── inbox/              # Internal inbox
│   │   ├── landing/            # Landing page sections
│   │   ├── leads/              # CRM lead management
│   │   ├── media/              # Media viewers & uploaders
│   │   ├── meetings/           # Meeting scheduler & room
│   │   ├── notifications/      # Notification system
│   │   ├── onboarding/         # User onboarding flow
│   │   ├── orders/             # Order management
│   │   ├── profile/            # User profile views
│   │   ├── promotions/         # Promotion campaigns
│   │   ├── pwa/                # PWA install prompts
│   │   ├── settings/           # User settings panels
│   │   ├── sidebar/            # Navigation sidebar
│   │   ├── ui/                 # Shared UI components (shadcn)
│   │   └── workflows/          # Workflow automation
│   ├── contexts/               # React context providers
│   ├── hooks/                  # 95+ custom React hooks
│   ├── i18n/
│   │   └── locales/            # 13 language files (en, es, fr, de, pt, zh, ja, ko, ar, hi, bn, it, ru)
│   ├── integrations/
│   │   └── supabase/           # Supabase client & auto-generated types
│   ├── lib/                    # Utility libraries
│   ├── pages/                  # Page-level components
│   │   ├── AdminPage.tsx       # Admin dashboard page
│   │   ├── AuthPage.tsx        # Login/signup page
│   │   ├── ChatPage.tsx        # Main chat interface
│   │   ├── Index.tsx           # Route handler
│   │   ├── InstallPage.tsx     # PWA install page
│   │   ├── LandingPage.tsx     # Public landing page
│   │   ├── MeetingJoinPage.tsx # Meeting join flow
│   │   ├── MeetingRoomPage.tsx # Active meeting room
│   │   ├── NotFound.tsx        # 404 page
│   │   └── SetupPage.tsx       # Installation wizard
│   ├── stores/                 # Zustand state stores
│   ├── types/                  # TypeScript type definitions
│   ├── App.tsx                 # Main app component with routing
│   ├── index.css               # Global styles & design tokens
│   └── main.tsx                # Application entry point
├── supabase/
│   ├── config.toml             # Supabase project configuration
│   ├── functions/              # 18 Deno edge functions
│   │   ├── admin-create-user/
│   │   ├── admin-delete-user/
│   │   ├── admin-update-app-settings/
│   │   ├── admin-update-user/
│   │   ├── ai-call-summary/
│   │   ├── ai-chat/
│   │   ├── check-lead-follow-ups/
│   │   ├── cleanup-stale-calls/
│   │   ├── complete-installation/
│   │   ├── on-new-channel-message/
│   │   ├── on-new-message/
│   │   ├── process-scheduled-messages/
│   │   ├── seed-demo-users/
│   │   ├── send-push-notification/
│   │   ├── smart-replies/
│   │   ├── summarize-chat/
│   │   ├── transcribe-audio/
│   │   └── translate-message/
│   ├── migrations/             # SQL migration files
│   └── storage/
│       └── buckets.json        # Storage bucket definitions
├── .env                        # Environment variables
├── CHANGELOG.md                # Version history
├── LICENSE                     # MIT License
├── SECURITY.md                 # Security policy
├── package.json                # Dependencies & scripts
├── tailwind.config.ts          # Tailwind CSS configuration
├── tsconfig.json               # TypeScript configuration
└── vite.config.ts              # Vite + PWA configuration

📋 Complete Setup Guide — Start to Finish

Follow these 10 steps in order to go from a fresh download to a fully working SwiftChat deployment. Each step builds on the previous one.

Time Estimate: ~30 minutes for the complete setup.
#StepWhat You'll DoTime
1Create Supabase ProjectCreate account, get API keys5 min
2Configure .envSet environment variables2 min
3Install Dependenciesnpm install + Supabase CLI3 min
4Deploy DatabaseRun migrations, create tables & storage3 min
5Deploy Edge FunctionsDeploy all 18 backend functions3 min
6Configure AuthDisable email verification, set URLs3 min
7Set SecretsConfigure VAPID key and Gemini AI key3 min
8Build for ProductionCompile to dist/ folder2 min
9Upload to ServerCopy dist/ to nginx/Apache/Docker5 min
10Run Setup WizardCreate Super Admin, configure branding2 min

Step 1 — Create a Supabase Project

1a. Create an Account

Go to supabase.com and sign up (free tier is sufficient).

1b. Create a New Project

  • Click "New Project"
  • Name: SwiftChat (or your preferred name)
  • Database Password: Generate a strong password — save it! You'll need it in Step 4.
  • Region: Choose the closest to your users

Wait 2–3 minutes for provisioning to complete.

1c. Record Your Credentials

Go to Project Settings → API and copy these 3 values:

CredentialWhere to FindExample
Project URLSettings → API → Project URLhttps://abcdefgh.supabase.co
Anon / Public KeySettings → API → anon keyeyJhbGciOi...
Project Reference IDSettings → Generalabcdefgh
Also save: Your Service Role Key (Settings → API → service_role key). This is needed for admin operations. Never expose it in client-side code.

Step 2 — Configure the .env File

In the project root, create (or edit) a .env file with your Supabase credentials:

.env
# ======================================== # SwiftChat Environment Configuration # ======================================== # ----- REQUIRED: Supabase Connection ----- VITE_SUPABASE_URL=https://YOUR_PROJECT_REF.supabase.co VITE_SUPABASE_PUBLISHABLE_KEY=your-anon-key-here VITE_SUPABASE_PROJECT_ID=YOUR_PROJECT_REF # ----- App Mode ----- VITE_DEMO_MODE=false # ----- OPTIONAL ----- # VITE_HCAPTCHA_SITE_KEY=your-hcaptcha-site-key # VITE_MAPBOX_TOKEN=pk.your-mapbox-public-token
Replace YOUR_PROJECT_REF and your-anon-key-here with the values from Step 1c.

Step 3 — Install Dependencies

Terminal
# Install frontend dependencies npm install # Install Supabase CLI (needed for Steps 4 & 5) npm install supabase

Verify Supabase CLI: npx supabase --version

Alternative: Use bun install or yarn install for faster dependency resolution.

Step 4 — Deploy Database & Storage

This imports all tables, RLS policies, functions, triggers, and storage buckets into your Supabase project.

Terminal
# Login to Supabase npx supabase login # Link to your project (use your Project Reference ID) npx supabase link --project-ref YOUR_PROJECT_REF # Deploy all database migrations (creates 70+ tables, storage buckets, RLS policies) npx supabase db push
When prompted for the database password, enter the one you saved in Step 1b.

What This Creates

Step 5 — Deploy Edge Functions

Deploy all 18 serverless backend functions to your Supabase project:

Terminal
# Deploy all edge functions at once npx supabase functions deploy

All 18 Edge Functions

FunctionPurpose
complete-installationSetup wizard finalization
seed-demo-usersCreate demo accounts for testing
admin-create-userAdmin: create new user accounts
admin-update-userAdmin: update user profiles & roles
admin-delete-userAdmin: delete user accounts
admin-update-app-settingsAdmin: update application settings
ai-chatAI assistant chatbot (Gemini)
smart-repliesAI-generated reply suggestions
summarize-chatAI chat summarization
translate-messageAI message translation
transcribe-audioAI audio-to-text transcription
ai-call-summaryAI call transcript & summary
send-push-notificationBrowser push notification delivery
on-new-messageWebhook: trigger on new chat message
on-new-channel-messageWebhook: trigger on new channel post
process-scheduled-messagesCron: send scheduled messages
check-lead-follow-upsCron: lead inactivity reminders
cleanup-stale-callsCron: clean abandoned call records
Verify: Go to your Supabase Dashboard → Edge Functions. You should see all 18 functions listed and active.

Step 6 — Configure Authentication Settings

In the Supabase Dashboard:

6a. Disable Email Confirmation

Go to Authentication → Providers → Email:

  • Enable Email Signup: ON
  • Confirm Email: OFF (so new users can sign in immediately)
  • Secure Email Change: ON

6b. Set URL Configuration

Go to Authentication → URL Configuration:

SettingValue
Site URLhttps://yourdomain.com
Redirect URLshttps://yourdomain.com/*
http://localhost:8080/* (for dev)
http://localhost:5173/* (for dev)

6c. Optional: Phone Auth

To enable phone OTP login, go to Authentication → Providers → Phone and enable it with a supported SMS provider (Twilio, Vonage, etc.).

Step 7 — Configure Edge Function Secrets

Go to Supabase Dashboard → Project Settings → Edge Functions → Secrets and add:

Secret NameHow to Get ItRequired For
VAPID_PRIVATE_KEY Generate with: npx web-push generate-vapid-keys
Use the Private Key output
Push notifications
GEMINI_API_KEY Get from Google AI Studio AI chat, smart replies, summaries, translations, transcription
Note: SUPABASE_URL, SUPABASE_ANON_KEY, and SUPABASE_SERVICE_ROLE_KEY are automatically available to all edge functions — you do not need to add them manually.

Generate VAPID Keys

Terminal
npx web-push generate-vapid-keys # Output: # Public Key: BEl62iUYgUivxIk... ← (already configured in the app) # Private Key: DH7FsOnD6WmP... ← Add this as VAPID_PRIVATE_KEY secret

Step 8 — Build for Production

Terminal
# Build the production bundle npm run build # Verify output ls dist/ # Should contain: index.html, assets/, sw.js, manifest.webmanifest, etc.

The dist/ folder contains everything needed for deployment — it's a static SPA (Single Page Application).

Build size: Typical production build is ~3–5 MB gzipped. Vite performs code splitting and tree shaking automatically.

Step 9 — Upload to Your Server

Copy the entire contents of the dist/ folder to your web server's document root. Choose your deployment method below:

MethodUpload Command / Process
SCP (VPS)scp -r dist/* user@server:/var/www/swiftchat/
rsync (VPS)rsync -avz dist/ user@server:/var/www/swiftchat/
cPanelFile Manager → public_html → Upload all files from dist/
Dockerdocker build -t swiftchat . && docker run -p 80:80 swiftchat
Vercelnpx vercel --prod
Netlifynpx netlify deploy --prod
Critical: Your server must be configured to serve index.html for all routes (SPA routing). See Deployment Options below for server configurations.

Step 10 — Run the Setup Wizard

Open your domain in a browser (e.g., https://yourdomain.com). SwiftChat will automatically redirect to the Setup Wizard.

Wizard Step 1 — Database Configuration

Enter your Supabase URL, Anon Key, and Project ID. The wizard verifies the connection, tables, storage buckets, and edge functions.

Wizard Step 2 — Site Branding

Set your site name, description, logo URL, and favicon URL. These are stored in app_settings and used across the entire application.

Wizard Step 3 — Create Super Admin

Enter a name, email, password, and optional avatar for the Super Admin account. This account has full access to everything.

Wizard Step 4 — Review & Install

Confirm everything and click Complete Installation. The wizard calls the complete-installation edge function which creates the admin account and marks the installation as complete.

After installation, you'll be redirected to the login page. Sign in with your Super Admin credentials. The setup wizard will not appear again.

✅ Post-Setup Verification Checklist

CheckHow to VerifyRequires
☐ Super Admin loginSign in with credentials from Step 10
☐ Admin panel accessNavigate to /adminAdmin role
☐ Create new userAdmin → Users → Add UserAdmin panel
☐ Send a messageOpen a chat, send a text messageTwo user accounts
☐ File uploadsSend an image or document in chatStorage buckets
☐ Real-time updatesOpen two browser tabs, send messagesSupabase Realtime
☐ Voice/video callsStart a call between two usersHTTPS
☐ Push notificationsSend message, check for browser notificationHTTPS + VAPID keys
☐ AI featuresUse smart replies or AI chatGEMINI_API_KEY secret
☐ PWA installCheck browser install promptHTTPS
☐ Language switchingSettings → Language → select non-English

🚀 Deployment Options

SwiftChat is a static SPA — it can be hosted anywhere that serves HTML files. Choose the method that fits your infrastructure:

Nginx (VPS / Cloud Server)

Create /etc/nginx/sites-available/swiftchat:

nginx.conf
server { listen 80; listen [::]:80; server_name yourdomain.com www.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name yourdomain.com www.yourdomain.com; # SSL (Let's Encrypt) ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; root /var/www/swiftchat; index index.html; # Security Headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Gzip Compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml; # Cache static assets (1 year — Vite hashes filenames) location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # No caching for service worker location = /sw.js { add_header Cache-Control "no-cache, no-store, must-revalidate"; } # SPA routing — serve index.html for all routes location / { try_files $uri $uri/ /index.html; } }
Enable & restart
sudo ln -s /etc/nginx/sites-available/swiftchat /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx

Apache / cPanel / Plesk

Create a .htaccess file in your document root (e.g., public_html/):

.htaccess
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </IfModule> <IfModule mod_headers.c> Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" </IfModule> <IfModule mod_expires.c> ExpiresActive On ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType font/woff2 "access plus 1 year" </IfModule> <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml </IfModule>

cPanel steps: Build locally → File Manager → Upload all files from dist/ to public_html → Create .htaccess above → Enable SSL via cPanel SSL/TLS.

Required Apache modules: sudo a2enmod rewrite headers expires deflate ssl

Docker

Dockerfile
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html # SPA routing config RUN echo 'server { \ listen 80; \ root /usr/share/nginx/html; \ index index.html; \ location / { try_files $uri $uri/ /index.html; } \ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } \ }' > /etc/nginx/conf.d/default.conf EXPOSE 80
docker-compose.yml
version: '3.8' services: swiftchat: build: . ports: - "80:80" restart: unless-stopped
Terminal
# Build and run docker build -t swiftchat . docker run -d -p 80:80 --name swiftchat swiftchat # Or with Docker Compose docker-compose up -d

Vercel / Netlify

Vercel
npm i -g vercel vercel --prod
Netlify
npm i -g netlify-cli netlify deploy --prod

Both platforms handle SPA routing automatically. Set environment variables in the platform's dashboard.

SSL & Custom Domain

HTTPS is required for PWA installation, push notifications, and WebRTC calls.

Let's Encrypt (free SSL)
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # Auto-renewal is configured automatically

DNS Configuration

TypeNameValue
A@Your server IP
AwwwYour server IP
CNAMEwwwyourdomain.com (alternative to A record)

Core Features

SwiftChat includes a comprehensive set of features for messaging, collaboration, and business operations.

💬 Real-time Messaging

Built on Supabase Realtime with PostgreSQL change notifications for instant message delivery.

📹 Voice & Video Calls

WebRTC peer-to-peer communication with STUN server support and DTLS-SRTP encryption.

📅 Scheduled Meetings

Full meeting scheduler with WebRTC-powered meeting rooms.

📢 Channels

Broadcast-style channels for announcements, news, and content distribution.

👥 Communities

Group spaces with comprehensive moderation, roles, and sub-groups.

📇 Contacts

📸 Status Updates

🤖 AI Integration (Gemini AI)

SwiftChat uses Gemini AI to power intelligent features across the platform. All AI features run through secure edge functions on your Supabase backend.

Requirement: Set the GEMINI_API_KEY secret in your Supabase Edge Function Secrets (Step 7). Get your key from Google AI Studio.

Smart Replies

AI-generated contextual reply suggestions displayed as quick-reply chips below the message input. Analyzes recent conversation context to suggest relevant responses.

Edge Function: smart-replies | Hook: useSmartReplies

AI Chat Assistant

Built-in conversational AI chatbot accessible from the sidebar. Supports streaming responses, markdown formatting, and maintains conversation context. Useful for Q&A, writing assistance, code generation, and general knowledge.

Edge Function: ai-chat | Hook: useAIChat

Chat & Call Summaries

Chat Summaries: Condense long conversations into key points and action items. Triggered on-demand per conversation.

Call Summaries: Automatically transcribe and summarize completed calls with key topics, decisions, and follow-ups.

Edge Functions: summarize-chat, ai-call-summary | Hooks: useChatSummary, useAICallSummary

Message Translation

Translate any message to any of the 13 supported languages with one click. Preserves formatting and context.

Edge Function: translate-message

Audio Transcription

Convert voice messages and audio recordings to text. Supports multiple languages and accents.

Edge Function: transcribe-audio

⚡ Workflow Automation

Create automated workflows triggered by events across the platform.

Hook: useWorkflows

📊 CRM & Lead Management

Full-featured CRM integrated directly into the messaging platform.

Lead Scoring

Automatic lead scoring based on activity, engagement, and profile completeness. Higher scores indicate more qualified leads.

Hook: useLeadScoring

Lead Templates

Save and reuse lead configurations with default values for stage, status, source, tags, and notes. Speeds up repetitive lead creation.

Hook: useLeadTemplates

Custom Fields

Define custom field types (text, number, date, dropdown) for leads. Fields can be marked as required and support custom sort order.

🛒 Orders & Products

Create and manage orders with full line item support.

Hook: useOrders

📣 Promotions & Coupons

Hooks: usePromotions, usePromotionABTesting, usePromotionCoupons, usePromotionAnalytics

📥 Inbox

Internal notification and messaging inbox separate from chat.

Hook: useInboxMessages

💳 Payment Gateways

Configurable payment gateway integrations managed via the admin panel.

GatewayTypeRegionsFeatures
StripeCards, SubscriptionsGlobalRecurring billing, refunds
PayPalPayPal, CardsGlobalBuyer protection, express checkout
RazorpayUPI, Cards, WalletsIndiaUPI payments, EMI
PaystackCards, Bank, Mobile MoneyAfricaMobile money, bank transfers
FlutterwaveCards, Mobile MoneyAfricaMulti-currency, mobile money
Crypto (BTC/ETH/USDT)CryptocurrencyGlobalDecentralized payments

Hook: usePaymentGateways | Admin Component: AdminPaymentGateways

Payment gateways are configured per-gateway in the admin panel. Each gateway can be independently enabled/disabled and set to test or live mode.

🛡️ Admin Dashboard

Comprehensive admin panel accessible at /admin. Only users with admin or moderator roles can access this area.

Admin Sections

SectionComponentDescription
DashboardAdminDashboardOverview with real-time stats, recent activity, quick actions
UsersAdminUsersUser management with CRUD, filters, bulk actions
ConversationsAdminConversationsView and manage all conversations
MessagesAdminMessagesSearch and review messages across the platform
CallsAdminCallsCall history and recordings management
MeetingsAdminMeetingsMeeting oversight and analytics
ChannelsAdminChannelsChannel management and moderation
CommunitiesAdminCommunitiesCommunity oversight and reports
ContactsAdminContactsPlatform-wide contact directory
LeadsAdminLeadsCRM lead management
PromotionsAdminPromotionsPromotion campaign management
InboxAdminInboxSystem notifications management
StatusesAdminStatusesStatus update moderation
ModerationAdminModerationFlagged messages & reports review
RolesAdminRolesRole assignment and management
SettingsAdminSettingsApp-wide configuration
MediaAdminMediaLibraryUpload and manage media assets
AnalyticsAdminAnalyticsUsage statistics and charts
System HealthAdminSystemHealthBackend status monitoring
Activity LogsAdminActivityLogsAdmin action audit trail
Payment GatewaysAdminPaymentGatewaysPayment provider configuration
Data & StorageAdminDataStorageDatabase and storage overview
NotificationsAdminNotificationsSystem notification management
HelpAdminHelpPanelAdmin help and documentation

User Management

Roles & Permissions

RoleAccess LevelKey Permissions
adminFull accessEverything: users, settings, moderation, analytics, data management
admin_viewerRead-only adminView admin dashboard and data, no write operations
moderatorModeration toolsReview flagged content, manage community reports, suspend users
userStandardChat, calls, meetings, channels, communities, contacts
Security: Roles are stored in a separate user_roles table with its own RLS. Role checks use a SECURITY DEFINER function has_role() to prevent RLS recursion. Demo users have an additional is_demo flag that restricts destructive actions.

App Settings

All settings are stored in the app_settings table and managed via the admin-update-app-settings edge function.

Hook: useAppSettings (reads settings), useDynamicSettings (applies settings dynamically)

Moderation

Hooks: useMessageFlags, useAdminActivityLogs

Analytics & System Health

Hooks: useAdminStats, useAdminRealtimeStats, useAdminAnalytics

Media Library

Central media management for admin-uploaded assets (logos, banners, branding materials).

Hook: useAdminMedia

📖 Reference

Environment Variables (.env)

Required

VariableDescriptionExample
VITE_SUPABASE_URLSupabase project URLhttps://abcdefgh.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEYSupabase anon/public keyeyJhbGciOi...
VITE_SUPABASE_PROJECT_IDProject reference IDabcdefgh

Optional

VariableDescriptionDefault
VITE_DEMO_MODEEnable demo mode with quick-access test accountsfalse
VITE_FORCE_SETUPForce show setup wizard even if already installedfalse
VITE_MAPBOX_TOKENMapbox public token for location sharing
VITE_HCAPTCHA_SITE_KEYhCaptcha site key for bot protection on registration

Edge Function Secrets

Configured in Supabase Dashboard → Project Settings → Edge Functions → Secrets:

SecretRequired ForAuto-Configured?How to Get
SUPABASE_URLAll edge functions✅ YesAutomatic
SUPABASE_ANON_KEYAll edge functions✅ YesAutomatic
SUPABASE_SERVICE_ROLE_KEYAdmin operations✅ YesAutomatic
GEMINI_API_KEYAI chat, smart replies, summaries, translations, transcription❌ ManualGoogle AI Studio
VAPID_PRIVATE_KEYPush notifications❌ Manualnpx web-push generate-vapid-keys

Database Schema

70+ tables with Row Level Security (RLS) on every table. All tables use UUID primary keys and include created_at timestamps.

Table GroupTablesPurpose
Coreprofiles, user_roles, app_settingsUser profiles, roles, and app configuration
Messagingconversations, conversation_participants, messages, message_reactions, message_readsChat system with read receipts and reactions
Callscalls, call_recordings, group_call_participantsVoice/video calls with recording support
Meetingsmeetings, meeting_participants, meeting_chat_messages, meeting_notes, meeting_recordings, meeting_reminders, meeting_templates, meeting_analyticsFull meeting system
Channelschannels, channel_subscribers, channel_messages, channel_scheduled_posts, channel_analytics, channel_bansBroadcast channels
Communitiescommunities, community_members, community_groups, community_announcements, community_invites, community_join_requests, community_bans, community_muted_members, community_reports, community_analytics, community_notification_settingsCommunity platform
CRMleads, lead_activities, lead_custom_field_definitions, lead_custom_field_values, lead_follow_up_reminders, lead_reminder_settings, lead_templatesLead management
Commerceorders, order_items, products, payment_gatewaysOrder & payment system
Contentflagged_messages, event_rsvps, inbox_messagesModeration, events, notifications
AI & Loggingai_call_logs, admin_activity_logs, admin_mediaAI usage tracking, admin audit trail

Storage Buckets

All buckets have RLS policies for secure access control.

BucketPurposePublicMax SizeAllowed Types
avatarsUser profile picturesYes5 MBPNG, JPEG, GIF, WebP
chat-attachmentsMessage file attachmentsYes50 MBImages, Video, PDF, Word
voice-messagesAudio messagesYes50 MBWebM, MP4, MPEG, OGG, WAV
call-recordingsCall recordingsNo500 MBWebM, MP4 (audio & video)
channel-mediaChannel media postsYes50 MBImages, Video, PDF
community-avatarsCommunity profile imagesYes5 MBPNG, JPEG, GIF, WebP
promotion-imagesPromotion bannersYes10 MBPNG, JPEG, GIF, WebP
status-mediaStatus update mediaYes50 MBImages, Video
admin-mediaAdmin uploaded assetsYes50 MBImages, SVG, Video
RLS Policies: Each bucket has granular policies. Users can only manage files in their own folder (e.g., user-id/filename). Admin-only buckets (admin-media, promotion-images) restrict uploads to admin roles. call-recordings is the only private bucket.

Create Storage Buckets (SQL)

If buckets are not auto-created by migrations, run this SQL in the Supabase SQL Editor:

SQL — Create Storage Buckets
-- Create all 9 storage buckets INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) VALUES ('avatars', 'avatars', true, 5242880, ARRAY['image/png','image/jpeg','image/gif','image/webp']), ('voice-messages', 'voice-messages', true, 52428800, ARRAY['audio/webm','audio/mp4','audio/mpeg','audio/ogg','audio/wav']), ('call-recordings', 'call-recordings', false, 524288000, ARRAY['audio/webm','audio/mp4','video/webm','video/mp4']), ('status-media', 'status-media', true, 52428800, ARRAY['image/png','image/jpeg','image/gif','image/webp','video/mp4','video/webm']), ('channel-media', 'channel-media', true, 52428800, ARRAY['image/png','image/jpeg','image/gif','image/webp','video/mp4','video/webm','application/pdf']), ('community-avatars', 'community-avatars', true, 5242880, ARRAY['image/png','image/jpeg','image/gif','image/webp']), ('promotion-images', 'promotion-images', true, 10485760, ARRAY['image/png','image/jpeg','image/gif','image/webp']), ('chat-attachments', 'chat-attachments', true, 52428800, ARRAY['image/png','image/jpeg','image/gif','image/webp','video/mp4','video/webm','application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document']), ('admin-media', 'admin-media', true, 52428800, ARRAY['image/png','image/jpeg','image/gif','image/webp','image/svg+xml','video/mp4','video/webm']) ON CONFLICT (id) DO NOTHING;

Storage Bucket RLS Policies (SQL)

Run these SQL statements to secure all storage buckets with Row Level Security policies:

SQL — Avatars Bucket Policies
-- AVATARS: Public read, user-scoped write CREATE POLICY "Avatar images are publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'avatars'); CREATE POLICY "Users can upload their own avatar" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can update their own avatar" ON storage.objects FOR UPDATE USING (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own avatar" ON storage.objects FOR DELETE USING (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]);
SQL — Chat Attachments Bucket Policies
-- CHAT-ATTACHMENTS: Public read, user-scoped write CREATE POLICY "Chat attachments are publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'chat-attachments'); CREATE POLICY "Users can upload chat attachments" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'chat-attachments' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own chat attachments" ON storage.objects FOR DELETE USING (bucket_id = 'chat-attachments' AND auth.uid()::text = (storage.foldername(name))[1]);
SQL — Voice Messages Bucket Policies
-- VOICE-MESSAGES: Public read, user-scoped write CREATE POLICY "Voice messages are publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'voice-messages'); CREATE POLICY "Users can upload voice messages" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'voice-messages' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own voice messages" ON storage.objects FOR DELETE USING (bucket_id = 'voice-messages' AND auth.uid()::text = (storage.foldername(name))[1]);
SQL — Call Recordings Bucket Policies (Private)
-- CALL-RECORDINGS: Private bucket — only uploader can access CREATE POLICY "Users can view their own call recordings" ON storage.objects FOR SELECT USING (bucket_id = 'call-recordings' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can upload call recordings" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'call-recordings' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own call recordings" ON storage.objects FOR DELETE USING (bucket_id = 'call-recordings' AND auth.uid()::text = (storage.foldername(name))[1]);
SQL — Status, Channel, Community Bucket Policies
-- STATUS-MEDIA: Public read, user-scoped write CREATE POLICY "Status media is publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'status-media'); CREATE POLICY "Users can upload status media" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'status-media' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own status media" ON storage.objects FOR DELETE USING (bucket_id = 'status-media' AND auth.uid()::text = (storage.foldername(name))[1]); -- CHANNEL-MEDIA: Public read, user-scoped write CREATE POLICY "Channel media is publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'channel-media'); CREATE POLICY "Users can upload channel media" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'channel-media' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own channel media" ON storage.objects FOR DELETE USING (bucket_id = 'channel-media' AND auth.uid()::text = (storage.foldername(name))[1]); -- COMMUNITY-AVATARS: Public read, user-scoped write CREATE POLICY "Community avatars are publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'community-avatars'); CREATE POLICY "Users can upload community avatars" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'community-avatars' AND auth.uid()::text = (storage.foldername(name))[1]); CREATE POLICY "Users can delete their own community avatars" ON storage.objects FOR DELETE USING (bucket_id = 'community-avatars' AND auth.uid()::text = (storage.foldername(name))[1]);
SQL — Admin & Promotion Bucket Policies
-- PROMOTION-IMAGES: Public read, admin-only write CREATE POLICY "Promotion images are publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'promotion-images'); CREATE POLICY "Admins can upload promotion images" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'promotion-images' AND public.has_role(auth.uid(), 'admin')); CREATE POLICY "Admins can update promotion images" ON storage.objects FOR UPDATE USING (bucket_id = 'promotion-images' AND public.has_role(auth.uid(), 'admin')); CREATE POLICY "Admins can delete promotion images" ON storage.objects FOR DELETE USING (bucket_id = 'promotion-images' AND public.has_role(auth.uid(), 'admin')); -- ADMIN-MEDIA: Public read, admin-only write CREATE POLICY "Admin media is publicly accessible" ON storage.objects FOR SELECT USING (bucket_id = 'admin-media'); CREATE POLICY "Admins can upload admin media" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'admin-media' AND public.has_role(auth.uid(), 'admin')); CREATE POLICY "Admins can update admin media" ON storage.objects FOR UPDATE USING (bucket_id = 'admin-media' AND public.has_role(auth.uid(), 'admin')); CREATE POLICY "Admins can delete admin media" ON storage.objects FOR DELETE USING (bucket_id = 'admin-media' AND public.has_role(auth.uid(), 'admin'));

Edge Functions

All 18 edge functions are Deno-based serverless functions deployed to Supabase. JWT verification is disabled for all functions (they handle auth internally).

FunctionPurposeAuth ModelTrigger
complete-installationSetup wizard finalization, creates admin userNone (first-run only)HTTP POST
seed-demo-usersCreate demo accounts for testingNoneHTTP POST
admin-create-userCreate new user accountsAdmin JWT (internal check)HTTP POST
admin-update-userUpdate user profiles & rolesAdmin JWT (internal check)HTTP POST
admin-delete-userDelete user accountsAdmin JWT (internal check)HTTP POST
admin-update-app-settingsUpdate application settingsAdmin JWT (internal check)HTTP POST
ai-chatAI assistant with streaming responsesUser JWTHTTP POST
smart-repliesAI reply suggestionsUser JWTHTTP POST
summarize-chatChat summarizationUser JWTHTTP POST
translate-messageMessage translationUser JWTHTTP POST
transcribe-audioAudio-to-text transcriptionUser JWTHTTP POST
ai-call-summaryCall transcript & summaryUser JWTHTTP POST
send-push-notificationBrowser push notification deliveryUser JWTHTTP POST
on-new-messageTrigger notifications on new messagesDB trigger (service role)Database webhook
on-new-channel-messageTrigger notifications on channel postsDB trigger (service role)Database webhook
process-scheduled-messagesSend scheduled messages when dueCron (service role)Scheduled / HTTP
check-lead-follow-upsSend lead inactivity remindersCron (service role)Scheduled / HTTP
cleanup-stale-callsClean abandoned call recordsCron (service role)Scheduled / HTTP

Custom Hooks Reference

SwiftChat includes 95+ custom React hooks organized by feature domain:

DomainHooks
MessaginguseMessages, useConversations, useMessageReactions, useMessageSearch, useReadReceipts, useTypingIndicator, useForwardMessage, usePinnedMessages, useStarredMessages, useScheduledMessages, useSmartReplies, usePollVoting, useEventRsvp
CallsuseWebRTC, useGroupWebRTC, useCalls, useCallHistory, useCallRecording, useCallRecordings, useCallNotifications, useCallQualityMonitor, useCallSignalStrength, useVirtualBackground, useInCallChat, useAICallSummary
MeetingsuseMeetings, useMeetingWebRTC, useMeetingChat, useMeetingNotes, useMeetingRecording, useMeetingRecordings, useMeetingTemplates, useMeetingAnalytics
ChannelsuseChannels, useChannelAnalytics
CommunitiesuseCommunities, useCommunityAnalytics, useCommunitySettings, useCommunityAvatarUpload
CRMuseLeads, useLeadScoring, useLeadTemplates, useLeadConversion, useLeadImportExport, useLeadReminderSettings, useContactActivity
CommerceuseOrders, usePaymentGateways, usePromotions, usePromotionABTesting, usePromotionCoupons, usePromotionAnalytics, usePromotionDetailAnalytics, usePromotionImageUpload
AIuseAIChat, useChatSummary, useSpeechRecognition, useSpeechSynthesis, useSpeechToText
MediauseFileUpload, useVoiceRecorder, useAvatarUpload, useGroupAvatarUpload, useMediaSelection, useSharedMedia
AdminuseAdminStats, useAdminRealtimeStats, useAdminUsers, useAdminConversations, useAdminMessages, useAdminRole, useAdminPermissions, useAdminActivityLogs, useAdminMedia
SystemuseAppSettings, useDynamicSettings, useDynamicFavicon, useInstallationStatus, useProfiles, useProfileStats, useBadgeCounts, useNotifications, useNotificationSound, usePushNotifications, useMessageNotifications, useInboxMessages, useContacts, useUserNotes, useStatuses, useAutoAway, useDemoAccount, usePWAInstall, useWorkflows, useInviteCodeHandler
UIuse-mobile, use-media-query, use-toast, useScrollAnimation, useSwipeGesture, usePullToRefresh

📱 PWA & Mobile

SwiftChat is a Progressive Web App installable on any device.

Requirements: PWA features require HTTPS. Push notifications additionally require VAPID_PRIVATE_KEY to be configured.

🌐 Internationalization

13 languages supported via i18next with automatic language detection:

🇺🇸 English

en.json

🇪🇸 Spanish

es.json

🇫🇷 French

fr.json

🇩🇪 German

de.json

🇵🇹 Portuguese

pt.json

🇨🇳 Chinese

zh.json

🇯🇵 Japanese

ja.json

🇰🇷 Korean

ko.json

🇸🇦 Arabic (RTL)

ar.json

🇮🇳 Hindi

hi.json

🇧🇩 Bengali

bn.json (via hi)

🇮🇹 Italian

it.json

🇷🇺 Russian

ru.json

Users can switch languages via Settings → Language. The app remembers the preference across sessions.

🔒 Security

Authentication

Data Protection

🧪 Demo / Test Mode

Set VITE_DEMO_MODE=true in .env to enable demo mode for testing or showcasing.

What Demo Mode Does

Demo Accounts

After enabling demo mode, invoke the seed-demo-users edge function to create test accounts:

EmailPasswordRole
admin@demo.comAdmin123!Admin
moderator@demo.comModerator123!Moderator
user@demo.comUser123!User
Production Warning: Always set VITE_DEMO_MODE=false and remove demo accounts before going live. Demo mode is controlled via environment variable only — no client-side bypass is possible.

Available Scripts

CommandDescription
npm run devStart development server on port 8080
npm run buildBuild production bundle to dist/
npm run previewPreview production build locally
npm run lintRun ESLint code linting
npx supabase loginAuthenticate with Supabase CLI
npx supabase link --project-ref IDLink to Supabase project
npx supabase db pushDeploy database migrations
npx supabase functions deployDeploy all edge functions
npx supabase functions serveRun edge functions locally for development
npx web-push generate-vapid-keysGenerate VAPID keys for push notifications

🔧 Troubleshooting

404 on page refresh
Your server isn't configured for SPA routing. Add try_files $uri $uri/ /index.html (Nginx) or .htaccess rewrite rules (Apache). See Deployment Options.
"Failed to send a request to the Edge Function"
1. Verify edge functions are deployed: npx supabase functions list
2. Check that your domain uses HTTPS
3. Check CORS — edge functions allow any HTTPS origin by default
4. Verify the function isn't timing out (check Supabase Dashboard → Edge Functions → Logs)
"Row violates row-level security policy"
Sign out and sign back in. Verify the user is authenticated and their user_id matches the RLS policy. Check that the user's role allows the operation.
Setup wizard keeps showing
Check app_settings table for installation.completed = true. Verify the is_app_installed() function exists. Try VITE_FORCE_SETUP=false.
Admin can't access /admin after clearing cache
This is a known race condition — the auth session must fully restore before the admin role check runs. Wait a moment and refresh, or sign out and back in.
Build fails with TypeScript errors
Run npm run build 2>&1 to see full error output. Common causes: outdated types file, missing imports. Try deleting node_modules and reinstalling.
AI features not working
Verify GEMINI_API_KEY is set in your Edge Function Secrets. Check function logs in the Supabase Dashboard → Edge Functions → select function → Logs.
Push notifications not working
Requires HTTPS. User must grant browser permission. Verify VAPID_PRIVATE_KEY is set in Edge Function Secrets. Check browser console for service worker errors.
WebRTC calls failing
Requires HTTPS. Check browser console for ICE connection errors. Ensure STUN servers (stun1–stun4.l.google.com) are accessible. Some corporate firewalls may block WebRTC.
Migration errors
If npx supabase db push fails, try: npx supabase db push --debug to see detailed error output. Common issues: migration ordering, existing objects, permission errors.
Storage upload failures
Check that the storage bucket exists and has the correct RLS policies. Verify the file meets the bucket's size and MIME type restrictions. See Storage Buckets reference.
Real-time not updating
Verify the table has been added to the supabase_realtime publication. Check browser console for WebSocket connection errors. Ensure RLS policies allow SELECT for the user.

❓ FAQ

Can I use SwiftChat without Supabase?

No. SwiftChat is built on Supabase for its database, authentication, storage, realtime, and edge functions. All backend logic depends on Supabase.

Is SwiftChat free to use?

SwiftChat itself is open-source. You'll need a Supabase project (free tier available) and a server to host the frontend. AI features require a Gemini API key (free tier available from Google).

Can I customize the branding?

Yes. Use the Admin Panel → Settings to change the site name, logo, favicon, colors, and more. All branding is configurable without code changes.

How do I add a new language?

Create a new JSON file in src/i18n/locales/ (e.g., tr.json for Turkish) following the structure of en.json. Register it in the i18next configuration.

How do I set up cron jobs for scheduled functions?

In the Supabase Dashboard, go to Database → Extensions and enable pg_cron. Then create cron jobs that call your edge functions via HTTP. Example:

SELECT cron.schedule('process-messages', '*/5 * * * *', 
  $$SELECT net.http_post('https://YOUR_REF.supabase.co/functions/v1/process-scheduled-messages', '{}', '{}', 
  ARRAY[net.http_header('Authorization', 'Bearer YOUR_SERVICE_ROLE_KEY')])$$);

How many concurrent users can SwiftChat handle?

This depends on your Supabase plan. The free tier supports ~50 concurrent realtime connections. Paid plans scale to thousands. WebRTC calls are peer-to-peer, so they don't consume server resources beyond signaling.

Can I deploy SwiftChat on shared hosting?

Yes, if the host supports serving static files with URL rewriting (most cPanel hosts do). See the Apache / cPanel deployment guide.

📝 Changelog

v1.4.2 Latest

Released: February 20, 2026

✨ New Features

🔧 Improvements

🐛 Bug Fixes

🗑️ Removed

v1.3.0

Released: February 15, 2026

✨ New Features

🔧 Improvements

🐛 Bug Fixes

🔒 Security

v1.0.0

Released: January 20, 2026

🔒 Security

✨ Initial Release

📄 License

SwiftChat is released under the MIT License. See the LICENSE file in the project root for details.