# Snippet **Category**: react **URL**: https://www.heroui.com/docs/react/migration/snippet **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/snippet.mdx > Migration guide for Snippet from HeroUI v2 to v3 *** The Snippet component has been **removed** in HeroUI v3. Use native HTML elements with Tailwind CSS classes and implement copy functionality manually using the Clipboard API. ## Key Changes ### 1. Component Removal **v2:** `` component from `@heroui/react` **v3:** Native HTML elements (`
`, ``) with manual copy implementation

### 2. Features Mapping

The v2 Snippet component had the following features that need to be replaced:

| v2 Feature | v3 Equivalent | Notes |
|-----------|---------------|-------|
| Copy button | Manual Button + Clipboard API | Use `navigator.clipboard.writeText()` |
| Copy tooltip | Tooltip component | Use v3 Tooltip component |
| Symbol prefix | Manual rendering | Add symbol as text content |
| Multi-line support | Array mapping | Map over array of strings |
| Variants (`flat`, `solid`, `bordered`, `shadow`) | Tailwind classes | Use background/border utilities |
| Colors (`default`, `primary`, etc.) | Tailwind classes | Use color utilities |
| Sizes (`sm`, `md`, `lg`) | Tailwind text sizes | Use `text-sm`, `text-base`, `text-lg` |
| Radius | Tailwind border radius | Use `rounded-*` classes |

## Structure Changes

In v2, `Snippet` was a component wrapper with built-in copy functionality:

```tsx
import { Snippet } from "@heroui/react";

export default function App() {
  return (
    
      npm install @heroui/react
    
  );
}

```

In v3, use native HTML elements with manual copy implementation:

```tsx
import { Button, Tooltip } from "@heroui/react";
import { useState } from "react";

export default function App() {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    await navigator.clipboard.writeText("npm install @heroui/react");
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    
        $ 
        npm install @heroui/react
      
{copied ? "Copied!" : "Copy to clipboard"}
); } ``` ## Migration Examples ### Multi-line Snippet ```tsx {[ "npm install @heroui/react", "yarn add @heroui/react", "pnpm add @heroui/react" ]} ``` ```tsx import { Button, Tooltip } from "@heroui/react"; import { useState } from "react"; function MultiLineSnippet() { const [copied, setCopied] = useState(false); const lines = [ "npm install @heroui/react", "yarn add @heroui/react", "pnpm add @heroui/react" ]; const codeString = lines.join("\n"); const handleCopy = async () => { await navigator.clipboard.writeText(codeString); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return (
{lines.map((line, index) => (
                $ 
                {line}
              
))}
{copied ? "Copied!" : "Copy to clipboard"}
); } ```
### Styling Options ```tsx {/* With variants */} npm install @heroui/react {/* Without symbol */} npm install @heroui/react {/* Without copy button */} npm install @heroui/react ``` ```tsx {/* With variants */}
        $ 
        npm install @heroui/react
      
{/* Copy button */}
{/* Without symbol */}
        npm install @heroui/react
      
{/* Copy button */}
{/* Without copy button */}
        $ 
        npm install @heroui/react
      
```
## Creating a Reusable Snippet Component (Recommended) Since Snippet functionality is commonly needed, here's a complete reusable component: ```tsx import { Snippet } from "@heroui/react"; npm install @heroui/react ``` ```tsx import { Button, Tooltip } from "@heroui/react"; import { useState, ReactNode } from "react"; import { cn } from "@/lib/utils"; // or your cn utility interface SnippetProps { children: string | string[]; symbol?: string | ReactNode; variant?: "flat" | "solid" | "bordered" | "shadow"; color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger"; size?: "sm" | "md" | "lg"; radius?: "none" | "sm" | "md" | "lg" | "full"; hideSymbol?: boolean; hideCopyButton?: boolean; disableCopy?: boolean; disableTooltip?: boolean; className?: string; codeString?: string; onCopy?: (value: string) => void; } const variantClasses = { flat: "bg-default-100", solid: "bg-default-200", bordered: "border border-default-200 bg-transparent", shadow: "bg-default-100 shadow-sm", }; const colorClasses = { default: "text-default-foreground", primary: "text-accent", secondary: "text-default-600", success: "text-success", warning: "text-warning", danger: "text-danger", }; const sizeClasses = { sm: "px-1.5 py-0.5 text-xs", md: "px-3 py-1.5 text-sm", lg: "px-4 py-2 text-base", }; const radiusClasses = { none: "rounded-none", sm: "rounded-sm", md: "rounded-md", lg: "rounded-lg", full: "rounded-full", }; export function Snippet({ children, symbol = "$", variant = "flat", color = "default", size = "md", radius = "md", hideSymbol = false, hideCopyButton = false, disableCopy = false, disableTooltip = false, className, codeString, onCopy, }: SnippetProps) { const [copied, setCopied] = useState(false); const isMultiLine = Array.isArray(children); const lines = isMultiLine ? children : [children]; const textToCopy = codeString || (isMultiLine ? lines.join("\n") : String(children)); const handleCopy = async () => { if (disableCopy) return; try { await navigator.clipboard.writeText(textToCopy); setCopied(true); setTimeout(() => setCopied(false), 2000); onCopy?.(textToCopy); } catch (error) { console.error("Failed to copy:", error); } }; const symbolElement = hideSymbol ? null : ( {symbol}{typeof symbol === "string" ? " " : ""} ); const copyButton = hideCopyButton ? null : ( {copied ? "Copied!" : "Copy to clipboard"} ); return (
{isMultiLine ? (
{lines.map((line, index) => (
                    {symbolElement}
                    {line}
                  
))}
) : (
                {symbolElement}
                {children}
              
)}
{copyButton}
); } // Usage npm install @heroui/react ```
## Summary 1. **Component Removed**: `Snippet` component no longer exists in v3 2. **Import Change**: Remove `import { Snippet } from "@heroui/react"` 3. **Use Native Elements**: Replace with native `
` and `` elements
4. **Manual Copy**: Implement copy functionality using Clipboard API
5. **Styling**: Apply Tailwind CSS classes directly for variants, colors, sizes
6. **Tooltip**: Use v3 Tooltip component for copy button tooltips
7. **Button**: Use v3 Button component for copy button

## Migration Steps

1. **Remove Import**: Remove `Snippet` from `@heroui/react` imports
2. **Replace Component**: Replace all `` instances with native HTML elements
3. **Add Copy Functionality**: Implement copy using `navigator.clipboard.writeText()`
4. **Add Copy Button**: Use v3 Button component with Tooltip
5. **Apply Styling**: Use Tailwind CSS classes for variants, colors, sizes
6. **Handle Multi-line**: Map over arrays if multi-line snippets are needed
7. **Optional**: Create reusable Snippet component for your application

## Clipboard API Notes

The Clipboard API requires:
- HTTPS (or localhost for development)
- User interaction (can't be called automatically)
- Browser support (modern browsers)

For fallback support:

```tsx
const handleCopy = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text);
  } catch (error) {
    // Fallback for older browsers
    const textArea = document.createElement("textarea");
    textArea.value = text;
    textArea.style.position = "fixed";
    textArea.style.opacity = "0";
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand("copy");
    document.body.removeChild(textArea);
  }
};

```