How SVG Icons Are Extracted and Converted to React Components in ai-website-cloner-template

The automation script queries all inline <svg> elements from the target website, deduplicates them by hashing their outerHTML, converts them to JSX using SVGR, and writes them as named exports to src/components/icons.tsx.

The ai-website-cloner-template repository provides a workflow for converting any website into a React application. During the cloning process, inline SVG icons are automatically extracted and transformed into reusable React components that integrate with shadcn/ui and Tailwind CSS.

The SVG Extraction Pipeline

The extraction process follows a six-step pipeline defined in the clone-website workflow (.windsurf/workflows/clone-website.md) and outlined in AGENTS.md.

Querying SVG Elements from the DOM

The automation script uses a browser-automation tool (such as Playwright) to execute document.querySelectorAll('svg') against the target page. This captures every inline <svg> element present in the HTML markup.

Deduplication via Hashing

To prevent duplicate icons, the script hashes each SVG's outerHTML string. Identical symbols are collapsed, ensuring only one copy of each unique icon proceeds to the conversion stage.

Generating PascalCase Component Names

The script derives human-readable names based on the SVG's visual purpose. The naming convention follows PascalCase with an Icon suffix. For example, a magnifying glass becomes SearchIcon, while a right-pointing arrow becomes ArrowRightIcon.

Converting SVG to React Components with SVGR

The raw SVG strings are processed by SVGR, the industry-standard tool for transforming SVG into JSX. According to the source configuration, SVGR performs three critical transformations:

  1. Strips unnecessary attributes from the original markup
  2. Preserves remaining attributes on the <svg> tag using the spread operator {...props}
  3. Adds a TypeScript props interface props: React.SVGProps<SVGSVGElement> to enable type-safe customization of size, color, and stroke properties

The Generated Output Structure

All generated components are concatenated into a single module at src/components/icons.tsx. Each icon is exported as a named export following this pattern:

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

export const SearchIcon = (props: React.SVGProps<SVGSVGElement>) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    {...props}
  >
    {/* path data */}
  </svg>
);

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>
);

Consuming Icons in Your Application

UI components import icons directly from the generated module and spread Tailwind CSS classes through the props interface:

import { SearchIcon, ArrowRightIcon } from '@/components/icons';

export function SearchButton() {
  return (
    <button className="flex items-center gap-2">
      <SearchIcon className="size-4" />
      Search
    </button>
  );
}

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

The className="size-4" pattern passes through {...props} to style the SVG element, while stroke="currentColor" ensures the icon inherits the parent's text color.

Summary

  • The automation queries inline <svg> elements using document.querySelectorAll('svg') during the browser automation phase.
  • Duplicate icons are eliminated by hashing each SVG's outerHTML string before processing.
  • SVGR converts raw SVG markup into TypeScript React components with React.SVGProps<SVGSVGElement> typing.
  • Generated components are written to src/components/icons.tsx as named exports using PascalCase with an Icon suffix.
  • Components accept Tailwind CSS classes through the spread props pattern, enabling size and color customization via className and currentColor.

Frequently Asked Questions

What tool converts the SVG markup into React components?

The workflow uses SVGR (SVG React) to transform raw SVG strings into JSX components. SVGR handles attribute optimization and injects the props spread pattern to allow runtime customization of SVG properties.

How does the script prevent duplicate icons from being generated?

The script hashes each SVG element's outerHTML string during the deduplication phase. Identical hashes indicate duplicate symbols, so only one instance of each unique icon proceeds to the component generation stage.

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

Yes. Each generated component accepts React.SVGProps<SVGSVGElement> through a props parameter. The components use stroke="currentColor" and spread {...props} onto the root <svg> element, allowing you to pass Tailwind classes like className="size-4 text-blue-500" to control dimensions and color.

Where are the generated icon components stored?

All extracted SVG icons are written to src/components/icons.tsx as named exports. This file is referenced in the project structure documentation (AGENTS.md) as the location for "Extracted SVG icons as React components."

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →