# @velastack/kit

Backend-agnostic SvelteKit plumbing, shared by Vela's backend bindings. Nothing in this package knows about any particular database — [@velastack/pocketbase](/helpers/pocketbase) and its siblings build on it.

```
npm install @velastack/kit
```

#### Match&lt;RouteId&gt;

Turns a SvelteKit route id into the shape of the URLs that match it — route groups are stripped and `[param]` segments widen to `string`. Useful for keeping test URLs honest:

```ts
import type { Match } from '@velastack/kit';
import type { RouteId } from './$types';

const res = await context.request.get('/dashboard' satisfies Match<RouteId>);
```

Segments that may match nothing — `[[optional]]` and `[...rest]` — widen to a union including the variant where the segment is absent, so both of these hold for `/[[lang]]/blog`:

```ts
'/blog' satisfies Match<'/[[lang]]/blog'>;
'/en/blog' satisfies Match<'/[[lang]]/blog'>;
```

The widening is deliberately loose — `string` also spans `/`, so a URL with extra segments can still satisfy a single `[param]`.

#### proxy

`proxy(url, event)` forwards the current request to `url` and returns the upstream response. Hop-by-hop headers are stripped and `accept-encoding: identity` is pinned so the body streams through untouched. The incoming `event.request.headers` is copied, never mutated.

#### protectedRouteRedirect

Returns a 302 to `loginPath`, with the original destination in a `redirect` query parameter, when an unauthenticated request matches one of `protectedRoutes` by route-id prefix — or `null` when the request may proceed. This is what backs the [auth](/enable/auth) module's `(app)` group.

```ts
protectedRouteRedirect({
	routeId: event.route.id,
	url: event.url,
	protectedRoutes: ['/(app)'],
	loginPath: '/login',
	authenticated: pb.authStore.isValid,
	clearCookies: ['pb_auth']
});
```

#### errorPage

`errorPage(status, message)` renders a standalone HTML error page styled for both colour schemes. `message` is interpolated as **trusted HTML** and is not escaped — never pass user input to it.

#### handleStatic

The whole server hook for a project with no backend. In development it answers a 404 on a page a `vela` command has yet to generate with the command that creates it, and does nothing otherwise. It takes no options — there is no backend to point it at.

```ts
// src/hooks.server.ts
import { handleStatic } from '@velastack/kit';

export const handle = handleStatic();
```

`LEGAL_PAGES` and `AUTH_PAGES` map those paths to the command that creates them, and `generatedPageResponse(pathname, pages)` turns one into a 404 that says so, or returns `null` and leaves your own 404 alone. A project with a backend gets the same behaviour, plus the auth pages, from [`handlePocketbase`](/helpers/pocketbase).