When converting SvelteKit routes from +page.server.ts to universal +page.ts for Capacitor compatibility, watch for server-only APIs that silently work differently in universal context:
localsis unavailable —event.locals.userdoesn't exist in universal loads. Move user context to a client-side store (get_ctx()) and consume it in the component instead of the loader return value.loggerfrom server modules —$lib/server/*imports fail in universal loads. Replace withconsole.error.Timezone-dependent computations survive —
new Date().toLocaleDateString('en-CA', { timeZone: 'America/New_York' })works identically in browser JS, so server-computed timezone values can move to universal loads without change.Type safety gap — TypeScript won't catch the
localsremoval at the loader level becausePageLoadsimply doesn't havelocalsin its type. But downstream components referencingdata.self_username(removed from return) will fail atsvelte-checktime. Always runsvelte-checkafter conversion, not justtsc.Pair with
webPathToMobile— Even after converting to universal loads, mobile routes may still benefit from redirection to a dedicated mobile page (e.g.,/pulse→/m/explorewhere pulse is embedded with bottom tabs). The universal load conversion makes the web route work in-app; the redirect makes it good in-app.