# How to Integrate Extracted Content with shadcn/ui Component Primitives

> Learn to integrate extracted content with shadcn/ui component primitives by generating React icons, extending cva variants, and merging Tailwind CSS. Boost your UI development now.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-07-21

---

**You integrate extracted content with shadcn/ui component primitives by generating a React icons module from cloned SVGs, extending `cva` variant definitions with extracted design-token classes, and merging all Tailwind utilities through the `cn` helper in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts).**

The `JCodesMore/ai-website-cloner-template` repository is built to bridge AI-extracted website assets and a modern React UI layer. After the `/clone-website` skill runs, you receive SVG icons and design tokens that you can integrate with shadcn/ui component primitives already scaffolded in the template. This guide covers the exact file paths, utility functions, and composition patterns defined in the source code to make that integration seamless.

## Architecture Overview

The template separates three concerns that let you plug cloned assets directly into the UI layer.

- **`cn` utility in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts)** — This function uses `clsx` and `tailwind-merge` to merge Tailwind class lists without conflicts. Every primitive relies on it to compose final class strings.
- **Shadcn/ui primitives in `src/components/ui/*`** — These are thin wrappers around Radix primitives that expose a `cva`-based variant API. For example, [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) wraps `@base-ui/react/button` and applies variant classes via `cn`.
- **Extracted assets** — SVG icons, images, and custom design-token values generated by the AI agents are placed under [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) (created at clone time) and `public/images/…`.

Because every primitive ultimately renders a plain HTML element or Radix component, extracted content can be injected anywhere a `className` or `children` prop is accepted.

## Generated Artifacts After Cloning

When the cloning pipeline completes, it produces two categories of artifacts:

1. **Design tokens** — Colors, radii, spacing, and typography values that map directly onto Tailwind CSS classes or CSS custom properties.
2. **SVG icons** — Visual elements extracted from the source site that correspond to buttons, logos, and decorative graphics.

These artifacts are type-safe by convention: the icons module follows the same pattern as shadcn/ui’s own icon components, and the tokens are applied through `className` strings that `cn` resolves.

## Step-by-Step Integration

### Generate the Icons Module

The first step is to create [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) at clone time. Each extracted SVG is exported as a React component using `forwardRef` so it can receive standard SVG props and refs.

```tsx
// src/components/icons.tsx (generated)
import { forwardRef } from "react";

export const Logo = forwardRef<SVGSVGElement>((props, ref) => (
  <svg ref={ref} viewBox="0 0 24 24" {...props}>
    {/* …extracted path data… */}
  </svg>
));

// repeat for each SVG extracted from the target site

```

This module mirrors the pattern expected by shadcn/ui consumers: import an icon and pass it as a child or through an `icon` prop.

### Use Icons Inside UI Components

With the icons module in place, you can compose them directly inside any primitive. Because shadcn/ui components accept `children`, no internal changes to the primitive are required.

```tsx
// Example usage in a page or component
import { Button } from "@/components/ui/button";
import { Logo } from "@/components/icons";

export default function Example() {
  return (
    <Button variant="outline" size="sm">
      <Logo className="mr-2 size-4" />
      Sign in
    </Button>
  );
}

```

The `Button` primitive in [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) remains untouched; the extracted icon is injected through composition.

### Extend Variants with Design Tokens

Extracted design tokens become new variants inside the existing `cva` configuration. In [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx), the `buttonVariants` object can accept additional token-driven classes without breaking the original API.

```tsx
// src/components/ui/button.tsx – extend buttonVariants
import { cva } from "class-variance-authority";

const buttonVariants = cva(
  "group/button inline-flex ...", // existing base classes
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        // NEW variant derived from extracted token
        accent: "bg-[var(--extracted-accent-bg)] text-[var(--extracted-accent-fg)]",
        // keep existing ones…
      },
      // size variants stay the same
    },
    defaultVariants: { variant: "default", size: "default" },
  }
);

```

This keeps the UI code type-safe while allowing the cloned aesthetic to propagate through the same variant API.

### Merge Classes Safely with `cn`

The `cn` utility exported from [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts) guarantees that Tailwind class merging rules are respected. Use it whenever you combine generated token classes with user-provided or primitive classes.

