<Show/>Renders its children when when is truthy, else a fallback. For
reactivity, pass when as a reader (flag.read) or a function —
static values short-circuit and never re-evaluate. If children is a
callback, it receives a read-only signal (a memo) carrying
the current truthy value, so you can keep reading fresh values without
tearing down the tree.
For several mutually-exclusive branches reach for
<Switch/> instead.
| name | type | description |
|---|---|---|
when |
any | once when is truthy, render the children |
fallback? |
any | rendered when the condition is falsy |
Show mounts its children when when is truthy and fallback
otherwise. Pass the reader (visible.read) so the condition stays
reactive — visible.read() would be a one-time snapshot.
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const visible = signal(true)
return (
<div>
<button on:click={() => visible.update(v => !v)}>toggle</button>
<Show
when={visible.read}
fallback={<p>hidden</p>}
>
<p>hello</p>
</Show>
</div>
)
}
render(App)
When when is truthy, Show invokes the children function with a
reactive accessor for the value — useful when downstream code needs
the value (and TypeScript knows it is non-null inside the branch).
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const user = signal(null)
return (
<div>
<button on:click={() => user.write({ name: 'Ada' })}>
log in
</button>
<button on:click={() => user.write(null)}>log out</button>
<Show
when={user.read}
fallback={<p>not logged in</p>}
>
{u => <p>welcome, {() => u().name}</p>}
</Show>
</div>
)
}
render(App)
Show is the natural primitive for "render this only when the user is
authenticated, else fall back". Combining it with
<Navigate/> turns the fallback into a
redirect — no inline conditionals, the intent reads top-to-bottom.
import { render, signal } from 'pota'
import { Navigate, Route, Show } from 'pota/components'
function App() {
const user = signal(null)
return (
<div>
<button on:click={() => user.write({ name: 'Ada' })}>
log in as Ada
</button>
<button on:click={() => user.write(null)}>log out</button>
<Route path="/dashboard">
<Show
when={user.read}
fallback={
<Navigate
path="/login"
replace
/>
}
>
{u => <p>welcome, {() => u().name}</p>}
</Show>
</Route>
<Route path="/login">
<p>please log in</p>
</Route>
</div>
)
}
render(App)
A static (non-function) when short-circuits: the branch is decided
once and never re-evaluates.
import { render } from 'pota'
import { Show } from 'pota/components'
function App() {
return (
<>
<Show when={true}>Should show this text!</Show>
<Show when={false}>Nope!</Show>
<span> - the end</span>
</>
)
}
render(App)
Passing the reader (showing.read) keeps Show reactive; passing the
read value (showing.read()) takes a one-time snapshot that never
updates.
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const showing = signal(true)
return (
<div>
<button on:click={() => showing.update(v => !v)}>toggle</button>
<Show when={showing.read}>This is reactive</Show> -{' '}
<Show when={showing.read()}>This is not reactive</Show>
</div>
)
}
render(App)
When children is a function it receives a read-only signal carrying
the current when value. Read it with value(), or wrap it as
{() => …} to derive reactive content from it.
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const score = signal(0.2)
return (
<div>
<button on:click={() => score.write(Math.random())}>
roll
</button>
<Show when={score.read}>
{value => (
<>
<div>The value is: {value}</div>
<div>
Is the value above .5? {() => String(value() > 0.5)}
</div>
</>
)}
</Show>
</div>
)
}
render(App)
Wrapping a component in resolve memoizes the result, so
the component is created once and reused across toggles instead of
being re-rendered each time Show swaps back in.
import { render, resolve, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const showing = signal(true)
let rendered = 0
function CountRenders() {
rendered++
return <span>This component rendered {rendered} times</span>
}
const Test = resolve(() => CountRenders)
return (
<div>
<button on:click={() => showing.update(v => !v)}>toggle</button>
<Show when={showing.read}>
<Test />
</Show>
</div>
)
}
render(App)
A fallback renders when the condition becomes falsy. It is
instantiated only while shown and disposed when the condition turns
truthy again.
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const showing = signal(true)
return (
<div>
<button on:click={() => showing.update(v => !v)}>toggle</button>
<Show
when={showing.read}
fallback={<p>nothing here</p>}
>
Hey
</Show>
</div>
)
}
render(App)
Show keeps its position between sibling elements and between text
nodes — toggling it does not disturb the surrounding markup.
import { render, signal } from 'pota'
import { Show } from 'pota/components'
function App() {
const showing = signal(true)
return (
<div>
<button on:click={() => showing.update(v => !v)}>toggle</button>
<div>
<span>1</span>
<Show when={showing.read}>
<span>2</span>
</Show>
<span>3</span>
</div>
<div>
1<Show when={showing.read}>2</Show>3
</div>
</div>
)
}
render(App)