Show

<show> renders its children when a condition is truthy, and its fallback when it is not.

<Show> is the same component.

source
<script>
let user = { name: 'Alice' }
</script>

<show when={user}>
  <p>Welcome, {user.name}!</p>
</show>
output

Welcome, Alice!

Fallback

fallback is markup, and it is mounted like any other markup - so components inside it work.

What it is not is a template. The compiler never walks a <show> fallback, so an expression in one is a build error naming the fallback rather than three characters of text on screen: fallback="{message}" stops the build.

When the empty case has to react to state, give it a branch of its own - a Switch arm, or a second <show> with the negated condition. A For fallback is the exception in the family: its expressions are compiled.

<script>
let user = null

function toggle() {
  user = user ? null : { name: 'Alice' }
}
</script>

<button onclick="toggle()">Log {user ? 'out' : 'in'}</button>

<show when={user} fallback="<p>Nobody is logged in.</p>">
  <p>Welcome, {user.name}!</p>
</show>
output

Nobody is logged in.

Props

Prop Type Description
when any The condition. Plain JavaScript truthiness.
fallback string Literal markup to mount when when is falsy. An expression in it is a build error.
keyed boolean Rebuild the children whenever when changes reference, not just when it changes truthiness.

keyed

Without keyed, switching from one truthy value to another leaves the children in place and lets their bindings update.

With keyed, the children are destroyed and rebuilt - use it when a child holds state that must not survive the swap.

source
<show when={selectedItem} keyed>
  <ItemDetail item={selectedItem} />
</show>

When to Use It

For a plain either/or, a ternary or && in the markup is shorter:

source
{loggedIn ? <Dashboard /> : <Login />}

{error && <p class="error">{error.message}</p>}

Reach for <show> when the branch is a block of markup rather than one element, or when you want keyed.

For three or more branches use Switch.

A falsy <show> unmounts its children. They are removed from the document, not hidden, and turning the condition back on builds fresh nodes. Typed text, scroll position, focus and child component state are all lost on every toggle.

Hide with CSS when that state has to survive.

when={0} and when="" are falsy, so they take the fallback. when={[]} is truthy - an empty array still renders the children.

A <show> arm has no wrapper element. It is inserted at a comment anchor, so a <show> inside a flex or grid parent puts its own content into that parent.

Alpha code often carries [data-jaf-component="Show"] { display: contents } for the <div> that used to be there. Delete it - it matches nothing now.

A <show> body is your own markup. Handlers, bind: write-back, class:, style: and use: all resolve against the component that wrote it, modifiers included. ref: is the one refusal: the element does not exist until the arm mounts, so the compiler declines to promise when it appears.