# How Extracted SVG Icons Are Converted to React Components in the AI Website Cloner

> Learn how the AI Website Cloner converts extracted SVG icons into type-safe React components using SVGR. Discover the process detailed in the JCodesMore repository.

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

---

**The JCodesMore/ai-website-cloner-template pipeline extracts inline `<svg>` elements from target websites, deduplicates them by hashing their outerHTML, and uses SVGR to generate type-safe React components exported from [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx).**

This repository automates the cloning of existing websites into React-based codebases. A critical part of this workflow involves identifying vector graphics on the source page and transforming them into reusable, customizable React components that integrate with the shadcn/ui and Tailwind CSS stack.

## The Six-Step Extraction Pipeline

The conversion process is orchestrated by a browser-automation script (typically using Playwright) that runs during the inspection phase. According to the **clone-website workflow** documented in [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md), the system follows a strict six-step pipeline to handle SVG extraction.

### Step 1: Collecting SVG Markup

The automation queries the target page for all vector graphics using standard DOM selectors. It executes `document.querySelectorAll('svg')` to capture every inline `<svg>` element present in the HTML.

### Step 2: Deduplicating Icons

To prevent redundant components, each SVG's `outerHTML` string is hashed. Identical symbols are collapsed, ensuring that only one unique copy of each visual icon proceeds to the generation phase. This deduplication step keeps the final bundle size minimal and avoids naming conflicts.

### Step 3: Generating Component Names

The script derives human-readable, semantic names based on the SVG's visual purpose or context. These names follow strict **PascalCase** conventions with an `Icon` suffix. For example, a magnifying glass becomes `SearchIcon`, while a right-pointing arrow becomes `ArrowRightIcon`.

### Step 4: Converting SVG to React with SVGR

The raw SVG markup is fed into **SVGR**, the industry-standard tool for transforming SVG into JSX. SVGR strips unnecessary attributes, spreads remaining props onto the `<svg>` tag, and adds a TypeScript interface accepting `props: React.SVGProps<SVGSVGElement>`. This allows callers to override attributes like `className`, `fill`, or `stroke` at runtime.

### Step 5: Writing to icons.tsx

All generated components are concatenated into a single module at [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx). As noted in [`AGENTS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/AGENTS.md), this file is explicitly designated in the project structure as the destination for "Extracted SVG icons as React components." Each icon is exported as a named export:

```tsx
/* src/components/icons.tsx – auto-generated */
import React from 'react';

export const ArrowRightIcon = (
  props: React.SVGProps<SVGSVGElement>
) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    {...props}
  >
    <path d="M5 12h14M12 5l7 7-7 7" />
  </svg>
);

```

### Step 6: Consuming the Components

Downstream UI components import icons directly from the generated module. Because the components accept standard React SVG props, they integrate seamlessly with Tailwind CSS utility classes:

```tsx
import { ArrowRightIcon } from '@/components/icons';

export function CallToAction() {
  return (
    <a
      href="/pricing"
      className="inline-flex items-center gap-1 font-medium"
    >
      Get started
      <ArrowRightIcon className="size-4" />
    </a>
  );
}

```

## Generated Component Structure

The output in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) follows a consistent pattern. Every component is a functional component accepting `React.SVGProps<SVGSVGElement>` as its sole parameter. The spread operator (`{...props}`) is placed after default attributes, allowing consumer-defined props to override the defaults. This pattern ensures type safety while maintaining flexibility for styling and accessibility attributes.

## Integration with the Tech Stack

The generated components are designed specifically for the repository's preferred stack. By exporting from [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx), the system aligns with the **shadcn/ui** component architecture, where icons are typically imported as discrete components rather than sprite sheets. The use of `currentColor` for strokes and fills ensures compatibility with Tailwind's text color utilities, allowing developers to change icon colors via `className="text-blue-500"` or similar utilities.

## Summary

- **SVGR** handles the heavy lifting of converting raw SVG strings into typed React JSX.
- Icons are deduplicated via hashing of the `outerHTML` to ensure only unique graphics are converted.
- Component naming follows PascalCase with an `Icon` suffix (e.g., `SearchIcon`, `ArrowRightIcon`).
- All icons are centralized in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) as named exports for clean imports.
- The `React.SVGProps<SVGSVGElement>` interface allows full customization of size, color, and accessibility attributes through standard React props.

## Frequently Asked Questions

### What tool converts the SVG markup into React JSX?

The pipeline uses **SVGR** (the standard SVG-to-React conversion tool). It parses the raw SVG string, removes redundant attributes, and wraps the markup in a React functional component that accepts standard SVG props.

### How does the system prevent duplicate icons?

During extraction, each SVG element's `outerHTML` is hashed. Identical hashes trigger deduplication, so only one instance of each unique graphic is converted into a React component. This prevents bloating the [`icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/icons.tsx) file with redundant definitions.

### Where are the generated React components stored?

All generated icon components are written to [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx). This path is hardcoded in the clone-website workflow and referenced in [`AGENTS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/AGENTS.md) as the canonical location for extracted SVG assets.

### Can I customize the size and color of the generated icons?

Yes. Every generated component accepts a `props` object of type `React.SVGProps<SVGSVGElement>`, which includes standard HTML SVG attributes. You can pass `className` to target Tailwind utilities like `size-4` or `text-red-500`, or directly set `width`, `height`, `fill`, and `stroke` attributes.