# `razor:preview`
> The fence that renders as a live example with Preview and Code tabs.
Source: https://shelldocs.shellui.dev/docs/authoring/razor-preview
A `razor:preview` fence renders its contents as live components and shows the same markup in a Code tab. You write the example once, as Razor, and the reader sees it running and can copy it.
## Basic use
````markdown
```razor:preview
This renders as a real Callout component.
```
````
```razor
This renders as a real Callout component.
```
The tags can be components registered with ShellDocs : the built-in primitives, or [your own](https://shelldocs.shellui.dev/docs/guides/component-libraries.md). A fence of plain HTML renders live too:
```razor
A fence with only HTML and no component.
```
A fence with no tags at all stays a code block, and a warning is logged. Before `0.1.17-alpha` an HTML-only fence also rendered as a code block.
## The body is Razor, not markdown
Everything inside the fence is parsed as Razor markup, so the Code tab shows exactly what belongs in a `.razor` file. Elements wrap nested components as written and no text is wrapped in a paragraph.
Markdown syntax inside a fence renders literally. Use HTML for inline formatting:
```razor
Run shelldocs dev, then open /docs/introduction.
```
> **Markdown bodies live in the page, not the fence**
>
> A component tag written straight into the page takes a markdown body. See [Inline component tags](https://shelldocs.shellui.dev/docs/authoring/component-tags.md).
## Several components and wrapper elements
A fence can hold any number of top-level tags. They render in order inside one frame.
```razor
Two components in one fence.Rendered in order.
```
Plain HTML wrappers work too, which is how you lay an example out:
```razor
```
## Named slots
A direct child tag whose name matches one of the component's `RenderFragment` parameters goes into that slot. Everything else becomes `ChildContent`.
```razor
Body text.
```
Here `Icon` and `Footer` fill `Alert.Icon` and `Alert.Footer`, and the loose text fills `Alert.ChildContent`. This is what lets a fence preview composed components such as dialogs, cards with headers, and tab lists.
## Attribute values
Attributes are written as in Razor and converted to each parameter's type.
| Written as | Parameter type | Result |
|---|---|---|
| `Columns="3"` or `Columns="@3"` | `int` | `3` |
| `External="true"` or `External="@true"` | `bool` | `true` |
| `Variant="Destructive"` | enum | Looked up by name, ignoring case |
| `Variant="ButtonVariant.Destructive"` | enum | The qualified form works too, with or without `@` |
| `Sides="Left \| Right"` | flags enum | Combined |
| `Href="/docs"` | `string` | Left as written |
Parameter names match without regard to case, as in Blazor.
Some attributes can't be applied from markdown: event callbacks (`OnClick="Save"`), `@bind-*`, `@ref`, `@onclick`, and values that can't be converted. They are skipped with a logged warning, the component still renders, and the Code tab still shows them. That keeps a realistic example copyable without breaking the page.
Lines that are not markup, such as `@code { }` blocks, `@* comments *@` and `@using` lines, are left out of the render and kept in the Code tab.
## Generic components
A generic component registers under its bare name. Close it with a type-parameter attribute, as in Razor:
```razor
```
Type arguments use C# spellings: `int?`, `List`, or a simple or full type name. Without one, `object` is used when the constraints allow it and a warning is logged. If the type can't be closed the frame shows an error instead of breaking the page.
## Layout
Add `stretch` or `scroll` after the language to change how the example sits in the frame.
````markdown
```razor:preview stretch
…
```
````
| Name | Type | Default | Description |
|------|------|---------|-------------|
| `razor:preview` | `center` | | Centred, sized to its content. The default. |
| `razor:preview stretch` | `stretch` | | Block-level components fill the frame. |
| `razor:preview scroll` | `scroll` | | A wide example scrolls inside the frame on small screens. |
More on each in [PreviewFrame](https://shelldocs.shellui.dev/docs/components/preview-frame.md).
## Unknown components
If no tag in the fence is a registered component, the frame shows an error panel that names the tag and how to register it. A warning is written to the log as well.
## When a fence isn't enough
| Name | Type | Default | Description |
|------|------|---------|-------------|
| `Needs a code block, state or a loop` | `DemoPreview` | | Write the example as a .razor file in the docs project. Its file is the source shown. |
| `Has to sit inside another tag's body` | `ComponentPreview` | | A preview written as a tag. |
## See also
- [PreviewFrame](https://shelldocs.shellui.dev/docs/components/preview-frame.md): The toolbar, layouts and anchors.
- [DemoPreview](https://shelldocs.shellui.dev/docs/components/demo-preview.md): Examples with their own code block.
- [Inline component tags](https://shelldocs.shellui.dev/docs/authoring/component-tags.md): Components in page prose, with markdown bodies.
- [Documenting a component library](https://shelldocs.shellui.dev/docs/guides/component-libraries.md): Registering your own components.