> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pdfdyno.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Typst for Web Developers

> A 3-minute crash course to translate your HTML/CSS skills into Typst.

Typst is extremely powerful, but its syntax might feel unfamiliar to frontend developers at first glance. Don't panic: If you know HTML, CSS (Flexbox/Grid), and JavaScript, you will love Typst.

In PDFDyno, you receive your dynamic data via the `data` field in your JSON request. The backend automatically injects this data into your template as a `#data` variable.

Here is how you translate the most important web concepts:

## 1. Rendering Variables from JSON (like JSX)

Instead of using `{data.name}` like in React/JSX, Typst uses a `#` to evaluate logic and variables.

<CodeGroup>
  ```json data.json theme={null}
  {
    "user": {
      "firstName": "Valentin",
      "role": "Admin"
    }
  }
  ```

  ```typst template.typ theme={null}

  // The # prefix evaluates the variable:
  Welcome back, #data.user.firstName!
  Your role is: #data.user.role
  ```
</CodeGroup>

## 2. Layouts: Flexbox and CSS Grid

Typst completely drops the concept of `<div style="display: flex">`. Instead, you use native functions like `#grid()` or `#stack()`.

### Columns side-by-side (CSS Grid / Flex-Row)

If you want to place two elements next to each other (e.g., billing address and date), use `#grid`.

```typst template.typ theme={null}
// Equivalent to CSS: display: grid; grid-template-columns: 1fr 1fr;
#grid(
  columns: (1fr, 1fr),
  gutter: 20pt, // gap: 20px
  
  // Left column
  [
    *Billing Address:* \
    Max Mustermann \
    Berlin
  ],
  
  // Right column (right-aligned)
  align(right)[
    *Invoice Date:* \
    October 12, 2026
  ]
)
```

### Elements stacked vertically (Flex-Col with Gap)

```typst template.typ theme={null}
// Equivalent to CSS: display: flex; flex-direction: column; gap: 10px;
#stack(
  dir: ttb, // top-to-bottom
  spacing: 10pt,
  [Element 1],
  [Element 2],
  [Element 3]
)
```

## 3. Iterating over Arrays (`.map` in JS)

You have an array of invoice items in your JSON and want to render them in a table. Typst supports `for` loops and the `.map()` function on arrays.

<CodeGroup>
  ```json data.json theme={null}
  {
    "items": [
      { "name": "API Requests", "price": "10.00" },
      { "name": "Server Hosting", "price": "50.00" }
    ]
  }
  ```

  ```typst template.typ theme={null}

  #table(
    columns: (1fr, auto), // 1st column takes remaining space, 2nd is auto-sized
    
    // Header
    [*Product*], [*Price*],
    
    // Iterate over the array and flatten the output
    ..data.items.map(item => (
      item.name,
      item.price
    )).flatten()
  )
  ```
</CodeGroup>

## 4. Basic Styling (CSS -> Typst)

Styling in Typst is applied either globally via `#set` or locally as a function like `#text()`.

```typst template.typ theme={null}
// Global setup (Equivalent to styling the <body>)
#set text(font: "Helvetica", size: 11pt, fill: rgb("#111827"))
#set page(margin: 2cm)

// Local inline styling (Equivalent to <span style="...">)
#text(size: 24pt, weight: "bold", fill: rgb("#7c3aed"))[This is a colored headline]

// Spacing (Equivalent to margin-bottom / padding-bottom)
This is some text.
#v(20pt) // Vertical Space = 20pt
And this comes right below.
```

## 5. Common Pitfalls

When coming from HTML, there are a few Typst-specific quirks you need to watch out for.

### Escaping `@` and `#`

Typst uses `#` for logic and `@` for references/citations. If you need to print a literal `@` (e.g., in an email address) or `#` (e.g., for a hashtag), you must escape them with a backslash.

```typst theme={null}
Contact us at hello\@pdfdyno.com or use the hashtag \#pdfdyno.
```

### Umlauts and Special Characters in JSON

Ensure your JSON strings are properly UTF-8 encoded. Typst handles Unicode perfectly, but if your JSON parser sends malformed encoding (e.g., `MÃ¼ller` instead of `Müller`), the PDF will render exactly that.

```typst theme={null}
// Do this once at the top:
```

## 6. Common Developer Questions

### How do I force a page break?

Typst automatically handles pagination, but if you want to explicitly start a new page (e.g., before an appendix or a new section in a report), simply use `#pagebreak()`.

```typst theme={null}
This is the end of chapter 1.
#pagebreak()
= Chapter 2
```
