Skip to content

Routing

Honeycomb uses SvelteKit’s file-based routing system. Every folder inside src/routes/ maps directly to a URL path, and special files like +page.svelte, +layout.svelte, and +page.server.ts control what renders and what data loads.

SvelteKit route groups (folders wrapped in parentheses) share a layout without affecting the URL path. Honeycomb organizes routes into five groups:

GroupFolderPurpose
App(app)/All authenticated application pages — feed, settings, business, admin, etc.
Auth(auth)/Sign-in, sign-up, forgot/reset password, email verification.
Marketing(marketing)/The public landing page at /.
Onboarding(onboarding)/Post-signup onboarding flow at /onboarding.
Site Builder(sitebuilder)/The drag-and-drop site builder editor and published sites.

Additionally, top-level routes outside groups handle API endpoints (/api/) and short-link redirects (/l/[slug]).

Layouts nest from the root downward. A child layout inherits its parent and can add its own chrome (navigation, sidebars, etc.).

+layout.svelte ← Root: Supabase session provider
├── (app)/+layout.svelte ← App shell: sidebar, top nav, notification badge
│ ├── admin/+layout.svelte ← Admin sidebar
│ ├── settings/+layout.svelte ← Settings sidebar
│ └── honeycomb/+layout.server.ts ← Honeycomb community data
├── (auth)/+layout.svelte ← Centered auth card layout
├── (onboarding)/+layout.svelte ← Onboarding wizard layout
└── (sitebuilder)/+layout.svelte ← Full-screen editor layout

The root server layout calls safeGetSession() and returns session, user, and cookies to every page. This data is available via $page.data or export let data in any +page.svelte.

Fetches the authenticated user’s profile, unread notification count, and installed business apps for the sidebar. All (app) pages receive profile, unreadNotifications, and installedApps in their load data.

The guard system runs as SvelteKit middleware via sequence(supabase, guard) in hooks.server.ts. It executes two handles in order:

Creates the Supabase server client on event.locals.supabase and exposes event.locals.safeGetSession() for downstream use.

Checks every request against the route protection rules defined in $lib/server/guards.ts:

Request arrives
├─ PUBLIC_ROUTES match? → Allow through (no auth check)
│ Examples: /auth/callback, /auth/confirm, /api/stripe/webhook
├─ No session?
│ ├─ isProtectedRoute()? → Redirect to /sign-in
│ └─ Otherwise → Allow through (landing page, auth pages)
└─ Has session?
├─ PUBLIC_AUTH_ROUTES match? → Redirect to /feed
│ Examples: /sign-in, /sign-up, /forgot-password, /reset-password
├─ isLandingPage()? → Redirect to /feed
├─ isAdminRoute()?
│ └─ profile.role !== "admin"? → Redirect to /feed
└─ requiresOnboarding()?
└─ No onboard record? → Redirect to /onboarding

Fully public — no auth check, no redirect:

RoutePurpose
/auth/callbackSupabase OAuth callback
/auth/confirmEmail confirmation handler
/auth/errorAuth error display
/auth/forgot-passwordServer-side password reset action
/auth/reset-passwordServer-side password reset action
/auth/resend-verificationResend email verification
/verify-emailEmail verification page
/api/stripe/webhookStripe webhook endpoint

Auth pages — unauthenticated only (authenticated users redirect to /feed):

RoutePurpose
/sign-inLogin form
/sign-upRegistration form
/forgot-passwordRequest password reset
/reset-passwordSet new password

Protected — authenticated + onboarding complete:

Route prefixPurpose
/feedSocial feed
/post/[id]Single post view
/exploreDiscover content
/bookmarksSaved posts
/draftsUnpublished drafts
/profileUser profiles
/messagesDirect messages
/notificationsActivity notifications
/settingsUser settings
/walletWallet and transactions
/marketplaceProduct marketplace
/jobsJob listings
/businessBusiness dashboard and apps
/store/[id]Storefront view
/onboardingOnboarding flow (exempt from onboarding check itself)

Admin — authenticated + role === "admin":

Route prefixPurpose
/adminAdmin dashboard
/admin/usersUser management
/admin/postsPost moderation
/admin/productsProduct moderation
/admin/jobsJob moderation
/admin/adsAd management
/admin/categoriesCategory management
/admin/blacklistBlacklisted terms
/admin/reportsReport review

Below is every major route in the application grouped by section.

