Skip to content
On this page

Routes

File-based routing

In your routes folder (can be changed in the configuration), you can create new files to map to specific routes. Route files are formatted as follows:

  • index.get.ts maps to GET /
  • user.get.ts maps to GET /user
  • user/index.get.ts also maps to GET /user
  • hello/[name].get.ts maps to GET /hello/[name]
  • index.post.ts maps to POST /

etc.

Route handling

To create a route, default export a route handler by calling route.handle.

To send a response, use the Response class.

ts
import { Response, route, Status } from "svarta";

export default route.handle(async () => {
  return new Response(Status.Ok, "Hello world!");
});
import { Response, route, Status } from "svarta";

export default route.handle(async () => {
  return new Response(Status.Ok, "Hello world!");
});

route is the default route entry point and can be extended using middlewares

Input validation

To validate the request body, use route.input.

ts
export default route
  .input(zod.object({ name: zod.string() }).strict())
  .handle(async ({ input }) => {
    return new Response(Status.Ok, {
      // input is type-safe
      message: `Hello ${input.name}`,
    });
  });
export default route
  .input(zod.object({ name: zod.string() }).strict())
  .handle(async ({ input }) => {
    return new Response(Status.Ok, {
      // input is type-safe
      message: `Hello ${input.name}`,
    });
  });

Route parameters

Consider this route, which should greet the user using the name given in the route path.

WARNING

This will not build, as params are unknown by default.

ts
import { Response, route, Status } from "svarta";

export default route.handle(async ({ params }) => {
  const { name } = params; // Error: 'params' is of type 'unknown'

  return new Response(Status.Ok, {
    message: `Hello ${name}!`,
  });
});
import { Response, route, Status } from "svarta";

export default route.handle(async ({ params }) => {
  const { name } = params; // Error: 'params' is of type 'unknown'

  return new Response(Status.Ok, {
    message: `Hello ${name}!`,
  });
});

INFO

To statically validate parameters, export a params array and add it to the handler.

ts
import { Response, route, Status } from "svarta";

export const params = ["name"] as const; 

export default route
  .params(params) // <- register params 
  .handle(async ({ params }) => {
    const { name } = params; // OK!

    return new Response(Status.Ok, {
      message: `Hello ${name}!`,
    });
  });
import { Response, route, Status } from "svarta";

export const params = ["name"] as const; 

export default route
  .params(params) // <- register params 
  .handle(async ({ params }) => {
    const { name } = params; // OK!

    return new Response(Status.Ok, {
      message: `Hello ${name}!`,
    });
  });

Now consider adding additional parameters that are not present in the actual route filename:

WARNING

The params will be checked while building to validate the parameters are actually valid. If not, the build will fail.

ts
import { Response, route, Status } from "svarta";

// another_param is defined, but not defined in the route filename.
// This will show a warning while developing
// and will fatally error during build
export const params = ["name", "another_param"] as const;

export default route
  .params(params)
  .handle(async ({ params }) => {
    const { name } = params;

    return new Response(Status.Ok, {
      message: `Hello ${name}!`,
    });
  });
import { Response, route, Status } from "svarta";

// another_param is defined, but not defined in the route filename.
// This will show a warning while developing
// and will fatally error during build
export const params = ["name", "another_param"] as const;

export default route
  .params(params)
  .handle(async ({ params }) => {
    const { name } = params;

    return new Response(Status.Ok, {
      message: `Hello ${name}!`,
    });
  });

Redirects

Redirect is a helper class that wraps the standard Response class for easier redirect handling.

ts
import { Redirect, route } from "svarta";

export default route.handle(async () => {
  return new Redirect("https://google.com", { permanent: true });
});
import { Redirect, route } from "svarta";

export default route.handle(async () => {
  return new Redirect("https://google.com", { permanent: true });
});

Output validation

To validate the response body, use route.output.

ts
export default route
  .output(zod.object({ message: zod.string() }).strict())
  .handle(async () => {
    return new Response(Status.Ok, {
      // output is type-safe, this will show an error and return 500 in production
      msg: "Hello",
    });
  });
export default route
  .output(zod.object({ message: zod.string() }).strict())
  .handle(async () => {
    return new Response(Status.Ok, {
      // output is type-safe, this will show an error and return 500 in production
      msg: "Hello",
    });
  });