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:
- Strips unnecessary attributes from the original markup
- Preserves remaining attributes on the
<svg>tag using the spread operator{...props} - 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 usingdocument.querySelectorAll('svg')during the browser automation phase. - Duplicate icons are eliminated by hashing each SVG's
outerHTMLstring before processing. - SVGR converts raw SVG markup into TypeScript React components with
React.SVGProps<SVGSVGElement>typing. - Generated components are written to
src/components/icons.tsxas named exports using PascalCase with anIconsuffix. - Components accept Tailwind CSS classes through the spread props pattern, enabling size and color customization via
classNameandcurrentColor.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →