Pick one of several branches on a single value, with #switch(…) {#, #case …:# and #break#.
A deployment list where each row renders a badge chosen from its status. A chain of else if would work; a switch says more plainly that these are the alternatives for one value.
<style>
body { font: 14px/1.5 system-ui, sans-serif; margin: 0; color: #24292f; }
ul { list-style: none; padding: 0; margin: 0; }
li { display: flex; align-items: center; gap: 10px; padding: 7px 0;
border-bottom: 1px solid #eaeef2; }
li:last-child { border-bottom: 0; }
code { font-size: 13px; min-width: 11em; }
.badge { font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 20px; }
.ok { background: #dafbe1; color: #1a7f37; }
.run { background: #fff8c5; color: #7d4e00; }
.bad { background: #ffebe9; color: #cf222e; }
.unk { background: #f6f8fa; color: #57606a; }
.when { margin-left: auto; color: #8c959f; font-size: 12px; }
</style>
<script type="text/template" id="deploys">
<ul>
#for(let d of deployments) {#
<li>
<code>#d.service#</code>
#switch(d.status) {#
#case 'success':#
<span class="badge ok">Deployed</span>
#break#
#case 'running':#
<span class="badge run">In progress</span>
#break#
#case 'failed':#
<span class="badge bad">Failed</span>
#break#
#default:#
<span class="badge unk">#d.status#</span>
#}#
<span class="when">#d.finished#</span>
</li>
#}#
</ul>
</script>
<div id="output"></div>
<script src="https://cdn.jsdelivr.net/gh/richdafunk/hashJS@v1.3.6/hashJS.js"></script>
<script>
const data = {
deployments: [
{ service: 'api-gateway', status: 'success', finished: '2 min ago' },
{ service: 'auth', status: 'running', finished: 'started 40 s ago' },
{ service: 'image-resize', status: 'failed', finished: '11 min ago' },
{ service: 'search', status: 'queued', finished: '—' }
]
};
new hashJS('deploys', data, 'output');
</script> Every part is a separate tag: #case 'success':# opens a clause, #break# closes it, and #default:# catches the rest. Fall-through behaves as it does everywhere else in JavaScript — leave out a #break# and the next clause runs too.
The default branch prints #d.status# rather than the word unknown, so a status nobody planned for still says what it was.
Until version 1.3.6 the opening tag and the first #case# had to sit on the same line, because the newline between them compiled to a statement in a position a switch body does not allow. That whitespace is now dropped and a switch can be indented like any other block.