ComponentExample

ComponentExample embeds interactive Vue component examples in your documentation, rendering a live preview and displaying syntax-highlighted source code with collapsible support. It fetches example files registered at build time via useFetchComponentExample, significantly improving the readability and user experience of your docs.

Usage

ComponentExample is used to embed interactive component examples in your documentation. It automatically loads the component and shows a live preview alongside the source code.

Basic usage

Use the :component-example directive in your Markdown documentation:

<script setup lang="ts">
import type { AccordionItem } from '@nuxt/ui'

const items = [
  {
    label: 'Icons',
    icon: 'i-lucide-smile',
    content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
  },
  {
    label: 'Colors',
    icon: 'i-lucide-swatch-book',
    slot: 'colors' as const,
    content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
  },
  {
    label: 'Components',
    icon: 'i-lucide-box',
    content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
  }
] satisfies AccordionItem[]
</script>

<template>
  <UAccordion :items="items">
    <template #colors="{ item }">
      <p class="text-sm pb-3.5 text-primary">
        {{ item.content }}
      </p>
    </template>
  </UAccordion>
</template>
:component-example{name="AccordionExample"}

Advanced configuration

md
::component-example
---
name: AccordionExample
highlights: [10, 15, 20]
collapse: true
---
::

Client-only rendering

If the example uses browser APIs such as window, document, or setInterval directly, you can add client-only="true" so the preview component renders only on the client, avoiding warnings during the SSR phase:

md
:component-example{name="AccordionExample" client-only="true"}

API

Props

Prop Default Type
namestring
iframefalseboolean | { [key: string]: any; }

是否在 iframe 中渲染组件

props{ [key: string]: any; }
collapsefalseboolean | { icon?: string; name?: string; openText?: string; closeText?: string; open?: boolean; }

是否折叠代码块

options{ type?: string; alias?: string; name: string; label: string; items?: any[]; default: any; multiple?: boolean; }[]

链接到组件的可变属性列表

highlightsnumber[]

代码块中需要高亮的行号列表

lang'vue'string
filenamestring

覆盖用于代码块的文件名

iframeMobilefalseboolean

是否在移动端尺寸的 iframe 视口中显示组件

prettierfalseboolean

是否使用 Prettier 格式化代码

previewtrueboolean

是否显示预览 当设置为 false 时,将显示文件名

sourcetrueboolean

是否显示源代码

overflowHiddenboolean

是否在包装器上添加 overflow-hidden

clientOnlyfalseboolean

是否只在客户端渲染预览组件,适用于依赖 window / setInterval 等浏览器 API 的示例

elevatedboolean

是否添加 background-elevated 到 wrapper

Slots

Slot Type
options{}
code{}

ComponentExampleExtras

Create app/components/content/ComponentExampleExtras.vue in the consumer repository to overlay additional UI such as ThemeVisualizer or a Playground button inside the example container, without forking ComponentExample. The layer provides an empty implementation by default.

Available props:

PropTypeDescription
namestringThe raw value of the MDC name="...", i.e. the example filename
camelNamestringThe camelCase form of the example name
pascalNamestringThe PascalCase form of the example name, from useFetchComponentExample
effectivePropsRecord<string, any>The currently effective merged props (including options)
optionsArray<{ name, label, ... }> | undefinedThe options configuration, passed through as-is
wrapperContainerHTMLElement | nullThe outermost wrapper, used for popover / highlight box positioning
componentContainerHTMLElement | nullThe actual render container of the example component, used for DOM scanning such as querySelector('[data-slot]')

Example: overlaying ThemeVisualizer

Following Nuxt UI's ComponentThemeVisualizer.vue, implement a LazyComponentThemeVisualizer, then wire it up in the override file.

docs/app/components/content/ComponentExampleExtras.vue
<script setup lang="ts">
import { camelCase } from 'scule'

defineProps<{
  wrapperContainer: HTMLElement | null
  componentContainer: HTMLElement | null
}>()

const route = useRoute()
const slug = computed(() => camelCase(route.path.split('/').pop() ?? ''))
</script>

<template>
  <LazyComponentThemeVisualizer
    :slug="slug"
    :container="componentContainer"
    :position-container="wrapperContainer"
  />
</template>

Changelog

No recent changes
Copyright © 2024 - 2026