Believe it or not, you don't need extra dependencies to add icons in your App as actual components. Be it Svelte, React, or SolidJS.
This is the BEST way to add icons.
I'll share with you my best-practice for adding icons in your App. I currently use these three frameworks: React, SolidJS, and Svelte, so I'll show you how to add and manage your icons in each of those projects, without compromising on flexibility..
You only need two things:
- Icones.js.org; and
- This guide.
First, find an icon.
Go to Icones.js.org and search for the icon you want to add. Then click on the SVG button under "Snippets". For instance, I'll use this Marker Duotone icon. (The svg would be copied to your clipboard)
Second, add it to your JS app.
Now that you've copied the SVG to your clipboard, you can add it to your app. I'll show you how to do it in React, SolidJS, and Svelte. I usually store my icons in this structure:
- src
- assets
- icons
- index.ts
- marker-duotone.tsx # This is your icon.
- *.tsx # All your other icons.
You really only need to add {...props}
and add the SVG attributes to the props types.
React
Create a new .tsx
for your icon and extend the props with SVGProps<SVGSVGElement>
:
// src/assets/icons/marker-duotone.tsx
import { SVGProps } from 'react';
export default function MarkerDuotone(props: SVGProps<SVGSVGElement>) {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
{/* Your SVG code here */}
</svg>
)
}
Prefix the named export with Icon
it's easy to find with intellisense:
// src/assets/index.ts
export { default as IconMarkerDuotone } from './icons/marker-duotone';
// ... Do the same for the other icons here
Svelte 5
Create a new .svelte
for your icon and extend the props with SVGAttributes<SVGSVGElement>
:
<!-- src/assets/icons/marker-duotone.svelte -->
<script lang="ts">
import type { SVGAttributes } from 'svelte/elements';
let { ...restProps }: SVGAttributes<SVGSVGElement> = $props();
</script>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...restProps}
>
<!-- Your SVG code here -->
</svg
>
Prefix the named export with Icon
it's easy to find with intellisense:
// src/assets/index.ts
export { default as IconMarkerDuotone } from './icons/marker-duotone.svelte';
// ... Do the same for the other icons here
SolidJS
Create a new .tsx
for your icon and extend the props with JSX.SvgSVGAttributes<SVGSVGElement>
:
// src/assets/icons/marker-duotone.tsx
import { JSX, mergeProps, VoidProps } from 'solid-js';
export default function MarkerDuotone(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
{/* Your SVG code here */}
</svg>
)
}
Prefix the named export with Icon
it's easy to find with intellisense:
// src/assets/index.ts
export { default as IconMarkerDuotone } from './icons/marker-duotone';
// ... Do the same for the other icons here
Using your Icons
🥳 Congrats, you've added your icons! It's as easy as doing this now:
// You can even customize the size of your icon or add classes to it.
<IconMarkerDuotone width="35" height="35" className="text-blue-500 />
BONUS: Just save them as .svg
files.
There's a much easier way by taking advantage of Vite Plugins. Unfortunately, this only works for React (vite-plugin-svgr) and SolidJS (vite-plugin-solid-svg). But this way, you can store your icons like so:
- src
- assets
- icons
- index.ts
- marker-duotone.svg
- *.svg # All your other icons.
Use .svg
-only with SolidJS
- Install
vite-plugin-solid-svg
. - Add it to your
vite.config.ts
file.
// vite.config.ts
import { defineConfig } from 'vite';
import solidSvg from 'vite-plugin-solid-svg';
export default defineConfig({
plugins: [solidSvg()],
});
- Usually,
.svg
imports are 'string' types, not JSX. To fix this, add this totsconfig.json
:
// tsconfig.json
{
"compilerOptions": {
// ...
"types": [
"vite-plugin-solid-svg/types-component-solid", // Make sure this is above "vite/client"
"vite/client", // Replaces `/// <reference types="vite/client" />` in vite-env.d.ts. Make sure that is removed.
],
},
}
- In your
assets/index.ts
file, you can import the.svg
this way:
// src/assets/index.ts
import { default as IconMarkerDuotone } from './icons/marker-duotone.svg';
Use .svg
-only with React
- Install
vite-plugin-svgr
. - Add it to your
vite.config.ts
file.
// vite.config.ts
import { defineConfig } from 'vite';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
plugins: [svgr()],
});
- Usually,
.svg
imports are 'string' types, not JSX. To fix this, add this totsconfig.json
:
// tsconfig.json
{
"compilerOptions": {
// ...
"types": [
"vite-plugin-svgr/client", // Make sure this is above "vite/client"
"vite/client", // Replaces `/// <reference types="vite/client" />` in vite-env.d.ts. Make sure that is removed.
],
},
}
- In your
assets/index.ts
file, you can import the.svg
this way:
// src/assets/index.ts
import { default as IconMarkerDuotone } from './icons/marker-duotone.svg?react';
You've reached the end!**** Thanks for reading! 🥳