Skip to main content
Content can be conditionally rendered using {#if} blocks, which allow you to show or hide markup based on expressions.

Basic If Block

The simplest form renders content only when a condition is true:
{#if expression}...{/if}

Example

{#if answer === 42}
  <p>what was the question?</p>
{/if}

If-Else Blocks

Add an {:else} clause for content to show when the condition is false:
{#if expression}...{:else}...{/if}

Example

{#if user.loggedIn}
  <button onclick={logout}>Log out</button>
{:else}
  <button onclick={login}>Log in</button>
{/if}

Else-If Chains

Test multiple conditions with {:else if} clauses:
{#if expression}...{:else if expression}...{/if}

Example

{#if porridge.temperature > 100}
  <p>too hot!</p>
{:else if 80 > porridge.temperature}
  <p>too cold!</p>
{:else}
  <p>just right!</p>
{/if}

Real-World Use Cases

User Authentication

{#if user}
  <div class="profile">
    <img src={user.avatar} alt="{user.name}" />
    <span>Welcome, {user.name}</span>
  </div>
{:else}
  <a href="/login">Sign in</a>
{/if}

Loading States

{#if loading}
  <Spinner />
{:else if error}
  <ErrorMessage {error} />
{:else}
  <DataTable data={results} />
{/if}

Feature Flags

{#if features.darkMode}
  <button onclick={toggleDarkMode}>
    Switch to light mode
  </button>
{/if}

Permission Checks

{#if user.role === 'admin'}
  <AdminPanel />
{:else if user.role === 'moderator'}
  <ModeratorPanel />
{:else}
  <UserPanel />
{/if}

Inline Conditionals

Blocks don’t have to wrap elements - they can wrap text within elements:
<p>
  You have {count} {#if count === 1}item{:else}items{/if} in your cart.
</p>

Nested If Blocks

You can nest if blocks for complex conditions:
{#if user}
  {#if user.subscription === 'premium'}
    <PremiumFeatures />
  {:else}
    <StandardFeatures />
    {#if user.trialEligible}
      <TrialOffer />
    {/if}
  {/if}
{:else}
  <SignUpPrompt />
{/if}

Common Patterns

Show/Hide Toggle

<script>
  let showDetails = $state(false);
</script>

<button onclick={() => showDetails = !showDetails}>
  {showDetails ? 'Hide' : 'Show'} details
</button>

{#if showDetails}
  <div class="details">
    <p>Additional information here...</p>
  </div>
{/if}

Empty State

{#if items.length > 0}
  <ul>
    {#each items as item}
      <li>{item.name}</li>
    {/each}
  </ul>
{:else}
  <p class="empty-state">No items found</p>
{/if}

Status Indicators

{#if status === 'success'}
  <div class="alert success">Operation completed!</div>
{:else if status === 'error'}
  <div class="alert error">Something went wrong</div>
{:else if status === 'warning'}
  <div class="alert warning">Please review</div>
{/if}
Avoid too many nested if blocks as they can make templates hard to read. Consider extracting complex logic into separate components or computed values.

Performance Notes

Svelte efficiently updates the DOM when conditions change:
  • Only the affected parts of the DOM are updated
  • Elements inside false conditions are removed from the DOM
  • When conditions become true, elements are created fresh
<script>
  let show = $state(true);
  
  // This will re-run when show changes
  $effect(() => {
    console.log('Component mounted:', show);
  });
</script>

{#if show}
  <ExpensiveComponent />
{/if}