Skip to content

Attribute metadata

Svelte’s customElement.props option controls attribute names, conversion, and property reflection. @svebcomponents/auto-options derives that option from $props() types.

<svelte:options customElement="filter-panel" />
<script lang="ts">
import type { RemoteData } from "./data.js";
interface Props {
label: string;
pageSize: number;
active: boolean;
tags: string[];
settings: { compact: boolean };
data: RemoteData;
}
let { label, pageSize, active, tags, settings, data }: Props = $props();
</script>

Before Svelte compiles the component, auto-options expands the string tag and adds metadata for each prop it can map to an attribute:

<svelte:options
customElement={{
tag: "filter-panel",
props: {
label: { attribute: "label", reflect: true, type: "String" },
pageSize: {
attribute: "page-size",
reflect: true,
type: "Number",
},
active: { attribute: "active", reflect: true, type: "Boolean" },
tags: { attribute: "tags", reflect: false, type: "Array" },
settings: { attribute: "settings", reflect: false, type: "Object" },
data: { attribute: "data", reflect: false, type: "String" },
},
}}
/>

Svelte converts page-size="42" to the number 42. Svelte reflects a new scalar property value to its attribute after component code changes it. Arrays, objects, and unresolved references do not reflect because reflection would serialize them into markup.

Prop declarationSvelte converterReflects
string or a string literal"String"Yes
number or a number literal"Number"Yes
boolean or a boolean literal"Boolean"Yes
T[] or Array<T>"Array"No
Object literal, Record, interface"Object"No
Imported or unresolved type"String"No
Untyped destructured prop"String"Yes
Function or Svelte snippetNo attributeNo

auto-options converts attribute names to kebab case, so favoriteNumber becomes favorite-number.

Values in <svelte:options> take precedence over inferred values:

<svelte:options
customElement={{
tag: "filter-panel",
props: {
pageSize: {
type: "Number",
attribute: "data-page-size",
reflect: false,
},
},
}}
/>

auto-options keeps the fields you supply and fills the missing prop entries. Read the @svebcomponents/auto-options reference for plugin setup and supported TypeScript shapes.