From 982629f507e196595b72b4ca9288ce9bc24e7f72 Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 2 Apr 2026 01:53:36 +0200 Subject: [PATCH] feat(manacore/web): add subdomain-to-path routing for all apps Redirect app subdomains (e.g. todo.mana.how) to their path equivalent (mana.how/todo) so each app is reachable via its own subdomain while running as a single SvelteKit app. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/manacore/apps/web/src/hooks.server.ts | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/apps/manacore/apps/web/src/hooks.server.ts b/apps/manacore/apps/web/src/hooks.server.ts index a6f08d69f..baaedef08 100644 --- a/apps/manacore/apps/web/src/hooks.server.ts +++ b/apps/manacore/apps/web/src/hooks.server.ts @@ -25,7 +25,46 @@ const PUBLIC_CONTACTS_API_URL_CLIENT = process.env.PUBLIC_CONTACTS_API_URL_CLIENT || process.env.PUBLIC_CONTACTS_API_URL || ''; const PUBLIC_GLITCHTIP_DSN = process.env.PUBLIC_GLITCHTIP_DSN || ''; +// Map of app subdomains to internal paths +const APP_SUBDOMAINS = new Set([ + 'todo', + 'chat', + 'calendar', + 'clock', + 'contacts', + 'zitare', + 'skilltree', + 'planta', + 'cards', + 'storage', + 'presi', + 'nutriphi', + 'photos', + 'mukke', + 'picture', + 'calc', + 'citycorners', + 'inventar', + 'times', + 'uload', + 'memoro', + 'context', + 'questions', + 'moodlit', +]); + export const handle: Handle = async ({ event, resolve }) => { + // Redirect app subdomains to their path equivalent + // e.g. todo.mana.how → mana.how/todo + const host = event.request.headers.get('host') || ''; + const subdomain = host.split('.')[0]; + if (APP_SUBDOMAINS.has(subdomain) && event.url.pathname === '/') { + return new Response(null, { + status: 302, + headers: { Location: `/${subdomain}` }, + }); + } + const response = await resolve(event, { transformPageChunk: ({ html }) => { const envScript = `