> AI coding agents: see [/llms.txt](/llms.txt) for the full documentation index. Markdown version: [/docs/manual/en/concepts/nuxt.md](/docs/manual/en/concepts/nuxt.md).

---
title: Nuxt
description: Build interactive and reusable elements with Nuxt components
navigation:
  icon: i-simple-icons-nuxt
---

## TockDocs is a Nuxt app

TockDocs is distributed as a **Nuxt layer**. When you scaffold a project, you get a normal Nuxt application that extends the layer and can use the standard Nuxt ecosystem.

A starter app typically includes:

```bash
my-docs/
├── content/
├── nuxt.config.ts
├── package.json
└── public/
```

From there, you can add any normal Nuxt directories such as `app/`, `server/`, `plugins/`, or `modules/`.

## Nuxt modules

You can install and configure Nuxt modules exactly as you would in any other Nuxt project.

Example: add Vercel Analytics.

::steps
### Install the module

```bash [Terminal]
npm install @vercel/analytics
```

### Enable it in `nuxt.config.ts`

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  extends: ['tockdocs'],
  modules: ['@vercel/analytics/nuxt/module'],
})
```
::

## Custom Vue components in docs

You can use Markdown + MDC for most docs UI, but you can also create your own Vue components and use them inside content.

Example component:

::tabs
  :::tabs-item{.my-5 icon="i-lucide-code" label="Vue component"}
  ```vue [app/components/content/BrowserFrame.vue]
  <script setup lang="ts">
  defineProps<{
    title?: string
  }>()
  </script>

  <template>
    <div class="w-fit overflow-hidden rounded-xl border border-muted bg-accented px-2 pb-2 shadow-md">
      <div class="flex items-center justify-between border-b border-accented bg-accented px-2 py-2">
        <div class="flex items-center gap-2">
          <span class="h-3 w-3 rounded-full bg-red-500" />
          <span class="h-3 w-3 rounded-full bg-yellow-500" />
          <span class="h-3 w-3 rounded-full bg-green-500" />
        </div>
        <div class="text-muted">
          {{ title }}
        </div>
      </div>
      <slot mdc-unwrap="p" />
    </div>
  </template>
  ```
  :::

  :::tabs-item{icon="i-simple-icons-markdown" label="Markdown"}
  ```mdc
  ::browser-frame{title="The Alps"}
  ![mountains landscape](https://ptg90phsi6rf8j7h.public.blob.vercel-storage.com/site/mountains.webp)
  ::
  ```
  :::

  :::tabs-item{icon="i-lucide-eye" label="Preview"}
    ::::browser-frame{title="The Alps"}
    ![mountains landscape](https://ptg90phsi6rf8j7h.public.blob.vercel-storage.com/site/mountains.webp)
    ::::
  :::
::

## Vue pages

In addition to Markdown pages, you can create regular Vue pages.

```vue [app/pages/hello.vue]
<template>
  <div>
    <h1>Hello</h1>
  </div>
</template>
```

You can also use `definePageMeta` to change the layout or hide the default shell pieces:

```vue [app/pages/hello.vue]
<script setup lang="ts">
definePageMeta({
  layout: 'default',
  header: false,
  footer: false,
})
</script>
```

## Custom layouts

TockDocs ships with:

- `default` for landing pages and custom Vue pages
- `docs` for documentation pages

You can add your own layouts in `app/layouts/`:

```vue [app/layouts/custom.vue]
<template>
  <main class="custom-layout">
    <slot />
  </main>
</template>
```

## Why the layer approach matters

Because TockDocs is a layer instead of a closed template, you can:

- keep docs authoring in Markdown
- override built-in components when needed
- add your own pages and APIs
- install more Nuxt modules
- mix marketing pages, app pages, and docs in one project

::tip{to="/docs/manual/en/getting-started/project-structure"}
See the project structure guide for how this fits together in legacy mode and KB mode.
::
