How to vue 3 and svelte svg component output: complete format reference
- Step 1Read the leading banner — Every output starts with
<!-- Generated component: NAME -->, where NAME is yourcomponentName(or the file stem). It's a marker only — not a Vue/Svelte directive — so it's safe to keep or delete. For Vue, the NAME is the kebab-cased base used for the suggested.vuefilename. - Step 2Identify the wrapper layout — Vue:
<template>containing your SVG, then<script setup>(withlang="ts"if TypeScript is on). Svelte: a<script>block first, then your SVG as bare markup. Neither output includes a<style>block. - Step 3Enumerate the props — Vue declares
size,color,class; Svelte declaressize,color,className. Defaults:24,currentColor, empty string. These are the only props — there is noaria-label,title,width,height, or slot prop. - Step 4Check the TypeScript form — TS on (default): Vue
defineProps<{ size?: number | string; color?: string; class?: string }>(); Svelte typedexport letdeclarations. TS off: Vue runtimedefineProps({ size: { type: [Number, String], default: 24 }, ... }); Svelte untypedexport let size = 24. - Step 5Confirm what's preserved vs changed — Your SVG markup is inserted verbatim — every attribute, gradient, filter, and path survives. The only transformations are comment removal and a trim. Unlike the React converter, no attribute is renamed (
classstaysclass,stroke-widthstaysstroke-width). - Step 6Plan the manual bindings — Because
size/colorare declared but unbound, decide how you'll wire them: Vue:width="size"/:stroke="color", Sveltewidth={size}/stroke={color}.class(Vue) works via fallthrough;className(Svelte) needsclass={className}. Add these after generation.
Field-by-field output reference
Every structural element of the generated component, for both frameworks. 'Verbatim' means inserted exactly as in your input SVG.
| Element | Vue 3 | Svelte |
|---|---|---|
| Leading banner | <!-- Generated component: NAME --> | <!-- Generated component: NAME --> |
| SVG location | Inside <template>, verbatim | After the <script>, verbatim |
| Script block | <script setup> (or <script lang="ts" setup>) | <script> (or <script lang="ts">) |
| Props | size, color, class via defineProps | size, color, className via export let |
| Prop defaults | 24 / currentColor / '' (JS mode runtime defaults) | 24 / currentColor / '' |
| Style block | None | None |
| Slots | None | None |
| ARIA props | None | None |
Preserved vs transformed vs omitted
What the converter touches and what it never touches. Compare with the React converter, which renames attributes.
| Item | This tool (Vue/Svelte) | Compare: svg-to-jsx (React) |
|---|---|---|
| Your SVG attributes | Preserved verbatim (class, stroke-width unchanged) | Renamed (class→className, stroke-width→strokeWidth) |
| Comments | Stripped | Stripped |
| Whitespace | Trimmed (outer) | Trimmed (outer) |
{...props} spread | Not added | Added to root <svg> |
| size/color binding | Not bound (declared only) | n/a (uses prop spread instead) |
| Exported types | None (inline defineProps) | Uses React.SVGProps<SVGSVGElement> |
Cookbook
Canonical outputs for each option combination, so you can match the exact shape you'll get.
Vue 3 + TypeScript (default)
framework: vue, typescript: true. Type-only defineProps; no runtime defaults declared (the ? makes them optional).
<!-- Generated component: icon -->
<template>
<svg viewBox="0 0 24 24" fill="#000">...</svg>
</template>
<script lang="ts" setup>
defineProps<{
size?: number | string
color?: string
class?: string
}>()
</script>Vue 3 + JavaScript
framework: vue, typescript: false. Runtime defineProps with explicit types and defaults instead of a TS generic.
<!-- Generated component: icon -->
<template>
<svg viewBox="0 0 24 24" fill="#000">...</svg>
</template>
<script setup>
defineProps({
size: { type: [Number, String], default: 24 },
color: { type: String, default: 'currentColor' },
class: { type: String, default: '' },
})
</script>Svelte + TypeScript
framework: svelte, typescript: true. Typed export let; note className (not class) and the markup after the script.
<!-- Generated component: icon --> <script lang="ts"> export let size: number | string = 24; export let color: string = 'currentColor'; export let className: string = ''; </script> <svg viewBox="0 0 24 24" fill="#000">...</svg>
Svelte + JavaScript
framework: svelte, typescript: false. Same shape, untyped export let with default values.
<!-- Generated component: icon --> <script> export let size = 24; export let color = 'currentColor'; export let className = ''; </script> <svg viewBox="0 0 24 24" fill="#000">...</svg>
The bindings you add to make props live
Reference for the manual step. The tool stops before this; here's the canonical wiring per framework.
Vue (edit the <template>):
<svg :width="size" :height="size"
:stroke="color" :fill="color">
(class works automatically via Vue fallthrough)
Svelte (edit the markup):
<svg width={size} height={size}
stroke={color} fill={color} class={className}>Edge cases and what actually happens
Expecting size/color to be pre-bound
Declared, not boundThe reference fact people miss most: size and color appear in the props but are never referenced in the markup. Your SVG's literal width/height/fill/stroke stay. The props are scaffolding; bind them yourself (see the bindings example).
Looking for an exported Props type to import
Not exportedVue uses an inline defineProps<{...}>() generic — there is no export interface Props. Svelte types props inline on each export let. If you want import type { Props }, declare the interface yourself and reference it in the generated file.
Expecting attribute conversion like the React tool
Preserved verbatimUnlike SVG to JSX, this converter does not rename attributes: class stays class, stroke-width stays stroke-width, xlink:href stays as-is. That's correct for Vue/Svelte (which accept HTML/SVG attribute names) but will not compile in React — use the JSX tool there.
Searching for a <style> block or scoped CSS
None emittedNeither output includes <style> or <style scoped>. Styling is via the class prop and CSS. If your conventions require a scoped style block, add it to the downloaded file — there is no option to generate one.
Expecting slots or named slots
Not generatedThe component has no <slot> (Vue) or <slot /> (Svelte). It renders exactly your SVG. Add slots manually if you need to inject decorations — though for a single icon, slots are rarely warranted.
Looking for an Advanced template-override field
No such optionThe UI exposes only framework, component name, and TypeScript. There is no field to paste a custom template with SVG/props placeholders. The wrapper shape is fixed; to change it, edit the output or post-process it in your build.
Svelte className prop seems to do nothing
Needs bindingSvelte reserves class in script, so the prop is className, and it's not bound to the markup. <Icon className="x"> is inert until you add class={className} to the <svg>. Vue's class differs — it works via attribute fallthrough without binding.
Banner comment treated as a directive
Harmless markerThe <!-- Generated component: NAME --> is a plain HTML comment, not a Vue/Svelte directive. It has no runtime effect and you can delete it. It exists so a pasted snippet self-identifies which component it maps to.
Multi-root SVG fragments
Preserved as-isThe tool wraps whatever you give it. If your input isn't a single <svg> root (e.g. a fragment), Vue's template and class fallthrough assume a single root element — a non-single-root template can break fallthrough. Provide a proper single <svg> root.
Frequently asked questions
What props does the default Vue component expose?
Exactly three: size (number | string), color (string), and class (string), via defineProps. Defaults are 24, currentColor, and empty. There is no aria-label, title, width, height, or slot prop. Note that size and color are declared but not bound to the SVG — you wire them yourself.
What props does the Svelte component expose?
size, color, and className via export let, with the same defaults (24, currentColor, empty). The styling prop is className, not class, because class is reserved in Svelte's script. As with Vue, the props are declared but not bound to the markup.
Does the converter rename my SVG attributes?
No. Your SVG is inserted verbatim — class stays class, stroke-width stays stroke-width, gradients and filters are untouched. Only comments are stripped and outer whitespace trimmed. This differs from SVG to JSX, which renames attributes to React's camelCase and adds a {...props} spread.
Does the Vue component use scoped styles?
No — there is no <style> block of any kind. Styling is meant to flow through the class prop (applied to the root SVG via Vue fallthrough) and CSS, which avoids specificity battles. Add a scoped style block to the file manually only if you specifically need one.
How is the Svelte output different from the Vue output?
Vue wraps the SVG in <template> and uses defineProps in <script setup>; Svelte puts a <script> block with export let first, then the SVG as bare markup. The styling prop is class in Vue (auto-applied via fallthrough) and className in Svelte (needs binding). Both declare the same size/color and neither binds them.
Is there a named Props type I can import?
No. Vue uses an inline defineProps<{...}>() generic with no exported interface; Svelte types each export let inline. If your code review expects import type { Props }, declare the interface yourself in the generated file.
Can I customise the component template the tool uses?
No. The wrapper is fixed (banner, <template>/<script setup> for Vue; <script> + markup for Svelte), and there is no Advanced field to paste a custom template with placeholders. To change the shell, edit the output or post-process it in your build pipeline.
What's preserved versus stripped from my SVG?
Preserved: the entire SVG body — every attribute, path, gradient, filter, mask, and <defs>. Stripped: HTML/XML comments (<!-- -->). Trimmed: surrounding whitespace. Nothing else is altered, so what you put in is what you get out (wrapped in the component shell).
Can I add click handlers to the generated component?
Not via an option — the tool emits no event handlers or forwarding. Add them yourself: in Vue, attach @click where you use the component (or in the SFC); in Svelte, forward with on:click on the element. There is no auto-generated handler surface.
Why is there a comment at the top of every file?
It's a <!-- Generated component: NAME --> marker so a pasted snippet self-identifies which component it represents and (for Vue) what the kebab-cased filename should be. It's a plain HTML comment with no runtime effect — keep it or delete it freely.
Does TypeScript mode change anything besides types?
It changes the script tag (lang="ts") and the prop declaration form. In Vue, TS uses a type-only defineProps<{...}>() (props optional via ?); JS uses runtime defineProps({...}) with explicit type/default. In Svelte, TS adds type annotations to each export let. The SVG markup is identical either way.
Does the output include width/height props or just size?
Just size — there are no separate width/height props. The intent is one size value you bind to both dimensions (:width="size" :height="size"). Since the tool doesn't bind it, your SVG's original width/height attributes remain until you wire size in yourself.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.