# Configuration

Configure directories, SSR, metadata, aliases, modules, and Vite options for your application.

`runable.config.ts` defines the application structure, rendering mode, and extensions loaded at startup.

## Minimal configuration

Place this file at the project root:

```ts
// runable.config.ts
import { defineConfig } from "runable";

export default defineConfig({});
```

`defineConfig()` preserves the object while providing TypeScript types and autocomplete.

## Default values

Without additional options, Runable uses this structure:

| Option | Type | Default | Purpose |
| --- | --- | --- | --- |
| `appDir` | `string` | `app` | Root of Vue sources |
| `output` | `string` | `.app` | Files generated for development and typing |
| `distdir` | `string` | `.output` | Production build |
| `publicDir` | `string \| false` | `public` | Assets served as-is |
| `ssr` | `boolean` | `true` | Enables server rendering |
| `pages` | `string \| array` | `app/pages` | Page files |
| `layouts` | `string \| array` | `app/layouts` | Available layouts |
| `components` | `string \| array` | `app/components` | Auto-registered components |
| `composables` | `string \| array` | `app/composables` | Auto-imported composables |
| `globals` | `string \| array` | `app/globals` | Auto-imported global functions |
| `middlewares` | `string \| array` | `app/middlewares` | Navigation middleware |
| `plugins` | `string \| array` | `app/plugins` | Application plugins |
| `css` | `string \| array` | `[]` | Global stylesheets |
| `modules` | `string[]` | `[]` | Loaded Runable modules |

The full option set, with its exact TypeScript shape, is the `RunableConfig` interface in `packages/runable/src/config/types.ts`.

Relative paths are resolved from the directory containing the configuration.

## Define main directories

```ts
// runable.config.ts
import { defineConfig } from "runable";

export default defineConfig({
  appDir: "frontend",
  output: ".runable",
  distdir: "dist",
  publicDir: "static",
});
```

Use `publicDir: false` when your backend or a CDN handles all static assets.

## Enable or disable SSR

```ts
export default defineConfig({
  ssr: false,
});
```

With `ssr: false`, Runable returns the HTML document without rendering the Vue tree on the server. The client then creates the application in the browser.

| Mode | Choose it for |
| --- | --- |
| `ssr: true` | SEO, a rendered first display, and preloaded data |
| `ssr: false` | Internal SPAs or interfaces that depend entirely on the browser |

## Configure HTML metadata

```ts
export default defineConfig({
  siteUrl: "https://example.com",
  head: {
    title: "My application",
    meta: [
      {
        name: "description",
        content: "A Vue application rendered with Runable.",
      },
    ],
    link: [{ rel: "icon", href: "/favicon.svg" }],
  },
});
```

`siteUrl` supplies the origin used to produce some absolute URLs. `head` is passed to Unhead when the application is created.

## Add global styles

```ts
export default defineConfig({
  css: ["./app/css/reset.css", "./app/css/main.css"],
});
```

The `css` array accepts files Vite can process. Install the matching preprocessor when using Sass, Less, or Stylus.

## Define aliases

```ts
import { join } from "node:path";

export default defineConfig({
  alias: {
    "@": join(import.meta.dirname, "app"),
    "@shared": join(import.meta.dirname, "shared"),
  },
});
```

Runable also adds the internal `#build` alias, which points to the generated directory defined by `output`.

## Extend scanned directories

Replace conventional locations with your own paths:

```ts
export default defineConfig({
  pages: ["./frontend/views"],
  layouts: ["./frontend/shells"],
  composables: ["./frontend/composables", "./shared/composables"],
  globals: ["./frontend/globals"],
  middlewares: ["./frontend/middlewares"],
  plugins: ["./frontend/plugins"],
});
```

::u-tip
---
variant: info
title: Replacing defaults
---

When you provide a directory option, treat it as the new source to scan. Explicitly include the conventional directory if you want to keep it in the list.

::

## Configure components

An object entry controls the generated name:

```ts
export default defineConfig({
  components: [
    "./app/components",
    {
      dirs: "./app/components/ui",
      prefix: "Ui",
      pathPrefix: false,
    },
  ],
});
```

`app/components/ui/Button.vue` can therefore be exposed under a prefixed name according to the directory options.

## Load modules

```ts
export default defineConfig({
  modules: ["@acme/runable-auth", "./modules/content"],

  auth: {
    redirectTo: "/login",
  },
});
```

A module can add its own pages, components, layouts, plugins, or Vite options. Module-specific options live under the key declared by that module.

## Extend Vite

```ts
import inspect from "vite-plugin-inspect";

export default defineConfig({
  vite: {
    plugins: [inspect()],
    define: {
      __BUILD_TARGET__: JSON.stringify("web"),
    },
  },
});
```

Runable merges this with its internal Vite configuration. Fields that define framework behavior, including `root`, `appType`, `ssr`, and `server.middlewareMode`, remain under Runable's control.

## Complete example

```ts
import { join } from "node:path";
import { defineConfig } from "runable";

export default defineConfig({
  appDir: "app",
  output: ".app",
  distdir: ".output",
  publicDir: "public",

  ssr: true,
  siteUrl: "https://example.com",

  head: {
    title: "My application",
    meta: [{ name: "description", content: "My Runable application" }],
  },

  css: ["./app/css/main.css"],
  modules: [],

  alias: {
    "@": join(import.meta.dirname, "app"),
  },
});
```

::u-tip
---
variant: info
title: Next step
---

Learn how these options become an application in <a href="/docs/getting-started/concepts.md">Concepts</a>.

::
