norns

Pug pitfalls

Template lines that Pug parses differently from what a Svelte author expects.

Do not write Write Why
{@html foo} as a top-level Pug line | {@html foo} Pug parses a leading { as a malformed tag; the pipe emits the line as text
#{expr} in text {expr} Pug interpolation runs at preprocess time with no runtime data in scope, and SSR fails with a 500
attr="#{expr}" attr!="{expr}" same reason; != is Pug's unescaped attribute, which Svelte then reads as an expression
+each('row of rows') +each('rows as row'), optionally +each('rows as row (row.id)') the of form is copied verbatim into the Svelte block and the compiler rejects it
a .a.b chain or {expr} split across a line break one element per line Pug is line-oriented; the parse error surfaces on the next line

#Template syntax that works

  • +if('cond') / +elseif('cond') / +else, nested to any depth.
  • +each('items as item (item.id)').
  • +snippet('name', arg) to define, | {@render name(x)} to render.
  • attr!="{expr}" for Svelte expressions; bind:value!="{x}"; onclick!="{handler}".
  • .a.b class shorthand, including Tailwind variants and fractions like .hover:bg-x.gap-2.5, which norns-core rewrites for you.
  • svelte:head as a tag, with title, meta(...) and link(...) children.
  • Components as tags: Btn(variant="primary" href="/x") Save.

See the norns-core Pug template and control flow pages for the details.