# How to Convert Extracted Inline SVGs into Named React Components in icons.tsx

> Learn to convert inline SVGs into named React components in icons.tsx. Define IconProps, wrap SVGs in function components, and export them for type-safe use in your Next.js app.

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

---

**To convert extracted inline SVGs into named React components in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx), define a reusable `IconProps` type that extends `React.SVGProps<SVGSVGElement>`, wrap each raw SVG markup block in a named function component, and export them for type-safe use across your Next.js application.**

When the AI website cloning pipeline in the **JCodesMore/ai-website-cloner-template** extracts raw `<svg>` markup from target sites, it stores the SVG code as plain text. To make these icons usable within the generated Next.js project, you must convert them into reusable, typed React components centralized in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx).

## Why Convert Inline SVGs to React Components?

Raw SVG strings lack TypeScript safety and cannot accept dynamic Tailwind classes. By converting them to React components in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx), you enable className merging via the `cn` utility (as implemented in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts)) and ensure consistent prop typing across the application, following the same pattern used in [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx).

## Step-by-Step Conversion Process

### Step 1: Locate the Extracted SVG Markup

The cloning script saves each distinct `<svg>` block as plain text. Copy the raw markup including the opening `<svg>` tag and its attributes.

### Step 2: Create the icons.tsx File

Create [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) if it does not exist. This file serves as the single source of truth for all extracted icons in the repository.

### Step 3: Define the IconProps Type

Define a reusable type that extends React's native SVG props:

```typescript
import * as React from "react";

type IconProps = React.SVGProps<SVGSVGElement> & {
  /** Optional className merged with the SVG's default classes */
  className?: string;
};

```

### Step 4: Wrap SVGs in Named Components

Convert each SVG into a named component that spreads props to the root element:

```tsx
/** Search icon – extracted from the target site */
export const SearchIcon = (props: IconProps) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    className={props.className}
    {...props}
  >
    <path d="M11 4a7 7 0 1 0 0 14..." />
  </svg>
);

```

Repeat this pattern for every extracted SVG, choosing descriptive names like `SearchIcon`, `ArrowRightIcon`, or `LogoIcon` that reflect the visual function.

### Step 5: Export and Consume the Icons

Export individual icons for tree-shaking and optionally a default map for dynamic imports:

```tsx
export { SearchIcon, ArrowRightIcon, LogoIcon };

// Optional: Default export map for dynamic imports
const ICONS = {
  Search: SearchIcon,
  ArrowRight: ArrowRightIcon,
  Logo: LogoIcon,
};

export default ICONS;

```

## Complete icons.tsx Implementation Example

Here is the full skeleton for [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx):

```tsx
// src/components/icons.tsx
import * as React from "react";

type IconProps = React.SVGProps<SVGSVGElement> & {
  className?: string;
};

/* SearchIcon – extracted from the target website */
export const SearchIcon = (props: IconProps) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    className={props.className}
    {...props}
  >
    <path d="M11 4a7 7 0 1 0 0 14..." />
  </svg>
);

/* ArrowRightIcon – navigation arrow extracted from the site */
export const ArrowRightIcon = (props: IconProps) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    className={props.className}
    {...props}
  >
    <path d="M5 12h14M12 5l7 7-7 7" />
  </svg>
);

/* LogoIcon – brand logo extracted from the site */
export const LogoIcon = (props: IconProps) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 100 100"
    fill="currentColor"
    className={props.className}
    {...props}
  >
    <circle cx="50" cy="50" r="40" />
  </svg>
);

export { SearchIcon, ArrowRightIcon, LogoIcon };

```

## Using Icons with the Button Component

Consume the icons in components like the Button:

```tsx
import { SearchIcon } from "@/components/icons";
import { Button } from "@/components/ui/button";

<Button variant="default" size="default">
  <SearchIcon className="mr-2 size-4" />
  Search
</Button>

```

The `className` prop allows Tailwind sizing and coloring, consistent with the `cn` utility pattern found in [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts).

## Key Files and References

- **[`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx)**: Central location for all extracted SVG React components.
- **[`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts)**: Contains the `cn` utility for className merging used throughout the template.
- **[`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx)**: Demonstrates the pattern of accepting and merging `className` props that icons should follow.

## Summary

- Store all extracted SVG components in [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) for centralized management.
- Define an `IconProps` type that extends `React.SVGProps<SVGSVGElement>` to maintain type safety.
- Spread props onto the `<svg>` element to allow Tailwind class overrides via the `className` prop.
- Export icons individually for tree-shaking or as a default map for dynamic imports.
- Follow the same `className` merging pattern used in [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) for consistency.

## Frequently Asked Questions

### How do I handle SVGs with existing class attributes?

Merge the existing classes with the `className` prop using the `cn` utility from [`src/lib/utils.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/utils.ts), or simply pass `props.className` to the SVG's `className` attribute to allow Tailwind overrides while preserving default styling.

### Can I use these icons with dynamic imports?

Yes. Export an `ICONS` map object as the default export from [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx), then import it dynamically using `import()` or Next.js `dynamic()` imports to load icons on demand.

### Should I remove the xmlns attribute from the SVG?

No. Keep the `xmlns="http://www.w3.org/2000/svg"` attribute on the root `<svg>` element to ensure proper rendering in all browsers, even when the component is used outside of standard HTML contexts.

### How do I size the icons using Tailwind CSS?

Pass Tailwind utility classes like `size-4`, `w-6`, `h-6`, or `text-red-500` via the `className` prop. The component spreads these props to the underlying `<svg>` element, allowing full styling control consistent with the `cn` utility pattern.