Skip to main content

Types

Edit this page on GitHub

@sveltejs/kitpermalink

The following types can be imported from @sveltejs/kit:

Adapterpermalink

interface Adapter {
  name: string;
  adapt(builder: Builder): MaybePromise<void>;
}

Builderpermalink

interface Builder {
  log: Logger;
  rimraf(dir: string): void;
  mkdirp(dir: string): void;

  config: ValidatedConfig;
  prerendered: Prerendered;
  /**   * Create entry points that map to individual functions   * @param fn A function that groups a set of routes into an entry point   */  createEntries(
    fn: (route: RouteDefinition) => AdapterEntry
  ): Promise<void>;

  generateManifest: (opts: {
    relativePath: string;
    format?: 'esm' | 'cjs';
  }) => string;

  getBuildDirectory(name: string): string;
  getClientDirectory(): string;
  getServerDirectory(): string;
  getStaticDirectory(): string;
  /**   * @param dest the destination folder to which files should be copied   * @returns an array of paths corresponding to the files that have been created by the copy   */  writeClient(dest: string): string[];
  /**   *   * @param dest   */  writePrerendered(
    dest: string,
    opts?: {
      fallback?: string;
    }
  ): string[];
  /**   * @param dest the destination folder to which files should be copied   * @returns an array of paths corresponding to the files that have been created by the copy   */  writeServer(dest: string): string[];
  /**   * @param dest the destination folder to which files should be copied   * @returns an array of paths corresponding to the files that have been created by the copy   */  writeStatic(dest: string): string[];
  /**   * @param from the source file or folder   * @param to the destination file or folder   * @param opts.filter a function to determine whether a file or folder should be copied   * @param opts.replace a map of strings to replace   * @returns an array of paths corresponding to the files that have been created by the copy   */  copy(
    from: string,
    to: string,
    opts?: {
      filter?: (basename: string) => boolean;
      replace?: Record<string, string>;
    }
  ): string[];
}

Configpermalink

interface Config {
  compilerOptions?: CompileOptions;
  extensions?: string[];
  kit?: UserConfig;
  preprocess?: any;
}

ExternalFetchpermalink

interface ExternalFetch {
  (req: Request): Promise<Response>;
}

GetSessionpermalink

interface GetSession {
  (event: RequestEvent): MaybePromise<App.Session>;
}

Handlepermalink

interface Handle {
  (input: {
    event: RequestEvent;
    resolve(
      event: RequestEvent,
      opts?: ResolveOptions
    ): MaybePromise<Response>;
  }): MaybePromise<Response>;
}

HandleErrorpermalink

interface HandleError {
  (input: {
    error: Error & { frame?: string };
    event: RequestEvent;
  }): void;
}

Loadpermalink

The (event: LoadEvent) => LoadOutput load function exported from <script context="module"> in a page or layout.

Note that you can use generated types instead of manually specifying the Params generic argument.

interface Load<
  Params extends Record<string, string> = Record<
    string,
    string
  >,
  InputProps extends Record<string, any> = Record<
    string,
    any
  >,
  OutputProps extends Record<string, any> = InputProps
> {
  (event: LoadEvent<Params, InputProps>): MaybePromise<
    LoadOutput<OutputProps>
  >;
}

LoadEventpermalink

interface LoadEvent<
  Params extends Record<string, string> = Record<
    string,
    string
  >,
  Props extends Record<string, any> = Record<string, any>
> {
  fetch(
    info: RequestInfo,
    init?: RequestInit
  ): Promise<Response>;
  params: Params;
  props: Props;
  routeId: string | null;
  session: App.Session;
  stuff: Partial<App.Stuff>;
  url: URL;
  status: number | null;
  error: Error | null;
}

LoadOutputpermalink

interface LoadOutput<
  Props extends Record<string, any> = Record<string, any>
> {
  status?: number;
  error?: string | Error;
  redirect?: string;
  props?: Props;
  stuff?: Partial<App.Stuff>;
  cache?: LoadOutputCache;
  dependencies?: string[];
}

LoadOutputCachepermalink

interface LoadOutputCache {
  maxage: number;
  private?: boolean;
}

Navigationpermalink

interface Navigation {
  from: URL;
  to: URL;
}

Pagepermalink

interface Page<
  Params extends Record<string, string> = Record<
    string,
    string
  >
> {
  url: URL;
  params: Params;
  routeId: string | null;
  stuff: App.Stuff;
  status: number;
  error: Error | null;
}

ParamMatcherpermalink

interface ParamMatcher {
  (param: string): boolean;
}

RequestEventpermalink

interface RequestEvent<
  Params extends Record<string, string> = Record<
    string,
    string
  >
> {
  clientAddress: string;
  locals: App.Locals;
  params: Params;
  platform: Readonly<App.Platform>;
  request: Request;
  routeId: string | null;
  url: URL;
}

RequestHandlerpermalink

A (event: RequestEvent) => RequestHandlerOutput function exported from an endpoint that corresponds to an HTTP verb (get, put, patch, etc) and handles requests with that method. Note that since 'delete' is a reserved word in JavaScript, delete handles are called del instead.

Note that you can use generated types instead of manually specifying the Params generic argument.

interface RequestHandler<
  Params extends Record<string, string> = Record<
    string,
    string
  >,
  Output = ResponseBody
> {
  (event: RequestEvent<Params>): MaybePromise<
    RequestHandlerOutput<Output>
  >;
}

RequestHandlerOutputpermalink

interface RequestHandlerOutput<Output = ResponseBody> {
  status?: number;
  headers?: Headers | Partial<ResponseHeaders>;
  body?: Output extends ResponseBody
    ? Output
    : BodyValidator<Output>;
}

ResolveOptionspermalink

interface ResolveOptions {
  ssr?: boolean;
  transformPage?: ({
    html
  }: {
    html: string;
  }) => MaybePromise<string>;
}

ResponseBodypermalink

type ResponseBody =
  | JSONValue
  | Uint8Array
  | ReadableStream
  | import('stream').Readable;

SSRManifestpermalink

interface SSRManifest {
  appDir: string;
  assets: Set<string>;
  mimeTypes: Record<string, string>;
  /** private fields */  _: {
    entry: {
      file: string;
      js: string[];
      css: string[];
    };
    nodes: SSRNodeLoader[];
    routes: SSRRoute[];
    matchers: () => Promise<Record<string, ParamMatcher>>;
  };
}

Serverpermalink

class Server {
  constructor(manifest: SSRManifest);
  respond(
    request: Request,
    options: RequestOptions
  ): Promise<Response>;
}

UserConfigpermalink

interface UserConfig {
  adapter?: Adapter;
  alias?: Record<string, string>;
  appDir?: string;
  browser?: {
    hydrate?: boolean;
    router?: boolean;
  };
  csp?: {
    mode?: 'hash' | 'nonce' | 'auto';
    directives?: CspDirectives;
  };
  endpointExtensions?: string[];
  files?: {
    assets?: string;
    hooks?: string;
    lib?: string;
    params?: string;
    routes?: string;
    serviceWorker?: string;
    template?: string;
  };
  floc?: boolean;
  inlineStyleThreshold?: number;
  methodOverride?: {
    parameter?: string;
    allowed?: string[];
  };
  outDir?: string;
  package?: {
    dir?: string;
    emitTypes?: boolean;
    exports?(filepath: string): boolean;
    files?(filepath: string): boolean;
  };
  paths?: {
    assets?: string;
    base?: string;
  };
  prerender?: {
    concurrency?: number;
    crawl?: boolean;
    default?: boolean;
    enabled?: boolean;
    entries?: Array<'*' | `/${string}`>;
    onError?: PrerenderOnErrorValue;
  };
  routes?: (filepath: string) => boolean;
  serviceWorker?: {
    register?: boolean;
    files?: (filepath: string) => boolean;
  };
  trailingSlash?: TrailingSlash;
  version?: {
    name?: string;
    pollInterval?: number;
  };
  vite?:
    | import('vite').UserConfig
    | (() => MaybePromise<import('vite').UserConfig>);
}

Additional typespermalink

The following are referenced by the public types documented above, but cannot be imported directly:

AdapterEntrypermalink

interface AdapterEntry {
  /**   * A string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication.   * For example, `/foo/a-[b]` and `/foo/[c]` are different routes, but would both   * be represented in a Netlify _redirects file as `/foo/:param`, so they share an ID   */  id: string;
  /**   * A function that compares the candidate route with the current route to determine   * if it should be treated as a fallback for the current route. For example, `/foo/[c]`   * is a fallback for `/foo/a-[b]`, and `/[...catchall]` is a fallback for all routes   */  filter: (route: RouteDefinition) => boolean;
  /**   * A function that is invoked once the entry has been created. This is where you   * should write the function to the filesystem and generate redirect manifests.   */  complete: (entry: {
    generateManifest: (opts: {
      relativePath: string;
      format?: 'esm' | 'cjs';
    }) => string;
  }) => MaybePromise<void>;
}

BodyValidatorpermalink

type BodyValidator<T> = {
  [P in keyof T]: T[P] extends { [k: string]: unknown }
    ? BodyValidator<T[P]> // recurse when T[P] is an object
    : T[P] extends BigInt | Function | Symbol
    ? never
    : T[P];
};

Csppermalink

namespace Csp {
  type ActionSource = 'strict-dynamic' | 'report-sample';
  type BaseSource =
    | 'self'
    | 'unsafe-eval'
    | 'unsafe-hashes'
    | 'unsafe-inline'
    | 'none';
  type CryptoSource = `${
    | 'nonce'
    | 'sha256'
    | 'sha384'
    | 'sha512'}-${string}`;
  type FrameSource =
    | HostSource
    | SchemeSource
    | 'self'
    | 'none';
  type HostNameScheme = `${string}.${string}` | 'localhost';
  type HostSource =
    `${HostProtocolSchemes}${HostNameScheme}${PortScheme}`;
  type HostProtocolSchemes = `${string}://` | '';
  type HttpDelineator = '/' | '?' | '#' | '\\';
  type PortScheme = `:${number}` | '' | ':*';
  type SchemeSource =
    | 'http:'
    | 'https:'
    | 'data:'
    | 'mediastream:'
    | 'blob:'
    | 'filesystem:';
  type Source =
    | HostSource
    | SchemeSource
    | CryptoSource
    | BaseSource;
  type Sources = Source[];
  type UriPath = `${HttpDelineator}${string}`;
}

CspDirectivespermalink

interface CspDirectives {
  'child-src'?: Csp.Sources;
  'default-src'?: Array<Csp.Source | Csp.ActionSource>;
  'frame-src'?: Csp.Sources;
  'worker-src'?: Csp.Sources;
  'connect-src'?: Csp.Sources;
  'font-src'?: Csp.Sources;
  'img-src'?: Csp.Sources;
  'manifest-src'?: Csp.Sources;
  'media-src'?: Csp.Sources;
  'object-src'?: Csp.Sources;
  'prefetch-src'?: Csp.Sources;
  'script-src'?: Array<Csp.Source | Csp.ActionSource>;
  'script-src-elem'?: Csp.Sources;
  'script-src-attr'?: Csp.Sources;
  'style-src'?: Array<Csp.Source | Csp.ActionSource>;
  'style-src-elem'?: Csp.Sources;
  'style-src-attr'?: Csp.Sources;
  'base-uri'?: Array<Csp.Source | Csp.ActionSource>;
  sandbox?: Array<
    | 'allow-downloads-without-user-activation'
    | 'allow-forms'
    | 'allow-modals'
    | 'allow-orientation-lock'
    | 'allow-pointer-lock'
    | 'allow-popups'
    | 'allow-popups-to-escape-sandbox'
    | 'allow-presentation'
    | 'allow-same-origin'
    | 'allow-scripts'
    | 'allow-storage-access-by-user-activation'
    | 'allow-top-navigation'
    | 'allow-top-navigation-by-user-activation'
  >;
  'form-action'?: Array<Csp.Source | Csp.ActionSource>;
  'frame-ancestors'?: Array<
    Csp.HostSource | Csp.SchemeSource | Csp.FrameSource
  >;
  'navigate-to'?: Array<Csp.Source | Csp.ActionSource>;
  'report-uri'?: Csp.UriPath[];
  'report-to'?: string[];

  'require-trusted-types-for'?: Array<'script'>;
  'trusted-types'?: Array<
    'none' | 'allow-duplicates' | '*' | string
  >;
  'upgrade-insecure-requests'?: boolean;
  /** @deprecated */  'require-sri-for'?: Array<
    'script' | 'style' | 'script style'
  >;
  /** @deprecated */  'block-all-mixed-content'?: boolean;
  /** @deprecated */  'plugin-types'?: Array<`${string}/${string}` | 'none'>;
  /** @deprecated */  referrer?: Array<
    | 'no-referrer'
    | 'no-referrer-when-downgrade'
    | 'origin'
    | 'origin-when-cross-origin'
    | 'same-origin'
    | 'strict-origin'
    | 'strict-origin-when-cross-origin'
    | 'unsafe-url'
    | 'none'
  >;
}

HttpMethodpermalink

type HttpMethod =
  | 'get'
  | 'head'
  | 'post'
  | 'put'
  | 'delete'
  | 'patch';

JSONObjectpermalink

interface JSONObject {
  [key: string]: JSONValue;
}

JSONValuepermalink

type JSONValue =
  | string
  | number
  | boolean
  | null
  | undefined
  | ToJSON
  | JSONValue[]
  | JSONObject;

Loggerpermalink

interface Logger {
  (msg: string): void;
  success(msg: string): void;
  error(msg: string): void;
  warn(msg: string): void;
  minor(msg: string): void;
  info(msg: string): void;
}

MaybePromisepermalink

type MaybePromise<T> = T | Promise<T>;

PrerenderErrorHandlerpermalink

interface PrerenderErrorHandler {
  (details: {
    status: number;
    path: string;
    referrer: string | null;
    referenceType: 'linked' | 'fetched';
  }): void;
}

PrerenderOnErrorValuepermalink

type PrerenderOnErrorValue =
  | 'fail'
  | 'continue'
  | PrerenderErrorHandler;

Prerenderedpermalink

interface Prerendered {
  pages: Map<
    string,
    {
      /** The location of the .html file relative to the output directory */      file: string;
    }
  >;
  assets: Map<
    string,
    {
      /** The MIME type of the asset */      type: string;
    }
  >;
  redirects: Map<
    string,
    {
      status: number;
      location: string;
    }
  >;
  /** An array of prerendered paths (without trailing slashes, regardless of the trailingSlash config) */  paths: string[];
}

RequestOptionspermalink

interface RequestOptions {
  getClientAddress: () => string;
  platform?: App.Platform;
}

ResponseHeaderspermalink

string[] is only for set-cookie, everything else must be type of string

type ResponseHeaders = Record<
  string,
  string | number | string[]
>;

RouteDefinitionpermalink

interface RouteDefinition {
  id: string;
  type: 'page' | 'endpoint';
  pattern: RegExp;
  segments: RouteSegment[];
  methods: HttpMethod[];
}

RouteSegmentpermalink

interface RouteSegment {
  content: string;
  dynamic: boolean;
  rest: boolean;
}

ToJSONpermalink

interface ToJSON {
  toJSON(...args: any[]): Exclude<JSONValue, ToJSON>;
}

TrailingSlashpermalink

type TrailingSlash = 'never' | 'always' | 'ignore';

Apppermalink

It's possible to tell SvelteKit how to type objects inside your app by declaring the App namespace. By default, a new project will have a file called src/app.d.ts containing the following:

/// <reference types="@sveltejs/kit" />

declare namespace App {
  interface Locals {}

  interface Platform {}

  interface Session {}

  interface Stuff {}
}

By populating these interfaces, you will gain type safety when using event.locals, event.platform, session and stuff.

