# Frame

> `Frame(html)` shows a whole HTML document inside the page, in a frame of its own — what a mail preview is. The document is sandboxed whatever it contains: it runs no script, has an origin of its own, submits no form and opens nothing, so HTML carrying a customer's data can be shown safely on a page a member of staff is signed in to.

<!-- id: ui-frame · area: ui · stability: stable · html: https://osysharp.com/reference/ui/frame/ -->

## Summary        {#summary}
Some things an app shows are documents in their own right — a rendered mail above all, with its own `<html>`, its
own `<body>` and every style inline. Dropped into the page they would restyle it and be restyled by it. `Frame`
shows such a document beside everything else, looking exactly as it will look where it is going:

```osy syntax
var mail = OrderConfirmation(order);                 // an [Email] template's RenderedEmail
Frame(mail.Html, title: "Preview of the order confirmation", h: 720);
```

## Signature      {#signature}
```osy syntax
Frame(string html, title: string, <style props>)   // w / h / borderW / border / rounded … size and frame it
```

`html` is the document itself — not an address. `title` names the frame for a screen reader, which announces it as a
region of its own; always give one.

## Description    {#description}

### It is sandboxed, whatever the document says   {#sandbox}
Every `Frame` carries an empty `sandbox` and `referrerpolicy="no-referrer"`, on the server's first paint and in the
browser alike. So the document it shows:

- **runs no script** — a `<script>` inside it is inert;
- **has an origin of its own** — it cannot read the app's cookies or storage, or reach the page around it;
- **submits no form, opens no window and navigates nothing** outside itself;
- **sends no referrer** — a picture it loads does not learn which page of the app showed it.

There is no setting to relax any of that. It is what makes it safe to show HTML that carries data somebody typed —
a customer's name in a mail — inside a page a member of staff is signed in to.

### Size it   {#size}
A frame is as wide as its container and 320 pixels tall until told otherwise. Give it the height the document needs
with `h:` — a mail preview reads well at 700–900 — and a border with `borderW:` / `border:` / `rounded:`, like any
box.

## Examples       {#examples}

### A mail, previewed on a staff page   {#example-preview}
```osy title="render a mail for a real row and show it in a frame" test app=ui-frame
entity Order {
  [MaxLength(40)] string Reference;
  security { allow read when IsAuthenticated; }
}

[Email]
component Confirmation(Order order) {
  subject => $"Your order {order.Reference}";
  render {
    Box(bg: "#F6F7F9", p: 6) {
      Text($"Thank you — order {order.Reference} is reserved for you.", fontSize: 20, fontWeight: 700);
    }
  }
}

string PreviewHtml(Guid orderId) {
  var order = Order.Single(o => o.Id == orderId);
  return Confirmation(order).Html;
}

[Route("/preview/{id}")]
[Title("Preview")]
component PreviewPage(Guid id) {
  string html = "";
  on mount { html = PreviewHtml(id); }
  render {
    Stack(gap: 3, p: 6) {
      Text("What the customer gets", fontWeight: 600);
      if (html != "") { Frame(html, title: "Preview of the order confirmation", h: 720, borderW: 1, rounded: 8); }
    }
  }
}
```

## See also       {#see-also}
- [[Email] — mail rendered from data](https://osysharp.com/reference/ui/email/) — the `[Email]` templates whose rendered HTML a frame previews.
- [The EmailTemplates kit — mail that looks designed](https://osysharp.com/reference/ui/email-templates-kit/) — the parts a designed mail is built from.
- [Markdown — rendering markdown text](https://osysharp.com/reference/ui/markdown/) — formatted text that belongs IN the page, rather than a document beside it.
