Frameworks

SvelteKit

Mount the Clivly tick route as a SvelteKit +server.ts handler.

The docs work better when framework-specific scaffolding is on its own route instead of being buried in one huge page.

Every framework wraps the same createClivlyHandler(), and every route resolves to the same public URL: /api/clivly/tick. In SvelteKit, clivly init scaffolds a +server.ts handler at src/routes/api/clivly/tick/+server.ts.

SvelteKit, Remix, and Nuxt are all scaffolded by clivly init — each mounts the same handler behind its own router's export shape.

SvelteKit

src/routes/api/clivly/tick/+server.ts
import clivly from "../../../../clivly.config";
import type { RequestHandler } from "./$types";

const handler = clivly.createClivlyHandler();

export const POST: RequestHandler = ({ request }) => handler(request);

Load dotenv in your Vite config

SvelteKit populates its own $env/* modules and leaves process.env empty. Your clivly.config.ts reads process.env, and so does better-auth, so add one line to vite.config.ts:

vite.config.ts
import "dotenv/config";
import adapter from "@sveltejs/adapter-auto";
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [sveltekit({ adapter: adapter() })],

// Only needed for tunnelled local development — see below.
server: { allowedHosts: [".trycloudflare.com"] },
});

The scaffolded src/hooks.server.ts imports dotenv/config too, which covers the running server. The Vite config is what covers vite build.

`allowedHosts` is what makes `clivly dev` work

Vite refuses any Host header it does not recognise, so a tunnelled request is rejected with 403 before it reaches your tick route — and the dashboard reports "The host app returned 403", naming Clivly rather than Vite. Allowing the tunnel domain fixes it while keeping the allowlist tight. Skip this line if you never use clivly dev.

Without this line the production build fails

The auth-verify route pulls better-auth in through its own import graph, which never loads the boot hook. A vite build then dies with BetterAuthError: You are using the default secret, naming better-auth rather than the missing env file. clivly init prints this step for you rather than editing a config file it does not own.

This is not the edge rule

Elsewhere the docs warn that clivly.config.ts must never touch the filesystem, because it runs wherever your app runs — including edge runtimes with no node:fs. vite.config.ts is a different file that runs only on your build machine, where reading a .env is fine.