Skip to main content
Markup inside a Svelte component can be thought of as HTML++. You can use standard HTML elements alongside dynamic expressions and special Svelte features.

HTML Tags

Svelte distinguishes between regular HTML elements and components based on naming:
  • Lowercase tags like <div> denote regular HTML elements
  • Capitalized tags or dot notation like <Widget> or <my.stuff> indicate components
<script>
  import Widget from './Widget.svelte';
</script>

<div>
  <Widget />
</div>

Element Attributes

Attributes work like their HTML counterparts, but with powerful enhancements for dynamic values.

Static Attributes

<div class="foo">
  <button disabled>can't touch this</button>
</div>
Values may be unquoted:
<input type=checkbox />

Dynamic Attributes

Attribute values can contain JavaScript expressions:
<a href="page/{p}">page {p}</a>
Or they can be JavaScript expressions:
<button disabled={!clickable}>...</button>

Boolean and Nullish Attributes

Boolean Attributes

Included if truthy, excluded if falsy
<input required={false} placeholder="Not required" />

Other Attributes

Included unless nullish (null or undefined)
<div title={null}>No title attribute</div>

Attribute Shorthand

When attribute name and value match, use shorthand syntax:
<button {disabled}>...</button>
<!-- equivalent to -->
<button disabled={disabled}>...</button>

Component Props

Values passed to components are called props (not attributes):
<Widget foo={bar} answer={42} text="hello" />
Shorthand syntax works for props too:
<Widget {foo} {bar} />

Spread Attributes

Pass multiple attributes or props at once using spread syntax:
<Widget a="b" {...things} c="d" />
Order matters! Later attributes override earlier ones. In the example above, if things.a exists it overrides a="b", while c="d" overrides things.c.

Text Expressions

Embed JavaScript expressions in text using curly braces:
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}</p>

Expression Behavior

  • null or undefined values are omitted
  • All other values are coerced to strings
  • Regular expressions need parentheses:
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>

Rendering HTML

Expressions are escaped by default. To render HTML, use the {@html} tag:
{@html potentiallyUnsafeHtmlString}
Always escape user-provided strings or use trusted values to prevent XSS attacks.

Comments

Use HTML comments inside components:
<!-- this is a comment! -->
<h1>Hello world</h1>

Disabling Warnings

Comments starting with svelte-ignore disable warnings for the next markup block:
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />

Component Documentation

Add @component comments to show documentation when hovering over component usage:
<!--
@component
- You can use markdown here
- Usage:
  ```html
  <Main name="Arethra" />
—>

## Special Characters

Include curly braces in templates using HTML entities:

- `{` can be written as `&lbrace;`, `&lcub;`, or `&#123;`
- `}` can be written as `&rbrace;`, `&rcub;`, or `&#125;`

## Real-World Example

Here's a complete example combining multiple features:

```svelte
<script>
  let name = $state('World');
  let count = $state(0);
  let isActive = $state(true);
</script>

<div class="container" class:active={isActive}>
  <h1>Hello {name}!</h1>
  
  <!-- Dynamic attribute -->
  <button disabled={count >= 10} onclick={() => count++}>
    Clicked {count} times
  </button>
  
  <!-- Attribute shorthand -->
  <input bind:value={name} placeholder="Enter your name" />
</div>