Typst Guide

Typst Show Rules

#show is how you customize ANY element in Typst. Heading styling, figure layouts, link colors, table rendering — all one mechanism.

The pattern

#show <selector>: <transformation>

// Transformation can be a single function:
#show heading: set text(weight: "bold", size: 14pt)

// Or a function that takes the element and returns content:
#show heading: it => {
  v(1em)
  text(weight: "bold", size: 14pt, fill: blue, it.body)
  v(0.5em)
}

Common patterns

Chapter on new page

#show heading.where(level: 1): it => {
  pagebreak(weak: true)
  v(2em)
  text(size: 24pt, weight: "bold", it.body)
  v(1em)
}

Caption above figures (instead of below)

#show figure: it => {
  block(breakable: false)[
    #it.caption
    #it.body
  ]
}

Style links

#show link: set text(fill: rgb("#1A73E8"))

// Or with underline
#show link: it => underline(text(fill: rgb("#1A73E8"), it))

Custom citation rendering

// Make citations show in red (for visual debugging)
#show cite: set text(fill: red)

// Or wrap in brackets manually
#show cite: it => [(#it)]

Number raw code blocks

#show raw.where(block: true): it => {
  block(
    fill: luma(240),
    inset: 8pt,
    radius: 4pt,
    it,
  )
}

#set vs #show — when to use which

Use caseUse
Set heading numbering format#set
Make all headings bold#set or #show
Add page break before each chapter#show
Reorder figure caption + body#show
Set default page size#set
Wrap raw blocks in colored boxes#show

Rule of thumb: #set for parameter values, #show for transforming the element's rendering.

Try Typst with custom show rules

TypeTeX is a free in-browser Typst editor — write a show rule, see it apply across your document instantly.

Try TypeTeX free

Frequently Asked Questions

What's the difference between #set and #show in Typst?

#set changes the default values of an element type's parameters: #set heading(numbering: "1.") makes all headings numbered. #show is more powerful — it transforms how an element renders by passing it through a function: #show heading: it => { v(1em); text(weight: "bold", it.body) }. Use #set for parameter changes, #show for layout/structural changes.

How do I target only level-1 headings?

Use .where() to filter: #show heading.where(level: 1): it => { ... }. Other levels are unchanged. You can chain conditions: heading.where(level: 1, numbering: "1.").

How do I make every chapter start on a new page?

#show heading.where(level: 1): it => { pagebreak(weak: true); it }. The 'weak: true' avoids inserting an extra page if we're already at the start of one. Place this rule once at the top of your document; every level-1 heading will trigger.

How do I customize figure layouts?

#show figure: it => { ... }. Inside, you can re-arrange the figure's components: it.body (the content), it.caption (the caption), it.numbering. For example, to put captions above figures: #show figure: it => block[#it.caption #it.body].

How do I style links globally?

#show link: set text(fill: rgb("#1A73E8")). This applies a text color to all link content. Combine with underline or other formatting: #show link: it => underline(text(fill: blue, it)).

Can I make multiple show rules?

Yes. Stack them: #show heading.where(level: 1): ..., #show heading.where(level: 2): ..., #show figure: ..., etc. Each rule applies to matching elements. Order matters when rules could compete; later rules can override earlier ones.

How do show rules work with templates?

Templates package up #show + #set rules into reusable functions. #import "@preview/template:1.0": * imports a template, then #show: template.with(...) applies all its rules to your document. Most academic templates expose configuration as named parameters of the .with() call.

Can I conditionally apply show rules?

Yes. Use #if conditions outside the #show definition: #if mode == "thesis" { show heading.where(level: 1): chapter-style }. Or inside the rule's body: #show heading: it => if it.level == 1 { ... } else { ... }.

What does the 'it' variable mean in show rules?

'it' is the matched element being styled. For a heading, it.body is the heading text, it.level is 1/2/3, it.numbering is the number. The function in the show rule receives 'it' and returns the rendered version. Think of it as a transformer: input element → output styled content.

More Typst guides