## 1. Project Overview & Quickstart (unjs/consola)

# 🐨 Consola

> Elegant Console Wrapper

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]



## Why Consola?

👌&nbsp; Easy to use
💅&nbsp; Fancy output with fallback for minimal environments
🔌&nbsp; Pluggable reporters
💻&nbsp; Consistent command line interface (CLI) experience
🏷&nbsp; Tag support
🚏&nbsp; Redirect `console` and `stdout/stderr` to consola and easily restore redirect.
🌐&nbsp; Browser support
⏯&nbsp; Pause/Resume support
👻&nbsp; Mocking support
👮‍♂️&nbsp; Spam prevention by throttling logs
❯&nbsp; Interactive prompt support powered by [`clack`](https://github.com/natemoo-re/clack)

## Installation

Using npm:

```bash
npm i consola
```

Using yarn:

```bash
yarn add consola
```

Using pnpm:

```bash
pnpm i consola
```

## Getting Started

```js
// ESM
import { consola, createConsola } from "consola";

// CommonJS
const { consola, createConsola } = require("consola");

consola.info("Using consola 3.0.0");
consola.start("Building project...");
consola.warn("A new version of consola is available: 3.0.1");
consola.success("Project built!");
consola.error(new Error("This is an example error. Everything is fine!"));
consola.box("I am a simple box");
await consola.prompt("Deploy to the production?", {
  type: "confirm",
});
```

Will display in the terminal:



You can use smaller core builds without fancy reporter to save 80% of the bundle size:

```ts
import { consola, createConsola } from "consola/basic";
import { consola, createConsola } from "consola/browser";
import { createConsola } from "consola/core";
```

## Consola Methods

#### `<type>(logObject)` `<type>(args...)`

Log to all reporters.

Example: `consola.info('Message')`

#### `await prompt(message, { type, cancel })`

Show an input prompt. Type can either of `text`, `confirm`, `select` or `multiselect`.

If prompt is canceled by user (with Ctrol+C), default value will be resolved by default. This strategy can be configured by setting `{ cancel: "..." }` option:

- `"default"` - Resolve the promise with the `default` value or `initial` value.
- `"undefined`" - Resolve the promise with `undefined`.
- `"null"` - Resolve the promise with `null`.
- `"symbol"` - Resolve the promise with a symbol `Symbol.for("cancel")`.
- `"reject"` - Reject the promise with an error.

See [examples/prompt.ts](./examples/prompt.ts) for usage examples.

#### `addReporter(reporter)`

- Aliases: `add`

Register a custom reporter instance.

#### `removeReporter(reporter?)`

- Aliases: `remove`, `clear`

Remove a registered reporter.

If no arguments are passed all reporters will be removed.

#### `setReporters(reporter|reporter[])`

Replace all reporters.

#### `create(options)`

Create a new `Consola` instance and inherit all parent options for defaults.

#### `withDefaults(defaults)`

Create a new `Consola` instance with provided defaults

#### `withTag(tag)`

- Aliases: `withScope`

Create a new `Consola` instance with that tag.

#### `wrapConsole()` `restoreConsole()`

Globally redirect all `console.log`, etc calls to consola handlers.

#### `wrapStd()` `restoreStd()`

Globally redirect all stdout/stderr outputs to consola.

#### `wrapAll()` `restoreAll()`

Wrap both, std and console.

console uses std in the underlying so calling `wrapStd` redirects console too.
Benefit of this function is that things like `console.info` will be correctly redirected to the corresponding type.

#### `pauseLogs()` `resumeLogs()`

- Aliases: `pause`/`resume`

**Globally** pause and resume logs.

Consola will enqueue all logs when paused and then sends them to the reported when resumed.

#### `mockTypes`

- Aliases: `mock`

Mock all types. Useful for using with tests.

The first argument passed to `mockTypes` should be a callback function accepting `(typeName, type)` and returning the mocked value:

```js
// Jest
consola.mockTypes((typeName, type) => jest.fn());
// Vitest
consola.mockTypes((typeName, type) => vi.fn());
```

Please note that with the example above, everything is mocked independently for each type. If you need one mocked fn create it outside:

```js
// Jest
const fn = jest.fn();
// Vitest
const fn = vi.fn();
consola.mockTypes(() => fn);
```

If callback function returns a _falsy_ value, that type won't be mocked.

For example if you just need to mock `consola.fatal`:

```js
// Jest
consola.mockTypes((typeName) => typeName === "fatal" && jest.fn());
// Vitest
consola.mockTypes((typeName) => typeName === "fatal" && vi.fn());
```

**NOTE:** Any instance of consola that inherits the mocked instance, will apply provided callback again.
This way, mocking works for `withTag` scoped loggers without need to extra efforts.

## Custom Reporters

Consola ships with 3 built-in reporters out of the box. A fancy colored reporter by default and fallsback to a basic reporter if running in a testing or CI environment detected using [unjs/std-env](https://github.com/unjs/std-env) and a basic browser reporter.

You can create a new reporter object that implements `{ log(logObject): () => { } }` interface.

**Example:** Simple JSON reporter

```ts
import { createConsola } from "consola";

const consola = createConsola({
  reporters: [
    {
      log: (logObj) => {
        console.log(JSON.stringify(logObj));
      },
    },
  ],
});

// Prints {"date":"2023-04-18T12:43:38.693Z","args":["foo bar"],"type":"log","level":2,"tag":""}
consola.log("foo bar");
```

**Example:** Exit on fatal errors

```ts
import { consola } from 'consola';

consola.addReporter({
  log(logObj) {
    if(logObj.type === 'fatal') {
      process.exit(1)
    }
  }
})

// Will exit on this line.
consola.fatal("fatal error");
```

## Log Level

Consola only shows logs with configured log level or below. (Default is `3`)

Available log levels:

- `0`: Fatal and Error
- `1`: Warnings
- `2`: Normal logs
- `3`: Informational logs, success, fail, ready, start, ...
- `4`: Debug logs
- `5`: Trace logs
- `-999`: Silent
- `+999`: Verbose logs

You can set the log level by either:

- Passing `level` option to `createConsola`
- Setting `consola.level` on instance
- Using the `CONSOLA_LEVEL` environment variable (not supported for browser and core builds).

## Log Types

Log types are exposed as `consola.[type](...)` and each is a preset of styles and log level.

A list of all available built-in types is [available here](./src/constants.ts).

## Creating a new instance

Consola has a global instance and is recommended to use everywhere.
In case more control is needed, create a new instance.

```js
import { createConsola } from "consola";

const logger = createConsola({
  // level: 4,
  // fancy: true | false
  // formatOptions: {
  //     columns: 80,
  //     colors: false,
  //     compact: false,
  //     date: false,
  // },
});
```

## Integrations

### With jest or vitest

```js
describe("your-consola-mock-test", () => {
  beforeAll(() => {
    // Redirect std and console to consola too
    // Calling this once is sufficient
    consola.wrapAll();
  });

  beforeEach(() => {
    // Re-mock consola before each test call to remove
    // calls from before
    // Jest
    consola.mockTypes(() => jest.fn());
    // Vitest
    consola.mockTypes(() => vi.fn());
  });

  test("your test", async () => {
    // Some code here

    // Let's retrieve all messages of `consola.log`
    // Get the mock and map all calls to their first argument
    const consolaMessages = consola.log.mock.calls.map((c) => c[0]);
    expect(consolaMessages).toContain("your message");
  });
});
```

### With jsdom

```js
{
  new jsdom.VirtualConsole().sendTo(consola);
}
```

## Console Utils

```ts
// ESM
import {
  stripAnsi,
  centerAlign,
  rightAlign,
  leftAlign,
  align,
  box,
  colors,
  getColor,
  colorize,
} from "consola/utils";

// CommonJS
const { stripAnsi } = require("consola/utils");
```

## Raw logging methods

Objects sent to the reporter could lead to unexpected output when object is close to internal object structure containing either `message` or `args` props. To enforce the object to be interpreted as pure object, you can use the `raw` method chained to any log type.

**Example:**

```js
// Prints "hello"
consola.log({ message: "hello" });

// Prints "{ message: 'hello' }"
consola.log.raw({ message: "hello" });
```

## License

MIT



[npm-version-src]: https://img.shields.io/npm/v/consola?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/consola
[npm-downloads-src]: https://img.shields.io/npm/dm/consola?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/consola
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/consola/main?style=flat&colorA=18181B&colorB=F0DB4F
[codecov-href]: https://codecov.io/gh/unjs/consola
[bundle-src]: https://img.shields.io/bundlephobia/min/consola?style=flat&colorA=18181B&colorB=F0DB4F
[bundle-href]: https://bundlephobia.com/result?p=consola

## 2. Official Technical Reference & Guides (unjs/docs)

## File: README.md

# UnDocs

Minimal documentation theme and CLI for shared usage across UnJS/H3/Nitro projects.

Write your docs as Markdown, drop in a single config file, and get a fast,
elegant, zero-config documentation site — dev server, production build, search,
and `llms.txt` included.

## Quick Start

A docs project is three files. Create them in a `docs/` folder:

**1. `docs/package.json`** — pulls in the CLI and wires up two scripts:

```json
{
  "name": "docs",
  "private": true,
  "scripts": {
    "dev": "undocs dev",
    "build": "undocs build"
  },
  "devDependencies": {
    "undocs": "latest"
  }
}
```

**2. `docs/.config/docs.yaml`** — your site config:

```yaml
# yaml-language-server: $schema=https://unpkg.com/undocs/schema/config.json
name: "packageName"
shortDescription: "One-line summary."
github: "unjs/packageName"
```

**3. `docs/1.guide/1.index.md`** — your first page:

```md
# Getting Started

Welcome to the docs!
```

Then install and start the dev server on [localhost:3000](http://localhost:3000):

```sh
cd docs
npm install
npm run dev
```

Build a static production bundle with `npm run build`.

### Adding pages

Every Markdown file becomes a page. Numeric prefixes (`1.`, `2.`) control the
order in the sidebar and are stripped from the URL, so `1.guide/1.index.md`
is served at `/guide`. Add folders and files to grow the navigation — no routing
setup required:

```
docs/
├─ .config/
│  └─ docs.yaml
├─ 1.guide/
│  ├─ 1.index.md       → /guide
│  └─ 2.usage.md       → /guide/usage
└─ 2.config/
   └─ 1.index.md       → /config
```

See the [configuration reference](https://undocs.pages.dev/config) for the full
list of options (landing page, banner, socials, sponsors, `llms.txt`, and more).

## Stack

Undocs is currently powered by [Nitro](https://nitro.build), [Vite](https://vite.dev), [md4x](https://github.com/unjs/md4x), [rangi](https://github.com/pi0/rangi), [Unhead](http://unhead.unjs.io/) and [Reka UI](https://reka-ui.com/).

> UnDocs was originally based on [Nuxt](https://nuxt.com/), [Nuxt UI](https://ui.nuxt.com/), [Nuxt Content](https://content.nuxt.com/) ([Comark](https://comark.dev/)), [Vue Router](https://router.vuejs.org/), and other Nuxt ecosystem modules such as [nuxt-llms](https://github.com/nuxt-content/nuxt-llms) and [nuxt-icon](https://github.com/nuxt/icon) which inspired the new generation of undocs.

## License

Published under the [MIT](https://github.com/unjs/undocs/blob/main/LICENSE) license.

---

## File: docs/blog/1.initial-release.md

---
category: release
date: 2000-01-01
---

# Initial release

> Undocs is out!

[release notes and other content]

---

## File: docs/blog/2.second-release.md

---
category: release
date: 2001-01-01
---

# Second release

> Undocs is out with improvements!

[release notes and other content]

---

## File: docs/blog/3.new-blog.md

---
category: release
date: 2025-06-01
authors:
  - name: Pooya Parsa
    github: pi0
---

# New blog section

> Undocs now allows easily creating a blog section!

## Section

[release notes and other content]

## Section

[another section]

---

## File: docs/2.config/1.index.md

# Configuration

> Learn how to configure the documentation site made with UnDocs.

## Example

```yaml
# 


# yaml-language-server: $schema=https://unpkg.com/undocs/schema/config.json

name: "packageName"
shortDescription: ""
github: "unjs/packageName"
# url: 'https://packageName.unjs.io'
# llms:
#   # Generate `/llms.txt` and `/llms-full.txt`
#   domain: 'https://packageName.unjs.io'
#   title: 'packageName'
#   full:
#     title: 'packageName'
# redirects:
#   "/from": "/to"
# automd: true
landing:
  heroLinks:
    stackblitz:
      icon: "i-lucide-play"
      to: "https://stackblitz.com/github/unjs/packageName/tree/main/playground"
  # contributors: true
  # features:
  #   - title:
  #     description:


```

## Cross-origin isolation

Pages that use `SharedArrayBuffer` or wasm threads — an embedded SQLite build, an
FFmpeg demo, a Rust playground, anything reaching for `Atomics.wait` — only get
those APIs on a [cross-origin isolated](https://developer.mozilla.org/en-US/docs/Web/API/Window/crossOriginIsolated)
page. Isolation is opt-in, and off by default:

```yaml
crossOriginIsolation: true
```

With it on, every response serves:

```
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: credentialless
```

Both headers are required — COOP alone does not isolate. They are applied through
Nitro route rules, so `undocs dev` and the built output behave identically.

`credentialless` (what `true` means) sends cross-origin no-cors subresource
requests **without credentials**, so third-party images, fonts and scripts keep
loading whether or not the servers hosting them opt in.

`require-corp` is the stricter alternative, and only safe once every cross-origin
asset the docs load sends `Cross-Origin-Resource-Policy` (or is fetched with
CORS) — anything that does not is blocked outright:

```yaml
crossOriginIsolation: require-corp
```

::note
Under either value, a **cross-origin iframe** must send its own
`Cross-Origin-Embedder-Policy` to load at all. Check any embedded playground,
video or third-party widget after turning isolation on — that is a property of
isolation itself, not of the value you pick.
::

## Reference



### `$schema`

- **Type**: `string`

### `automd`

- **Type**: `boolean`

Enable integration with https://automd.unjs.io

### `banner`

Banner configuration

#### `actions`

- **Type**: `array`

Display a list of action buttons next to the title.

#### `close`

- **Type**: `undefined`

#### `closeIcon`

- **Type**: `string`
- **Default**: `"i-lucide-x"`

The icon displayed in the close button (e.g., 'i-lucide-x').

#### `color`

- **Type**: `string`
- **Default**: `"primary"`

Banner color theme.

#### `icon`

- **Type**: `string`

The icon displayed next to the title (e.g., 'i-lucide-info').

#### `id`

- **Type**: `string`

A unique id saved to local storage to remember if the banner has been dismissed. Change this value to show the banner again.

#### `target`

- **Type**: `string`

Link target attribute.

#### `title`

- **Type**: `string`

The banner title text.

#### `to`

- **Type**: `string`

Link destination URL or route path.

#### `ui`

UI customization classes for banner components.

##### `actions`

- **Type**: `undefined`

Actions container classes

##### `center`

- **Type**: `undefined`

Center section classes

##### `close`

- **Type**: `undefined`

Close button classes

##### `container`

- **Type**: `undefined`

Container element classes

##### `icon`

- **Type**: `undefined`

Icon element classes

##### `left`

- **Type**: `undefined`

Left section classes

##### `right`

- **Type**: `undefined`

Right section classes

##### `root`

- **Type**: `undefined`

Root element classes

##### `title`

- **Type**: `undefined`

Title element classes

### `branch`

- **Type**: `string`

The branch of the GitHub repository for the documentation site.

### `buildCache`

- **Type**: `boolean`

Enable build cache (experimental)

### `description`

- **Type**: `string`

The description of the documentation site.

### `dir`

- **Type**: `string`

Documentation directory

Note: This option will be automatically set

### `github`

- **Type**: `string`

The GitHub repository for the documentation site.

### `landing`

- **Type**: `undefined`

### `lang`

- **Type**: `string`
- **Default**: `"en"`

The language of the documentation site.

### `llms`

Configuration for `llms.txt` generation (`/llms.txt` and `/llms-full.txt`).

#### `description`

- **Type**: `string`

Description used in `/llms.txt`.

#### `domain`

- **Type**: `string`

Public site domain (e.g. https://example.com).

#### `full`

Metadata for `/llms-full.txt`.

##### `description`

- **Type**: `string`

Description used in `/llms-full.txt`.

##### `title`

- **Type**: `string`

Title used in `/llms-full.txt`.

#### `title`

- **Type**: `string`

Title used in `/llms.txt`.

### `name`

- **Type**: `string`

The name of the documentation site.

### `redirects`

Redirects for the documentation site.

### `shortDescription`

- **Type**: `string`

The description of the documentation site.

### `socials`

Social media links for the documentation site.

### `sponsors`

#### `api`

- **Type**: `string`

The URL to the sponsors JSON API.

### `themeColor`

- **Type**: `string`

The accent color of the documentation site. Defaults to `mono`.

Accepts `mono` (no accent — links and active navigation read in body color, the monochrome default), a Geist hue (`blue`, `red`, `amber`, `green`, `teal`, `purple`, `pink`), a Tailwind palette name that maps onto the nearest Geist hue (`violet` -> purple, `cyan` -> teal, `rose` -> red, ...), a neutral name (`gray`, `slate`, `zinc`, `neutral`, `stone`) as a synonym for `mono`, or any CSS color.

It tints links, active navigation, icons, and the landing glow, and is used for the `theme-color` meta tag. Buttons and other solid fills stay monochrome, as they are in Geist.

### `url`

- **Type**: `string`

The URL of the documentation site.

### `versions`

- **Type**: `array`

The versions of the documentation site.

---

## File: docs/1.guide/1.index.md

# Getting Started

> Write your docs as Markdown, drop in a single config file, and get a fast,
> elegant, zero-config documentation site — dev server, production build, search,
> and `llms.txt` included.

## Overview

UnJS Docs is a minimal Documentation Theme and CLI for shared usage across UnJS projects.

### Stack

Undocs is currently powered by [Nitro](https://nitro.build), [Vite](https://vite.dev), [md4x](https://github.com/unjs/md4x), [rangi](https://github.com/pi0/rangi) and [Unhead](http://unhead.unjs.io/). Its UI primitives are its own, derived from the MIT-licensed [Reka UI](https://reka-ui.com/).

> UnDocs was originally based on [Nuxt](https://nuxt.com/), [Nuxt UI](https://ui.nuxt.com/), [Nuxt Content](https://content.nuxt.com/) ([Comark](https://comark.dev/)), [Vue Router](https://router.vuejs.org/), and other Nuxt ecosystem modules such as [nuxt-llms](https://github.com/nuxt-content/nuxt-llms) and [nuxt-icon](https://github.com/nuxt/icon) which inspired the new generation of undocs.

## Quick Start

Create `docs/` project with starter template:

:pm-x{command="giget gh:unjs/undocs/template docs --install"}

Go to the docs dir `cd docs/`

Start development server:

:pm-run{script="dev"}

Build for production:

:pm-run{script="build"}

---

## File: docs/1.guide/2.components.md

---
icon: i-lucide-puzzle
---

# Components

> Discover the components you can use in your markdown files.

## Alerts


::tabs
  ::div
  ---
  label: Preview
  icon: i-lucide-search
  ---
  ::note
  Highlights information that users should take into account, even when skimming.
  ::
  ::tip
  Optional information to help a user be more successful.
  ::
  ::important
  Crucial information necessary for users to succeed.
  ::
  ::warning{to="/"}
  Critical content demanding immediate user attention due to potential risks.
  ::
  ::caution{to="/"}
  Negative potential consequences of an action.
  ::
  ::
  ::div
  ---
  label: Code
  icon: i-lucide-square-code
  ---
  ```mdc
  ::note
  Highlights information that users should take into account, even when skimming.
  ::
  ::tip
  Optional information to help a user be more successful.
  ::
  ::important
  Crucial information necessary for users to succeed.
  ::
  ::warning{to="/"}
  Critical content demanding immediate user attention due to potential risks.
  ::
  ::caution{to="/"}
  Negative potential consequences of an action.
  ::
  ```
  ::
::


## Package Manager

Components to generate cross package manager comments


::tabs
  ::div
  ---
  label: Preview
  icon: i-lucide-search
  ---
  :pm-install{name="defu"}

  :pm-run{script="dev"}

  :pm-x{command="giget unjs new-lib"}

  ::
  ::div
  ---
  label: Code
  icon: i-lucide-square-code
  ---
  ```mdc
  :pm-install{name="defu"}

  :pm-run{script="dev"}

  :pm-x{command="giget unjs new-lib"}
  ```
  ::
::


## Read More

The component is used to create a link to another page.


::tabs
  ::div
  ---
  label: Preview
  icon: i-lucide-search
  ---
  :read-more{to="/guide"}
  :read-more{to="https://unjs.io" title="UnJS Website"}
  ::
  ::div
  ---
  label: Code
  icon: i-lucide-square-code
  ---
  ```mdc
  :read-more{to="/guide"}
  :read-more{to="https://unjs.io" title="UnJS Website"}
  ```
  ::
::


## Cards

Group related links or highlights into cards. A `::card` can be standalone or wrapped in a `::card-group` grid. Add a `to` to make the whole card a link.


::tabs
  ::div
  ---
  label: Preview
  icon: i-lucide-search
  ---
  ::card-group{cols="2"}
    ::card
    ---
    title: Getting Started
    icon: i-lucide-rocket
    to: /guide
    ---
    Install undocs and scaffold your first docs site.
    ::
    ::card
    ---
    title: Components
    icon: i-lucide-puzzle
    to: /guide/components
    ---
    Alerts, tabs, cards and more, straight from markdown.
    ::
  ::
  ::
  ::div
  ---
  label: Code
  icon: i-lucide-square-code
  ---
  ```mdc
  ::card-group{cols="2"}
    ::card
    ---
    title: Getting Started
    icon: i-lucide-rocket
    to: /guide
    ---
    Install undocs and scaffold your first docs site.
    ::
    ::card
    ---
    title: Components
    icon: i-lucide-puzzle
    to: /guide/components
    ---
    Alerts, tabs, cards and more, straight from markdown.
    ::
  ::
  ```
  ::
::


## Tabs

Group alternative content into tabs. Each direct child becomes a tab — set its `label` (or `title`) and an optional `icon`. Children can be `::tab` blocks or `::div` blocks carrying those props.

::tabs
::tab{label="npm" icon="i-lucide-package"}
Content shown under the **npm** tab.
::
::tab{label="pnpm" icon="i-lucide-package"}
Content shown under the **pnpm** tab.
::
::

```mdc
::tabs
  ::tab{label="npm" icon="i-lucide-package"}
  Content shown under the **npm** tab.
  ::
  ::tab{label="pnpm" icon="i-lucide-package"}
  Content shown under the **pnpm** tab.
  ::
::
```

## Steps

Render a vertical, numbered steps list. Each heading inside `::steps` becomes a numbered step; the content beneath it belongs to that step. Numbering and the guide line are produced with CSS, so any headings work.

::steps

#### Install the package

:pm-install{name="undocs"}

#### Run the dev server

:pm-run{script="dev"}

#### Ship your docs 🚀

::

```mdc
::steps
#### Install the package

:pm-install{name="undocs"}

#### Run the dev server

:pm-run{script="dev"}

#### Ship your docs 🚀
::
```

> [!TIP]
> Steps are also generated automatically from standard numbered lists — see [Content Transform](/guide/content-transformation#steps).

## Code Group

Group multiple code blocks into a single tabbed switcher. Each block's filename (in `[brackets]`) becomes its tab label, with a language icon inferred automatically.

::code-group

```json [package.json]
{
  "scripts": {
    "dev": "undocs dev"
  }
}
```

```ts [server/api/hello.get.ts]
export default defineEventHandler(() => {
  return { hello: "world" };
});
```

::

````mdc
::code-group
```json [package.json]
{
  "scripts": {
    "dev": "undocs dev"
  }
}
```

```ts [server/api/hello.get.ts]
export default defineEventHandler(() => {
  return { hello: "world" };
});
```
::
````

> [!NOTE]
> Consecutive code blocks are grouped automatically — see [Content Transform](/guide/content-transformation#auto-code-groups). Use `::code-group` when you need to group blocks that are not adjacent.

## Code Tree

Display a set of files in a VS Code–style explorer: a folder/file tree on the left, the selected file's highlighted code on the right. Filenames containing `/` (e.g. `[server/routes/index.ts]`) nest into folders. Use `defaultValue` to pick the initially selected file and `expandAll` to expand every folder.

::code-tree{defaultValue="src/app.ts" expandAll}

```ts [package.json]
{
  "name": "my-app"
}
```

```ts [src/app.ts]
export const app = createApp();
```

```ts [src/routes/index.ts]
export default defineRoute(() => "Hello");
```

::

````mdc
::code-tree{defaultValue="src/app.ts" expandAll}
```ts [package.json]
{
  "name": "my-app"
}
```

```ts [src/app.ts]
export const app = createApp();
```

```ts [src/routes/index.ts]
export default defineRoute(() => "Hello");
```
::
````

## Mermaid Graphs

````
  ```mermaid
  graph TD
  A[Getting Started] --> B[Components]
  A --> C[Content Transform]
  A --> D[Prose]

      click A "/guide"
      click B "/guide/components"
      click C "/guide/content-transformation"
      click D "/guide/prose"
  ```
````

```mermaid
%%{init: {'theme':'neutral'}}%%
graph TD
    A[Getting Started] --> B[Components]
    A --> C[Content Transform]
    A --> D[Prose]

    click A "/guide"
    click B "/guide/components"
    click C "/guide/content-transformation"
    click D "/guide/prose"
```

## Prose Components

Undocs ships its own set of Prose components that render standard markdown — headings, links, tables, code blocks, and more — with sensible typography defaults. Just write markdown and they are applied automatically.

:read-more{to="/guide/prose" title="Prose rendering"}

---

## File: docs/1.guide/3.content-transformation.md

---
icon: material-symbols:markdown-outline
---

# Content Transform

> Discover ways that undocs transforms content to make it more easier to just write documentation.

## Github Notes

https://github.com/orgs/community/discussions/16925

```md
> [!NOTE]
> Highlights information that users should take into account, even when skimming.
```

> [!NOTE]
> Highlights information that users should take into account, even when skimming.

```md
> [!TIP]
> Optional information to help a user be more successful.
```

> [!TIP]
> Optional information to help a user be more successful.

```md
> [!IMPORTANT]
> Crucial information necessary for users to succeed.
```

> [!IMPORTANT]
> Crucial information necessary for users to succeed.

```md
> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.
```

> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.

```md
> [!CAUTION]
> Negative potential consequences of an action.
```

> [!CAUTION]
> Negative potential consequences of an action.

## Auto Code Groups

If you have code blocks right after each other, they will be grouped together using a `code-group` component.

````md
```json [package.json]
{
  "scripts": {
    "dev": "undocs dev"
  }
}
```

```ts [server/api/hello.get.ts]
export default defineEventHandler(() => {
  return {
    hello: "world",
  };
});
```

```html [index.html]
<template>
  
    <h1>Welcome to the homepage</h1>
  
</template>
```
````

```json [package.json]
{
  "scripts": {
    "dev": "undocs dev"
  }
}
```

```ts [server/api/hello.get.ts]
export default defineEventHandler(() => {
  return {
    hello: "world",
  };
});
```

```html [index.html]
<template>
  
    <h1>Welcome to the homepage</h1>
  
</template>
```

## Steps

Generate steps by using standard markdown numbered lists!

> [!IMPORTANT]
> In order to generate this component, you need to have content inside at least one of the lists. The list can't be a child of another component & also any content within a Markdown list will need at least 2 tabs to be considered as a child of the list.

```md
1. Install Package

   ::note
   Please note that steps only work with numbered lists and is not within children.
   ::

   :pm-install{name="undocs"}

2. Run development server

   :pm-run{script="undocs"}

3. Done ✅
```

1. Install Package

   ::note
   Please note that steps only work with numbered lists and is not within children.
   ::

   :pm-install{name="undocs"}

2. Run development server

   :pm-run{script="undocs"}

3. Done ✅

## Config References

Generate beautiful references for your configuration files by just using markdown!

> [!TIP]
> If you use [automd:jsdocs](https://automd.unjs.io/generators/jsdocs), you can reference the schema file directly! Check out this example from the [config](/config) page.

```md
### `$schema`

- **Type**: `string`

### `automd`

- **Type**: `boolean`

Enable integration with https://automd.unjs.io

### `buildCache`

- **Type**: `boolean`

Enable build cache (experimental)

### `description`

- **Type**: `string`

The description of the documentation site.
```

### `$schema`

- **Type**: `string`

### `automd`

- **Type**: `boolean`

Enable integration with https://automd.unjs.io

### `buildCache`

- **Type**: `boolean`

Enable build cache (experimental)

### `description`

- **Type**: `string`

The description of the documentation site.

> [!TIP]
> Do you have an idea for a new content transformation, feel free to [open an issue](https://github.com/unjs/undocs/issues/new?assignees=&labels=pending+triage&projects=&template=feature-request.yml)!

---

## File: docs/1.guide/4.prose.md

---
icon: material-symbols:text-fields
---

# Prose

> Undocs renders standard Markdown through its own set of Prose components with sensible typography defaults — just write Markdown and it looks great.

## Headings

Use `#` through `######` for headings. Each renders with consistent spacing and an anchor link on hover.

```md
# Heading 1

## Heading 2

### Heading 3

#### Heading 4
```

## Text

Emphasize inline content with **bold**, _italic_, ~~strikethrough~~, and `inline code`. Combine them for **_strong emphasis_** where needed.

```md
**bold**, _italic_, ~~strikethrough~~, and `inline code`.
```

## Links

Internal and external [links](https://unjs.io) are styled consistently. External links open in a new tab automatically.

```md
Internal and external [links](https://unjs.io) are styled consistently.
```

## Blockquotes

> A blockquote is rendered with a subtle left border and muted text — handy for callouts and citations.

```md
> A blockquote is rendered with a subtle left border and muted text.
```

## Lists

Unordered, ordered, and task lists all render cleanly:

- First item
- Second item
  - Nested item
- Third item

1. Install the package
2. Run the dev server
3. Ship your docs

- [x] Write the Markdown
- [ ] Review the rendering
- [ ] Deploy

```md
- First item
- Second item
  - Nested item

1. Install the package
2. Run the dev server

- [x] Write the Markdown
- [ ] Review the rendering
```

## Tables

| Feature     | Supported | Notes                      |
| ----------- | :-------: | -------------------------- |
| Headings    |    ✅     | Anchor links on hover      |
| Tables      |    ✅     | Column alignment respected |
| Code blocks |    ✅     | Syntax highlighted         |
| Task lists  |    ✅     | Rendered as checkboxes     |

```md
| Feature | Supported | Notes                 |
| ------- | :-------: | --------------------- |
| Tables  |    ✅     | Column alignment kept |
```

## Code

Inline `code` and fenced code blocks are highlighted with [rangi](https://github.com/pi0/rangi):

```ts [example.ts]
export function greet(name: string): string {
  return `Hello, ${name}!`;
}
```

## Images

Images are responsive and constrained to the content width:

```md

```

## Horizontal Rule

Separate sections with a thematic break:

---

That's a `---` rendered as a horizontal rule.