Skip to main content
Docus is built on Nuxt, which means you can leverage Nuxt’s powerful extensibility features to customize every aspect of your documentation site.

Overriding Components

Replace any built-in Docus component by creating a file with the same name in your components/ directory.

Component Structure

Docus includes several key components you can override:
components/
├── app/
   ├── AppHeader.vue
   ├── AppHeaderLogo.vue
   ├── AppHeaderBody.vue
   ├── AppHeaderCenter.vue
   ├── AppHeaderCTA.vue
   ├── AppFooter.vue
   ├── AppFooterLeft.vue
   └── AppFooterRight.vue

Example: Custom Header

Create a custom header by overriding AppHeader.vue:
[components/app/AppHeader.vue]
<template>
  <UHeader>
    <template #logo>
      <AppHeaderLogo />
    </template>
    
    <template #center>
      <AppHeaderCenter />
    </template>
    
    <template #right>
      <UButton to="/docs" color="primary">
        Get Started
      </UButton>
      <AppHeaderCTA />
    </template>
  </UHeader>
</template>
1

Create Component

Create a new component in components/app/AppHeader.vue
2

Copy Base Structure

Copy the base structure from the original component or create your own
3

Customize

Add your custom functionality, styling, or layout
4

Auto-Import

Nuxt automatically imports your component, overriding the default

Custom Layouts

Create custom layouts for different page types:
[layouts/custom.vue]
<template>
  <div>
    <AppHeader />
    <main>
      <slot />
    </main>
    <AppFooter />
  </div>
</template>
Use the layout in a page:
[content/docs/special-page.md]
---
title: Special Page
layout: custom
---

This page uses a custom layout.
Layouts give you full control over page structure while reusing components like AppHeader and AppFooter.

Custom Pages

Add custom pages by creating Vue components in the pages/ directory:
[pages/changelog.vue]
<script setup lang="ts">
const { data: releases } = await useFetch('/api/releases')
</script>

<template>
  <UContainer>
    <PageHero title="Changelog" description="Latest updates and releases" />
    
    <div v-for="release in releases" :key="release.id">
      <h2>{{ release.name }}</h2>
      <p>{{ release.body }}</p>
    </div>
  </UContainer>
</template>

Extending Templates

Docus provides template pages that you can extend:

Landing Page Template

The default landing page template is used when you don’t have an index.vue:
[pages/index.vue]
<script setup lang="ts">
const { data: page } = await useAsyncData('index', () => {
  return queryCollection('landing').path('/').first()
})

if (!page.value) {
  throw createError({ statusCode: 404 })
}

useSeoMeta({
  title: page.value.title,
  description: page.value.description,
})
</script>

<template>
  <div>
    <PageHero v-bind="page" />
    <ContentRenderer :value="page" />
  </div>
</template>

Composables

Docus provides several composables you can use in your custom components:

useDocusI18n

<script setup lang="ts">
const { isEnabled, locale, locales, t, localePath } = useDocusI18n()
</script>

<template>
  <div>
    <p v-if="isEnabled">Current locale: {{ locale }}</p>
    <p>{{ t('docs.edit') }}</p>
  </div>
</template>
isEnabled
Ref<boolean>
Whether i18n is enabled
locale
Ref<string>
Current locale code
locales
LocaleObject[]
Available locales
t
(key: string) => string
Translation function
localePath
(path: string) => string
Get localized path

useSeo

<script setup lang="ts">
useSeo({
  title: 'Custom Page',
  description: 'A custom page with SEO',
})
</script>

useLogoAssets

<script setup lang="ts">
const { 
  logo, 
  wordmark, 
  favicon,
  copyLogo,
  downloadLogo,
} = useLogoAssets()
</script>

<template>
  <img :src="logo" alt="Logo" />
  <button @click="copyLogo">Copy Logo</button>
</template>

Custom Modules

Create Nuxt modules to add functionality to Docus:
[modules/analytics.ts]
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    name: 'analytics',
  },
  setup(options, nuxt) {
    const { resolve } = createResolver(import.meta.url)
    
    // Add plugin
    addPlugin(resolve('./runtime/plugin'))
    
    // Extend config
    nuxt.options.runtimeConfig.public.analytics = {
      enabled: true,
    }
  },
})
Register the module:
[nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['./modules/analytics'],
})
When creating custom modules, ensure they don’t conflict with Docus’s internal modules: config, routing, markdown-rewrite, and css.

Plugins

Add functionality with Nuxt plugins:
[plugins/analytics.client.ts]
export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig()
  
  if (config.public.analytics.enabled) {
    // Initialize analytics
    nuxtApp.hook('page:finish', () => {
      // Track page view
    })
  }
})
Use .client.ts suffix for plugins that only run in the browser:
// plugins/analytics.client.ts

API Routes

Add custom API endpoints:
[server/api/search.ts]
export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  
  const results = await queryCollection('docs')
    .where('title', 'contains', query.q)
    .all()
  
  return {
    results,
  }
})
1

Create Handler

Create a file in server/api/ directory
2

Define Logic

Implement your API logic using Nuxt Content or other data sources
3

Use in Frontend

Call the API from your components:
const { data } = await useFetch('/api/search', {
  query: { q: 'installation' },
})

Middleware

Add route middleware for authentication or redirects:
[middleware/auth.ts]
export default defineNuxtRouteMiddleware((to) => {
  const user = useUser()
  
  if (!user.value && to.path.startsWith('/admin')) {
    return navigateTo('/login')
  }
})
Apply globally or per-page:
[pages/admin.vue]
<script setup lang="ts">
definePageMeta({
  middleware: 'auth',
})
</script>

Nitro Configuration

Customize the server with Nitro configuration:
[nuxt.config.ts]
export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ['/sitemap.xml'],
    },
    routeRules: {
      '/api/**': { cors: true },
      '/docs/**': { swr: 3600 },
    },
  },
})
Automatically discover and prerender linked pages
nitro.routeRules
object
Configure caching, headers, and redirects per route pattern

Content Hooks

Hook into content processing:
[nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    'content:file:beforeParse': (file) => {
      // Modify file before parsing
      if (file._id.endsWith('.md')) {
        // Add custom transformations
      }
    },
  },
})

Next Steps

Nuxt Documentation

Learn more about Nuxt features

Nuxt Content

Explore Content module capabilities

Build docs developers (and LLMs) love