Note that since it's an ambient declaration file, you can't use import statements — instead, use the import(...) function:

interface Locals {
  user: import('$lib/types').User;
}

Localspermalink

The interface that defines event.locals, which can be accessed in hooks (handle, handleError and getSession) and endpoints.

interface Locals {}

Platformpermalink

If your adapter provides platform-specific context via event.platform, you can specify it here.

interface Platform {}

Sessionpermalink

The interface that defines session, both as an argument to load functions and the value of the session store.

interface Session {}

Stuffpermalink

The interface that defines stuff, as input or output to load or as the value of the stuff property of the page store.

interface Stuff {}

Generated typespermalink

The RequestHandler and Load types both accept a Params argument allowing you to type the params object. For example this endpoint expects foo, bar and baz params:

src/routes/[foo]/[bar]/[baz].js
ts
/** @type {import('@sveltejs/kit').RequestHandler<{
* foo: string;
* bar: string;
* baz: string
* }>} */
export async function get({ params }) {
A function whose declared type is neither 'void' nor 'any' must return a value.2355A function whose declared type is neither 'void' nor 'any' must return a value.
// ...
}

Needless to say, this is cumbersome to write out, and less portable (if you were to rename the [foo] directory to [qux], the type would no longer reflect reality).

To solve this problem, SvelteKit generates .d.ts files for each of your endpoints and pages:

.svelte-kit/types/src/routes/[foo]/[bar]/__types/[baz].d.ts
import type { RequestHandler as GenericRequestHandler, Load as GenericLoad } from '@sveltejs/kit';

export type RequestHandler<Body = any> = GenericRequestHandler<
  { foo: string; bar: string; baz: string },
  Body
>;

export type Load<
  InputProps extends Record<string, any> = Record<string, any>,
  OutputProps extends Record<string, any> = InputProps
> = GenericLoad<{ foo: string; bar: string; baz: string }, InputProps, OutputProps>;

These files can be imported into your endpoints and pages as siblings, thanks to the rootDirs option in your TypeScript configuration:

src/routes/[foo]/[bar]/[baz].js
ts
/** @type {import('./__types/[baz]').RequestHandler} */
export async function get({ params }) {
// ...
}
<script context="module">
  /** @type {import('./__types/[baz]').Load} */  export async function load({ params, fetch, session, stuff }) {
    // ...  }
</script>

For this to work, your own tsconfig.json or jsconfig.json should extend from the generated .svelte-kit/tsconfig.json (where .svelte-kit is your outDir):

{ "extends": "./.svelte-kit/tsconfig.json" }

Default tsconfig.jsonpermalink

The generated .svelte-kit/tsconfig.json file contains a mixture of options. Some are generated programmatically based on your project configuration, and should generally not be overridden without good reason:

.svelte-kit/tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "..",
    "paths": {
      "$lib": "src/lib",
      "$lib/*": "src/lib/*"
    },
    "rootDirs": ["..", "./types"]
  },
  "include": ["../src/**/*.js", "../src/**/*.ts", "../src/**/*.svelte"],
  "exclude": ["../node_modules/**", "./**"]
}

Others are required for SvelteKit to work properly, and should also be left untouched unless you know what you're doing:

.svelte-kit/tsconfig.json
{
  "compilerOptions": {
    // this ensures that types are explicitly
    // imported with `import type`, which is
    // necessary as svelte-preprocess cannot
    // otherwise compile components correctly
    "importsNotUsedAsValues": "error",

    // Vite compiles one TypeScript module
    // at a time, rather than compiling
    // the entire module graph
    "isolatedModules": true,

    // TypeScript cannot 'see' when you
    // use an imported value in your
    // markup, so we need this
    "preserveValueImports": true,

    // This ensures both `svelte-kit build`
    // and `svelte-kit package` work correctly
    "lib": ["esnext", "DOM"],
    "moduleResolution": "node",
    "module": "esnext",
    "target": "esnext"
  }
}
previous Configuration
next SEO
We stand with Ukraine. Donate → We stand with Ukraine. Petition your leaders. Show your support.