```tsx
import { cn } from "@/lib/utils";

const cardClass = cn(
  "rounded-lg p-4",
  "bg-[var(--extracted-card-bg)]", // token from extraction
  customClass // user-provided class
);

```

According to the source code in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts), `cn(...inputs)` delegates to `clsx` for conditional logic and `tailwind-merge` for deduplication, so duplicate `bg-` or `p-` utilities never conflict.

## Practical Code Examples

### Page-Level Composition

The file [`src/app/page.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/page.tsx) demonstrates how to mix extracted icons, extended button variants, and token-driven layout classes in a single view.

```tsx
/* src/app/page.tsx */
import { Button } from "@/components/ui/button";
import { Logo } from "@/components/icons";
import { cn } from "@/lib/utils";

export default function Home() {
  return (
    <main className="flex min-h-screen items-center justify-center gap-4">
      <Button variant="accent" size="lg">
        <Logo className="mr-2 size-5" />
        Get Started
      </Button>

      {/* A card that uses extracted design tokens */}
      <section
        className={cn(
          "rounded-xl p-6 shadow-md",
          "bg-[var(--extracted-card-bg)]",
          "border-[var(--extracted-card-border)]"
        )}
      >
        <h2 className="text-xl font-bold">Welcome</h2>
        <p className="mt-2 text-muted-foreground">
          This UI is built from assets cloned from the original site.
        </p>
      </section>
    </main>
  );
}

```

### Primitive-Level Token Injection

You can also bake extracted tokens directly into other shadcn/ui primitives. Below is an `Input` component that references cloned color variables for its background and border.

```tsx
/* src/components/ui/input.tsx */
import { Input as InputPrimitive } from "@base-ui/react/input";
import { cn } from "@/lib/utils";

export function Input({ className, ...props }: InputPrimitive.Props) {
  return (
    <InputPrimitive
      className={cn(
        "border rounded-md px-3 py-2",
        "bg-[var(--extracted-input-bg)]",
        "border-[var(--extracted-input-border)]",
        className
      )}
      {...props}
    />
  );
}

```

This pattern ensures the extracted palette is respected even at the lowest-level wrapper.

## Key Files and Their Roles

- **[`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts)** — Houses the `cn` utility that merges Tailwind classes safely using `clsx` and `tailwind-merge`.
- **[`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx)** — The shadcn/ui primitive wrapping `@base-ui/react/button`; exposes `buttonVariants` via `cva`.
- **[`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx)** — Generated at clone time; exports each extracted SVG as a `forwardRef` React component.
- **[`src/app/page.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/page.tsx)** — Example page composing extracted icons and design tokens with shadcn/ui primitives.
- **[`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx)** — Global layout loading Tailwind and font configuration for the entire application.

## Summary

- **Generate [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx)** to expose every extracted SVG as a reusable React component.
- **Extend `cva` variants** in primitives such as [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) with extracted design-token classes.
- **Use `cn` from [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts)** whenever you merge Tailwind utilities to prevent conflicting class names.
- **Compose via `children` and `className`** rather than editing primitive internals, keeping the architecture clean and type-safe.
- **Reference CSS variables** like `var(--extracted-accent-bg)` directly in variant definitions to reflect the cloned site's design.

## Frequently Asked Questions

### Can I add extracted icons to any shadcn/ui primitive?

Yes. Because shadcn/ui primitives render standard HTML or Radix elements, they accept `children` and `className` props natively. You can import any icon from [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) and place it inside a `Button`, `Dialog`, or `DropdownMenu` without modifying the primitive source.

### Where should the extracted design tokens live?

The tokens are consumed as CSS custom properties referenced inside `className` strings. You can define these variables in a global stylesheet or in [`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx), then reference them in variant objects like `buttonVariants` or inside `cn` calls across `src/components/ui/*`.

### Does the `cn` utility handle duplicate Tailwind classes?

Yes. The `cn` function in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts) passes inputs through `tailwind-merge`, which automatically resolves duplicate utilities. For example, if `"bg-red-500"` and `"bg-blue-500"` are both supplied, the last one wins and no invalid CSS is produced.

### Do I need to modify Radix or base-ui imports to use cloned assets?

No. The template wraps primitives such as `@base-ui/react/button` and `@base-ui/react/input` in local files under `src/components/ui/`. You only edit the wrapper files to inject token classes; the underlying Radix or base-ui imports remain unchanged.