VitePress Copy Button

website·Indexed 32 days ago

https://vitepress-copybutton.cssnr.com

A component for VitePress that adds a copy button to code blocks, featuring optional parameters for customization.

Tokens
1.9K
Snippets
12
Records
14
Agent score
0%

What's inside VitePress Copy Button

  1. Use the setup hook for Composition API logic

    The setup hook runs inside the root component's setup(), allowing the use of Composition API calls (like watch or onMounted) without wrapping them in a layout component. Note that browser-only work must be placed inside onMounted as this hook also runs during SSR/SSG.
    import { watch } from 'vue'
    import { useData } from 'vitepress'
    import DefaultTheme from 'vitepress/theme'
    
    export default {
      extends: DefaultTheme,
      setup() {
        const { page } = useData()
        watch(() => page.value.relativePath, (path) => {
          console.log('now viewing', path)
        })
      }
    }
  2. Setup CopyButton in VitePress theme

    To use the CopyButton component, register it in your .vitepress/theme/index.ts (or .js) file. You must import the component and its associated CSS styles.
    import DefaultTheme, { VPBadge } from 'vitepress/theme'
    import CopyButton from '@cssnr/vitepress-plugin-copybutton'
    import '@cssnr/vitepress-plugin-copybutton/style.css'
    
    export default {
      ...DefaultTheme,
      enhanceApp({ app }) {
        // VPBadge is only required if using VitePress Badges
        app.component('Badge', VPBadge)
        // Register the CopyButton component as 'CB'
        app.component('CB', CopyButton)
      },
    }
  3. Build a custom layout component

    A basic layout must include the <Content /> component to render markdown content. You can use the useData() helper to access page.isNotFound for 404 pages or frontmatter to conditionally render different layouts based on page-level configuration (e.g., layout: home).
    <script setup>
    import { useData } from 'vitepress'
    const { page, frontmatter } = useData()
    </script>
    
    <template>
      <h1 >Custom Layout!</h1>
    
      <div v-if="page.isNotFound">
        Custom 404 page!
      </div>
      <div v-if="frontmatter.layout === 'home'">
        Custom home page!
      </div>
      <Content v-else />
    </template>
  4. Enable a custom theme in VitePress

    VitePress enables a custom theme when it detects a theme entry file at .vitepress/theme/index.js or .vitepress/theme/index.ts. When this file exists, VitePress uses the custom theme instead of the default theme.
    . 
    ├─ docs                # project root
    │  ├─ .vitepress
    │  │  ├─ theme
    │  │  │  └─ index.js   # theme entry
    │  │  └─ config.js     # config file
    │  └─ index.md
    └─ package.json
  5. Consume an external npm theme

    To use a theme distributed via npm, import and re-export it from your .vitepress/theme/index.js. If the theme provides a base configuration, extend it in your .vitepress/config.ts using the extends property.
    // .vitepress/theme/index.js
    import Theme from 'awesome-vitepress-theme'
    export default Theme
    // .vitepress/config.ts
    import baseConfig from 'awesome-vitepress-theme/config'
    import { defineConfig } from 'vitepress'
    import type { ThemeConfig } from 'awesome-vitepress-theme'
    
    export default defineConfig<ThemeConfig>({
      extends: baseConfig,
      themeConfig: {
        // Theme-specific options
      }
    })
    
  6. Use the Badge component in VitePress

    The Badge component is globally available in VitePress and is used to add status labels (such as version numbers or status tags) to headers. It can be used by providing a text prop or by passing children into the component slot.
    ### Title <Badge type="info" text="default" />
    ### Title <Badge type="tip" text="^1.9.0" />
    ### Title <Badge type="warning" text="beta" />
    ### Title <Badge type="danger" text="deprecated" />
    
    <!-- Using custom children instead of the text prop -->
    ### Title <Badge type="info">custom element</Badge>
  7. Install vitepress-plugin-copybutton

    Install the copy button plugin for VitePress using your preferred package manager.
    npm i @cssnr/vitepress-plugin-copybutton
    # or
    pnpm i @cssnr/vitepress-plugin-copybutton
    # or
    yarn add @cssnr/vitepress-plugin-copybutton
    # or
    bun i @cssnr/vitepress-plugin-copybutton
  8. Implement the VitePress Theme interface

    A custom theme is defined as an object exported as the default export from the theme entry file. The only required property is Layout. Optional hooks include enhanceApp for Vue app instance modification, setup for Composition API logic in the root component, and extends to inherit from another theme.
    interface Theme {
      /** Root layout component for every page @required */
      Layout: Component
      /** Enhance Vue app instance @optional */
      enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
      /** Runs inside the root component's `setup()` @optional */
      setup?: () => void
      /** Extend another theme @optional */
      extends?: Theme
    }
    
    interface EnhanceAppContext {
      app: App // Vue app instance
      router: Router // VitePress router instance
      siteData: Ref<SiteData> // Site-level metadata
    }
  9. Badge component API reference

    The <Badge> component accepts the following props to control its appearance and content.
    interface Props {
      // The text to display inside the badge. Ignored if children/slot are provided.
      text?: string
    
      // The color style of the badge. Defaults to `tip`.
      // Matches markdown containers/alerts colors.
      type?: 'info' | 'note' | 'tip' | 'important' | 'caution' | 'warning' | 'danger'
    }
  10. Use the enhanceApp hook for global configuration

    The enhanceApp hook provides access to the Vue app instance and the VitePress router. It is used to register global components, integrate Vue libraries, or listen for route changes using router.onBeforeRouteChange and router.onAfterRouteChange.
    export default {
      enhanceApp({ router }) {
        router.onBeforeRouteChange = (to) => {
          console.log('navigating to', to)
          // Return false to cancel navigation
        }
    
        router.onAfterRouteChange = (to) => {
          console.log('navigated to', to)
        }
      }
    }
  11. Customize Badge colors via CSS variables

    You can override the default styles of the Badge component by redefining the following CSS variables in your :root or a specific scope. Each type has a border, text, and background variable.
    :root {
      --vp-badge-info-border: transparent;
      --vp-badge-info-text: var(--vp-c-text-2);
      --vp-badge-info-bg: var(--vp-c-default-soft);
    
      --vp-badge-note-border: transparent;
      --vp-badge-note-text: var(--vp-c-note-1);
      --vp-badge-note-bg: var(--vp-c-note-soft);
    
      --vp-badge-tip-border: transparent;
      --vp-badge-tip-text: var(--vp-c-tip-1);
      --vp-badge-tip-bg: var(--vp-c-tip-soft);
    
      --vp-badge-important-border: transparent;
      --vp-badge-important-text: var(--vp-c-important-1);
      --vp-badge-important-bg: var(--vp-c-important-soft);
    
      --vp-badge-caution-border: transparent;
      --vp-badge-caution-text: var(--vp-c-caution-1);
      --vp-badge-caution-bg: var(--vp-c-caution-soft);
    
      --vp-badge-warning-border: transparent;
      --vp-badge-warning-text: var(--vp-c-warning-1);
      --vp-badge-warning-bg: var(--vp-c-warning-soft);
    
      --vp-badge-danger-border: transparent;
      --vp-badge-danger-text: var(--vp-c-danger-1);
      --vp-badge-danger-bg: var(--vp-c-danger-soft);
    }