Files
gw-svelte/src/hooks.server.ts
T

38 lines
1.4 KiB
TypeScript
Raw Normal View History

2026-05-18 22:25:43 +12:00
import type { Handle } from '@sveltejs/kit';
2026-05-19 23:36:58 +12:00
import { resolveSurface } from '$lib/server/surface';
import { resolveAnonId, resolveHeroVariant } from '$lib/server/ab';
2026-05-18 22:25:43 +12:00
const ADMIN_PATH = '/owner/welcome';
export const handle: Handle = async ({ event, resolve }) => {
2026-05-19 23:36:58 +12:00
const { surface } = resolveSurface(event.url, event.cookies);
2026-05-18 22:25:43 +12:00
const path = event.url.pathname;
// Sticky A/B assignment, marketing surface only — no point polluting the
// owner/clients hosts with marketing-experiment cookies, and it skews
// exposure counts when staff hit the public site from the dashboard.
if (surface === 'marketing') {
event.locals.anonId = resolveAnonId(event.cookies);
event.locals.abHero = resolveHeroVariant(event.url, event.cookies);
}
2026-05-19 23:36:58 +12:00
// The admin host (cp.*) serves the dashboard at its root.
if (surface === 'cp' && (path === '/' || path === '')) {
2026-05-18 22:25:43 +12:00
return new Response(null, {
status: 302,
headers: { location: ADMIN_PATH },
});
}
2026-05-19 23:36:58 +12:00
// Block the admin dashboard from the public marketing site so /owner/*
// only renders on the cp surface (or on the clients surface during the
// legacy onboarding-host transition window). Localhost dev preview is
// allowed: resolveSurface returns 'cp' there too when ?preview=cp or
// ?preview=admin is set.
if (surface === 'marketing' && path.startsWith('/owner/')) {
2026-05-18 22:25:43 +12:00
return new Response('Not Found', { status: 404 });
}
return resolve(event);
};