RouteFile pathDescription
/feed(app)/feed/Main social feed
/explore(app)/explore/Discover content and users
/post/[id](app)/post/[id]/View a single post
/bookmarks(app)/bookmarks/Bookmarked posts
/drafts(app)/drafts/Draft posts
/stories(app)/stories/Stories feed
/stories/[userId](app)/stories/[userId]/User’s stories
/notifications(app)/notifications/Activity notifications
RouteFile path
/honeycomb(app)/honeycomb/
/honeycomb/rooms(app)/honeycomb/rooms/
/honeycomb/rooms/create(app)/honeycomb/rooms/create/
/honeycomb/rooms/[slug](app)/honeycomb/rooms/[slug]/
/honeycomb/rooms/[slug]/members(app)/honeycomb/rooms/[slug]/members/
/honeycomb/rooms/[slug]/settings(app)/honeycomb/rooms/[slug]/settings/
/honeycomb/messages(app)/honeycomb/messages/
/honeycomb/messages/[conversationId](app)/honeycomb/messages/[conversationId]/
/honeycomb/calls(app)/honeycomb/calls/
/honeycomb/calls/[callId](app)/honeycomb/calls/[callId]/
/honeycomb/broadcast(app)/honeycomb/broadcast/
/honeycomb/polls(app)/honeycomb/polls/
/honeycomb/games(app)/honeycomb/games/
/honeycomb/badges(app)/honeycomb/badges/
/honeycomb/stickers(app)/honeycomb/stickers/
/honeycomb/ads(app)/honeycomb/ads/
/honeycomb/memberships(app)/honeycomb/memberships/
/honeycomb/moderation(app)/honeycomb/moderation/
/honeycomb/moderation/bans(app)/honeycomb/moderation/bans/
/honeycomb/moderation/filters(app)/honeycomb/moderation/filters/
/honeycomb/settings(app)/honeycomb/settings/
RouteFile path
/messages(app)/messages/
/messages/[chatId](app)/messages/[chatId]/
/forums(app)/forums/
/forums/[forumSlug](app)/forums/[forumSlug]/
/forums/[forumSlug]/[topicSlug](app)/forums/[forumSlug]/[topicSlug]/
/forums/[forumSlug]/new(app)/forums/[forumSlug]/new/
/learn/[slug](app)/learn/[slug]/
/learn/[slug]/[itemId](app)/learn/[slug]/[itemId]/
/learn/[slug]/quiz/[quizId](app)/learn/[slug]/quiz/[quizId]/
/learn/[slug]/assignment/[assignmentId](app)/learn/[slug]/assignment/[assignmentId]/
RouteFile path
/business(app)/business/
/business/ads/new(app)/business/ads/new/
/business/products(app)/business/products/
/business/products/new(app)/business/products/new/
/business/products/[id](app)/business/products/[id]/
/business/products/[id]/edit(app)/business/products/[id]/edit/
/business/jobs(app)/business/jobs/
/business/jobs/new(app)/business/jobs/new/
/business/store(app)/business/store/
/business/upgrade(app)/business/upgrade/
/business/apps(app)/business/apps/
/business/apps/*25+ installable business apps (see Business pages)
RouteFile path
/marketplace(app)/marketplace/
/marketplace/product/[id](app)/marketplace/product/[id]/
/jobs(app)/jobs/
/jobs/[id](app)/jobs/[id]/
/store/[id](app)/store/[id]/
RouteFile path
/settings(app)/settings/
/settings/profile(app)/settings/profile/
/settings/account(app)/settings/account/
/settings/security(app)/settings/security/
/settings/privacy(app)/settings/privacy/
/settings/notifications(app)/settings/notifications/
/settings/social(app)/settings/social/
RouteFile path
/profile(app)/profile/ (redirects to own profile)
/profile/[username](app)/profile/[username]/
/profile/[username]/blog(app)/profile/[username]/blog/
/profile/[username]/blog/[slug](app)/profile/[username]/blog/[slug]/
/profile/[username]/store(app)/profile/[username]/store/
/profile/[username]/store/[slug](app)/profile/[username]/store/[slug]/
/profile/[username]/plans(app)/profile/[username]/plans/
/profile/[username]/plans/[slug](app)/profile/[username]/plans/[slug]/
/profile/[username]/followers(app)/profile/[username]/followers/
/profile/[username]/following(app)/profile/[username]/following/
/profile/[username]/links(app)/profile/[username]/links/
/profile/[username]/book(app)/profile/[username]/book/
RouteFile path
/wallet(app)/wallet/
/affiliates(app)/affiliates/
/affiliates/referrals(app)/affiliates/referrals/
RouteFile pathDescription
/verify/[code](app)/verify/[code]/Verification code handler
/sign/[id](app)/sign/[id]/E-signature signing page
/document/[code](app)/document/[code]/Shared document viewer
/file-request/[id](app)/file-request/[id]/File request submission
/bundles/[slug](app)/bundles/[slug]/Product bundle view
/certificates(app)/certificates/Certificate viewer
/courses(app)/courses/Browse courses
/courses/[slug](app)/courses/[slug]/Course detail
/events(app)/events/Browse events
/events/[slug](app)/events/[slug]/Event detail
/support(app)/support/Support tickets
/support/new(app)/support/new/Create support ticket
/support/[ticketId](app)/support/[ticketId]/View ticket
/dashboard(app)/dashboard/Dashboard
/sign-out(app)/sign-out/Session logout
/l/[slug]l/[slug]/Short-link redirect

Add a new folder under the correct route group. For a protected page, put it inside (app)/:

src/routes/(app)/my-new-page/
+page.svelte ← The page component
+page.server.ts ← Server load function (optional)

If the route prefix is not already covered by isProtectedRoute() in $lib/server/guards.ts, add a new if statement:

if (path.startsWith("/my-new-page")) return true;

If the page needs its own sidebar or sub-navigation, add +layout.svelte in the route folder. It will nest inside the (app) layout automatically.

Your page can access the app layout data (profile, installed apps, etc.) through the standard SvelteKit load chain:

<script lang="ts">
export let data;
// data.profile, data.user, data.installedApps are available
</script>