Architecture
Honeycomb is a SvelteKit application deployed to Cloudflare Pages. It serves as the frontend for the Mindhyv social-business platform, connecting to Supabase for authentication, database, and realtime features.
Directory structure
Section titled “Directory structure”honeycomb/├── src/│ ├── routes/ # SvelteKit file-based routing│ │ ├── (app)/ # Protected routes (feed, messages, settings, ...)│ │ ├── (auth)/ # Sign-in, sign-up, forgot-password│ │ ├── (marketing)/ # Public landing and marketing pages│ │ ├── (onboarding)/ # Post-signup onboarding flow│ │ ├── (sitebuilder)/ # Site builder feature│ │ ├── api/ # API routes (+server.ts endpoints)│ │ ├── +layout.server.ts # Root server layout (session + cookies)│ │ ├── +layout.ts # Root universal layout (Supabase browser client)│ │ └── +layout.svelte # Root Svelte layout (providers, auth listener)│ ├── lib/│ │ ├── modules/ # Feature modules (auth, post, messaging, ...)│ │ ├── components/ # Shared UI components│ │ ├── server/ # Server-only utilities (guards, helpers)│ │ ├── services/ # Service layer (payments, notifications, ...)│ │ ├── hooks/ # Reusable Svelte hooks│ │ ├── schemas/ # Shared Zod schemas│ │ ├── types/ # Global TypeScript types│ │ ├── utils/ # Shared utility functions│ │ └── apps/ # Extension/app registrations│ └── hooks.server.ts # Server middleware (Supabase client + route guards)├── supabase/ # Supabase config, migrations, seed data├── svelte.config.js # SvelteKit config with Cloudflare adapter└── wrangler.toml # Cloudflare Pages deployment configRoute groups
Section titled “Route groups”SvelteKit route groups (parenthesized directories) organize pages by access level. The grouping does not affect the URL path.
(app)/ — Protected routes
Section titled “(app)/ — Protected routes”Everything under (app)/ requires authentication and completed onboarding. This includes the main application pages:
/feed— Social feed/messages— Chat and messaging/notifications— Notification center/profile— User profiles/settings— Account settings/wallet— Payments and wallet/marketplace— Product and service marketplace/business— Business dashboard and extension management/admin— Admin panel (requiresadminrole)- Plus 15+ additional feature routes (explore, bookmarks, drafts, stories, jobs, store, courses, events, and more)
The (app)/+layout.server.ts loader fetches data needed by every protected page: the current user profile, unread notification count, and installed apps for the sidebar.
(auth)/ — Authentication routes
Section titled “(auth)/ — Authentication routes”Sign-in, sign-up, forgot-password, and reset-password pages. Authenticated users who navigate here are redirected to /feed.
(marketing)/ — Public pages
Section titled “(marketing)/ — Public pages”Landing page and marketing content. The landing page (/) redirects authenticated users to /feed.
(onboarding)/ — Onboarding flow
Section titled “(onboarding)/ — Onboarding flow”Post-signup onboarding wizard. Protected routes check whether onboarding is complete and redirect here if not.
Server middleware: hooks.server.ts
Section titled “Server middleware: hooks.server.ts”All authentication and authorization logic is centralized in src/hooks.server.ts using two sequenced handlers:
1. Supabase client setup
Section titled “1. Supabase client setup”Creates a server-side Supabase client attached to event.locals.supabase and a safeGetSession helper that securely validates the user via getUser() (not just the JWT).
2. Route guard
Section titled “2. Route guard”A single guard handler enforces all access rules so that individual +page.server.ts and +layout.server.ts files do not contain auth redirects:
| Condition | Behavior |
|---|---|
| Public route (webhooks, auth callbacks) | Pass through, no check |
| Unauthenticated user on protected route | Redirect to /sign-in |
Authenticated user on auth page (/sign-in, /sign-up) | Redirect to /feed |
Authenticated user on landing page (/) | Redirect to /feed |
Admin route without admin role | Redirect to /feed |
| Protected route without completed onboarding | Redirect to /onboarding |
Route classification is handled by functions in src/lib/server/guards.ts.
Data flow
Section titled “Data flow”Data flows through a well-defined chain from server to client to component:
hooks.server.ts Middleware: creates Supabase client, enforces guards ↓+layout.server.ts (root) Loads session, user, and cookies ↓+layout.ts (root) Creates browser Supabase client, exposes session ↓+layout.server.ts (app) Loads profile, unread count, installed apps ↓+page.server.ts Loads page-specific data (posts, messages, etc.) ↓+page.svelte Receives all data via $props(), renders the page ↓Child components Receive slices of data via $props()Root layout server (+layout.server.ts)
Section titled “Root layout server (+layout.server.ts)”Returns the session, user object, and serialized cookies. This data is available to every page in the app.
Root universal layout (+layout.ts)
Section titled “Root universal layout (+layout.ts)”Creates the appropriate Supabase client depending on the environment:
- Browser:
createBrowserClientfor client-side queries and realtime subscriptions - Server:
createServerClientusing cookies from the server layout
Registers a supabase:auth dependency so that invalidate('supabase:auth') triggers a data reload on auth state changes.
Root Svelte layout (+layout.svelte)
Section titled “Root Svelte layout (+layout.svelte)”Sets up global providers and listeners:
- Auth state listener: Watches for session changes and calls
invalidate('supabase:auth')when the token expires or refreshes - ModeWatcher: Dark/light mode support
- Toaster: Toast notifications via
svelte-sonner
App layout server ((app)/+layout.server.ts)
Section titled “App layout server ((app)/+layout.server.ts)”Fetches three things for every protected page:
- Profile: Username, avatar, name, verified status, role, type
- Unread notifications: Count of notifications with
read_at IS NULL - Installed apps: Active apps from
user_appsjoined withappsfor slug, name, and icon
This data powers the sidebar, header, and notification badge across the entire app shell.
Deployment
Section titled “Deployment”Cloudflare Pages
Section titled “Cloudflare Pages”The app uses @sveltejs/adapter-cloudflare configured in svelte.config.js:
import adapter from '@sveltejs/adapter-cloudflare';
const config = { kit: { adapter: adapter() }};Server-side code (hooks, server loaders, API routes) runs as Cloudflare Workers. Static assets are served from Cloudflare’s CDN.
Environment variables
Section titled “Environment variables”Public variables (prefixed with PUBLIC_) are embedded at build time:
PUBLIC_SUPABASE_URL— Supabase project URLPUBLIC_SUPABASE_PUBLISHABLE_KEY— Supabase anon/publishable key
Secret variables are configured in the Cloudflare dashboard and accessed via $env/static/private or platform bindings.
Key conventions
Section titled “Key conventions”- Centralized guards: All auth logic in
hooks.server.ts, never in page loaders. - Barrel imports: Modules export through
index.tsbarrels. Import from$lib/modules/auth, not from internal files. - Server code stays in routes:
+page.server.tsand+server.tsfiles handle form actions and API endpoints. Module folders contain only client-importable code. - Supabase on both sides: Server uses
event.locals.supabase(cookie-based). Client uses the browser client from+layout.ts. Both share the same session. - Svelte 5 runes: Components use
$props(),$derived(), and$state()for reactivity.