# Components

Documentation pages are MDX, and this page is the whole component vocabulary: every entry is a design system component from `@aziontech/webkit`, or a thin wrapper over one. A component absent from this page is not available: an import of it fails the build.

## Asides

No import needed. Asides are written as `:::` blocks and render the design system's `DocCallout`; they are the most common construct after links.

```mdx
:::note
Bucket names must be unique across all existing buckets.
:::

:::tip
**Increase limits** <br></br>
Contact [technical support](/en/documentation/support/) to request a higher limit for your plan.
:::

:::caution
With Load Balancer enabled, data transfer can generate usage-related costs. For more information, refer to [Pricing](/en/documentation/fundamentals/pricing/).
:::
```

Valid types: `note`, `tip`, `caution`, `danger`. `caution` renders as the callout's warning kind.

**`:::warning` is not valid** and does not render as intended. Use `:::caution`.

- A callout holds prose: sentences, short paragraphs, and a list. Keep fences and tables out of it: a fence inside a callout renders every line boxed as inline code. Put them before or after the aside.
- The callout has no title row. The bracket text is kept as a lead-in to the copy (`Did you know? — ...`), so use it only when the first words need it. In Portuguese pages, localize it: `:::note[nota]`, `:::tip[dica]`, `:::caution[Atenção]`.

## DocButton

The house call to action. A wrapper around the design system's Button that keeps the button styling inside the article body.

```mdx
import DocButton from '~/components/webkit/DocButton.vue'

<DocButton href="/en/documentation/platform/applications/cache/real-time-purge/" label="Real-Time Purge reference" kind="secondary" size="medium" />
```

- `href` and `label` are required. No client directive: the button is a static link.
- `kind`: omit it for the primary action, `secondary` for a reference link. `outlined`, `text`, and `danger` also exist.
- Always `size="medium"`.
- `icon` takes an icon class, always placed before the label. `target="_blank"` opens an external destination in a new tab.

## Code

Renders the design system's `CodeBlock`, with a copy button. Fenced blocks render the same component.

```mdx
import Code from '~/components/webkit/CodeBlock.vue'

<Code client:visible lang="bash" code={`azion deploy --local`} />
```

- A block of two or more lines numbers its lines and shows a bar on top naming the language: `Shell`, `JSON`, `JavaScript`. A `text` block reads `Text`.
- A one-line block shows the code and the copy button, with no line numbers, and no bar unless it has a file name.
- `client:visible` is mandatory on `<Code>`: without it the copy button does not work. A fence gets it for you.
- Props: `code`, `lang`, and two optional ones. `fileName` puts a file name in the bar in place of the language. `showLineNumbers` overrides the line-number default. On a fence, `title="index.js"` after the language tag sets the file name.

**The value is a JavaScript template literal.** Backticks and `${` inside it must be escaped, and a line continuation needs a doubled backslash. When a snippet contains either, that is a reason to use `<Code>` rather than a fence, because you control the escaping.

Fenced blocks are also house style. Use a fence for output the reader reads, and `<Code>` for input the reader copies.

Language tags in use: `bash`, `sh`, `json`, `javascript`, `js`, `typescript`, `ts`, `hcl`, `graphql`, `shell`, `text`, `plaintext`. Terraform is `hcl`, not `terraform`.

---

## Tabs and Fragment

The multi-interface pattern: one task, one panel per interface. Renders the design system's `TabView`, with every panel kept in the HTML.

```mdx
import Tabs from '~/components/webkit/Tabs.vue'
import Code from '~/components/webkit/CodeBlock.vue'

<Tabs client:visible>
    <Fragment slot="tab.console">Console</Fragment>
    <Fragment slot="tab.api">API</Fragment>

<Fragment slot="panel.console">

1. Access [Azion Console](https://console.azion.com/) > **Object Storage**.
2. Select **+ Bucket**.

</Fragment>

<Fragment slot="panel.api">

<Code client:visible lang="bash" code={`curl ...`} />

</Fragment>

</Tabs>
```

- `client:visible` is mandatory. Without it the tabs render and do not switch.
- A block pairs each `tab.x` with a `panel.x`. The one exception is a page that documents more than one interface, such as a [Quickstart page](/en/documentation/style-guide/content/quickstart/) or a [how-to guide](/en/documentation/style-guide/content/how-to-guides/): the prerequisites block declares the tab strip, and every later block of the same `sharedStore` holds only `panel.x` slots. A panel-only block of the `interface` store renders that strip above its own panels, so the reader switches at any section.
- **Blank lines around markdown inside a Fragment are mandatory**, or the markdown renders as one literal paragraph.
- Panels are paired to tabs by key, and the first tab is the default. An `interface` block renders its tabs in one order on every page, whatever order the MDX declares them in: Console, GraphiQL, CLI, GitHub, API. Write them in that order anyway, so the page and its Markdown twin read the same.
- Canonical keys: `tab.console`, `tab.api`, `tab.cli`, plus `tab.apiv3` / `tab.apiv4` for versioned APIs. A key is lowercase letters and digits only: a hyphen escapes the `tab.x` / `panel.x` pairing check without failing it.
- In a block with `sharedStore="interface"`, open every panel with a heading one level below the section it sits in, carrying the tab label: `### Console`. These headings stay out of the table of contents, and each one links to its section with its interface selected: `?interface=console#create-a-database`.
- Optional `sharedStore="<key>"` syncs selection across tab groups on a page. Interface tabs use `sharedStore="interface"`, so one selection follows the reader down a page that repeats the tabs per section, and on to the next page: that one store is kept in the browser and written to the URL as `?interface=<key>`, which leaves the fragment free for a section. Give every block sharing a key the same tabs. A block that does not offer the selected key shows its own first panel instead, and leaves the selection untouched for the blocks that do offer it.

## Tag

Status badges.

```mdx
import Tag from '~/components/webkit/Tag.vue'

<Tag severity="info">Preview</Tag>
```

- No client directive: the badge is static HTML.
- `severity` is `success`, `info`, `warning`, or `danger`. `info` is the neutral label chip, used for "Preview" and product badges; the other three are status colors.
- The label goes in the children. `value="Preview"` is also accepted.

## Video

No import needed. Emits the iframe plus schema.org `VideoObject` metadata.

```mdx
<Video
  src="https://www.youtube.com/embed/BV4jRPpADw8"
  title="Local development with Azion CLI"
  description="How the CLI supports local debugging and faster workflows."
  uploadDate="2023-10-17"
/>
```

`src` must be a YouTube **embed** URL. `src` and `title` are required. For a screenshot or a clip file, use Figure.

## Mermaid diagrams

A diagram is a `mermaid` code fence, not an image. The text reaches an agent fetching the markdown twin; an image reference does not.

````md
```mermaid
%%{init: {"layout": "elk", "themeVariables": {"fontSize": "13px"}, "flowchart": {"nodeSpacing": 24, "rankSpacing": 36, "padding": 8, "wrappingWidth": 150, "useMaxWidth": true}, "sequence": {"width": 120, "actorMargin": 30, "useMaxWidth": true}}}%%
flowchart TD
  Client(["Client"]) -->|"request"| DC["Azion data center"]
  DC -->|"miss"| Origin[["origin server"]]
  Origin -.->|"response"| DC
  DC -.->|"response"| Client
```
````

`title="..."` after `mermaid` on the fence adds a caption below the diagram. Label every node and edge in words, and never rely on color alone to carry a distinction. A diagram never stands alone: architecture and use-case pages keep the numbered dataflow beneath it.

Every diagram follows the same rules:

- **Open with the shared `init` line** the example shows. It lays the diagram out with ELK, gives the labels room, and shrinks a diagram wider than the column to fit it. When the first node does not render at the top, add an `elk` object right after `"layout": "elk",`. In a diagram with a cycle, such as a request and its response, use ELK's model-order options, so the declaration order decides the layers: `"cycleBreakingStrategy": "MODEL_ORDER"`, or `"preset": "modelOrder", "keepEntryNodeOnTop": true`. In a diagram with more than one starting node, use `"layeringStrategy": "LONGEST_PATH_SOURCE"`, which puts every starting node in the top row.
- **Run every flowchart top to bottom** (`flowchart TD`), a chain of steps included. A chain drawn left to right grows wider than the column and shrinks its labels to fit.
- **Give each role one shape.** The client is a stadium (`(["Client"])`), anything on Azion, a Product or a Platform Resource, is a rectangle (`["application"]`), a data store is a cylinder (`[("KV Store")]`), and a system outside Azion is a subroutine (`[["origin server"]]`). A step, a state, or a decision keeps its rectangle or its diamond.
- **Let the line style say which way the flow runs.** When a diagram draws a request and its response, solid arrows (`-->`) carry the request and dotted arrows (`-.->`) carry the response. A flow that runs apart from any request, such as a purge or a log stream, takes thick arrows (`==>`).

## Steps

A numbered walkthrough: each step is a title with an optional body, and the numbers come from the order on the page.

```mdx
import DocSteps from '@aziontech/webkit/doc-steps'
import DocStep from '@aziontech/webkit/doc-step'

<DocSteps>
  <DocStep title="Create the bucket">

  In [Azion Console](https://console.azion.com/), go to **Object Storage** and select **+ Bucket**.

  </DocStep>
  <DocStep title="Name it">

  Bucket names must be unique across all existing buckets.

  </DocStep>
</DocSteps>
```

- No client directive.
- Never write the number: reordering the steps renumbers them.
- A `DocStep` always sits inside a `DocSteps`. Blank lines around the markdown inside a step are mandatory.

## Figure

A framed screenshot, clip, or diagram, with an optional lead-in above and a caption below.

```mdx
import DocFrame from '@aziontech/webkit/doc-frame'

<DocFrame
  src="/assets/docs/images/uploads/real-time-metrics-overview.png"
  alt="Overview of a Real-Time Metrics query flow"
  caption="The query flow, from the console to the data source."
/>
```

- `src` takes an image or a clip (`.mp4`, `.webm`). Give an image an `alt`. Without `src`, the frame wraps its children, such as a `mermaid` fence.
- `caption` and `hint` are plain strings; the slots of the same name (`<Fragment slot="caption">`) carry a caption with a link or inline code.
- `autoplay` plays a clip muted, inline, and looping, with no controls.

## Cards

A grid of navigation cards, for a page that fans out into sections. It is the closing `## Next steps` section of a page: one card per destination, with the reason as the copy.

```mdx
import DocCardGroup from '@aziontech/webkit/doc-card-group'
import DocCard from '@aziontech/webkit/doc-card'

<DocCardGroup cols={2}>
  <DocCard title="Build" href="/en/documentation/" label="Applications, functions, and connectors." />
  <DocCard title="Secure" href="/en/documentation/">Firewall, WAF, and DDoS protection.</DocCard>
</DocCardGroup>
```

- No client directive.
- `cols` is 2, 3, or 4; the grid collapses to one column on a phone.
- `href` makes the whole card the link. `label` is the copy; children replace it when the copy needs a link or inline code.
- Optional: `icon` takes a PrimeIcons class (`pi pi-bolt`), `overline` a small line above the title, `link` a call-to-action text on a closing row.

## Related items

A framed list of rows, each a name and one sentence, for a reader choosing what to read next. It is the closing `## Related` section of a page.

```mdx
import FrameBox from '@aziontech/webkit/frame-box'
import ItemList from '@aziontech/webkit/item-list'
import DocItem from '@aziontech/webkit/doc-item'

<FrameBox>
<ItemList>
  <DocItem title="Cache Settings" href="/en/documentation/platform/applications/cache/cache-settings/">How a data center decides what to keep and for how long.</DocItem>
  <DocItem title="Rules Engine" href="/en/documentation/platform/applications/rules-engine/">Conditions and behaviors on the request and response phases.</DocItem>
</ItemList>
</FrameBox>
```

- No client directive. `FrameBox` draws the perimeter; `ItemList` rules between the rows.
- `href` makes the row the link; an external URL gets the outward arrow. Optional `icon` takes a PrimeIcons class.
- The copy is one sentence: what the thing is, or why the reader would go there. Inline code and links are allowed; blocks are not.

## Changelog entry

One dated entry: label and version on the left, the notes on the right, with an anchor built from the label.

```mdx
import DocUpdate from '@aziontech/webkit/doc-update'

<DocUpdate label="July 10, 2026" description="Bot Manager 1.3.0" tags={['Marketplace']}>

**Bot Manager** now ships nine new static rules and two new arguments.

</DocUpdate>
```

- No client directive. Blank lines around the markdown inside are mandatory.
- `label` is the anchor, slugified. Two entries with the same label need distinct `anchor` values.
- `description` is the line under the label; `tags` is an array of short labels.
- A page of entries outlines them: the right rail lists one row per date and links the first entry with that date, in place of the headings inside the notes. The [Changelog](/en/documentation/style-guide/content/changelog/) pattern holds the rest.

## Prompt

A block of literal text the reader hands to an agent, set in the mono face with a copy control. It is not a code block: no language, no highlighting.

```mdx
import DocPrompt from '@aziontech/webkit/doc-prompt'

<DocPrompt client:visible title="Try it">Create an application with caching enabled and deploy it.</DocPrompt>
```

- `client:visible` is mandatory: the copy control and the expand control need it.
- `kind="line"` makes one scrolling line instead of a paragraph capped at four lines. `title` and `icon` are optional.

## Inline gloss

A term in running prose that shows its definition on hover or focus, with an optional link.

```mdx
import DocTooltip from '@aziontech/webkit/doc-tooltip'

The <DocTooltip client:visible headline="Cache key" tip="The identifier a data center builds from a request." cta="Read more" href="/en/documentation/platform/applications/cache/cache-settings/">cache key</DocTooltip> decides what matches.
```

- `client:visible` is mandatory; without it the term renders and never opens.
- `tip` is the definition, `headline` the bold lead-in, `cta` plus `href` the link.

## Supplied by the layout

`DocPageHeader` (from `title` and `description` in the frontmatter), `DocOnThisPage`, `DocPagination`, and the `DocProse` typography contract render around every page. Never author them.

---

## Shared snippets

Reusable blocks under `~/includes/snippets/`, each with an `en/` and a `pt/` variant. Note the Portuguese folder is `pt/`, not `pt-br/`.

```mdx
import VersionDeprecated from '~/includes/snippets/versionDeprecated/en/snippet.mdx'

<VersionDeprecated>[Workloads](/en/documentation/platform/workloads/)</VersionDeprecated>
```

Available: `versionRollingOut`, `versionDualSteps`, `versionDeprecated`, `JourneyAPI`, `InterfaceNote`, `LetsEncryptExpiration`, `RulesEngineExecution`.

### Version notices

A page about a resource that exists in API v3 and API v4 carries exactly one version notice, and the notice comes from one of three snippets. Never write a version notice by hand.

| Snippet             | Goes on                                                                 | Content                                        | Removed when                                                                                          |
| ------------------- | ----------------------------------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `versionRollingOut` | The top of an API v4 page whose resource has an API v3 page             | A link to the API v3 page, titled as that page | API v4 reaches every account                                                                          |
| `versionDualSteps`  | The end of the introduction of a guide with steps for API v4 and API v3 | None                                           | API v4 reaches every account. The API v3 steps go with it                                             |
| `versionDeprecated` | The top of an API v3 page                                               | A link to the API v4 page, titled as that page | API v4 reaches every account. The page then redirects to its API v4 counterpart, never to a home page |

An API v3 page is not listed in the navigation. Its row in the product tree carries `"hidden": true`, so the page keeps the sidebar and breadcrumb of its product, and readers reach it from the notice on its API v4 counterpart.

The date when API v3 shuts down appears only in `versionDeprecated` and on [API v4 Migration](/en/documentation/fundamentals/api-v4-migration/).

## SectionBasicContent

The header block of a template showcase page. Import it from `~/components/webkit/SectionBasicContent.vue`. Takes `description` and a `buttons` array, with the rest of the page in a `<Fragment slot="content">`. Each button takes `label`, `link`, and optionally `severity: "secondary"`, `outlined: true`, `icon`, and `target`. A button without `link` renders nothing. Read an existing showcase page before using it.

## ProductGuidesSection

Renders the Guides and tutorials hub as a table of name, type, and last updated. Used on the hub page of a product section, and nowhere else.

```mdx
import ProductGuidesSection from '~/components/ProductGuidesSection.astro'

<ProductGuidesSection product="applications" />
```

- `product` — the section's id, such as `applications`. The table lists every guide the guides catalog tags with the section or with a Product nested in it.
- The date is the page's last change, filled in for you. Never write it by hand.
- The type column shows each page's content type, in the reader's language.
- Rows sort by title.

---

## GlossaryFilter

Client-side filter over a glossary table. Used on a product's Glossary page, and nowhere else.

```mdx
import GlossaryFilter from '~/components/GlossaryFilter.astro'

<GlossaryFilter lang="en">

| Term | Definition |
| --- | --- |
| cache key | The identifier a data center builds from a request to decide whether two requests match the same cached object. |

</GlossaryFilter>
```

- The child is one GFM pipe table, `| Term | Definition |`. Blank lines around it are mandatory.
- `lang` localizes the filter placeholder and the empty-state message: `en` or `pt-br`.
- Each body row gets an anchor id from its term, ASCII-folded (`ação múltipla` → `#acao-multipla`), so a definition is deep-linkable. Ids are set at render time, so anchors work without JavaScript.
- Filtering is a progressive enhancement: without JavaScript the full table renders. Matching is case- and accent-insensitive, against the whole row.

## Tables and line breaks

Tables are plain GFM pipe tables. Horizontal scrolling is added automatically; do not wrap them yourself.

`<br />` or `<br></br>`. **Bare `<br>` breaks the build** — MDX requires every tag closed.

## MDX rules that break builds

- Bare `<` and `{` in prose are parsed as JSX. Escape them or use backticks.
- Every tag must be closed or self-closing.
- No H1 in the body; `title` renders it.
- `---` between major sections is house style, roughly three per page. Never immediately after the frontmatter block.
- Imports go directly after the frontmatter block, before any prose.

## Related resources

- [Code](/en/documentation/style-guide/formatting/code.md): When a fence carries output and a `<Code>` block carries input.
- [Text formatting](/en/documentation/style-guide/formatting/text.md): Links, bold, italics, and monospace around the components.
- [Choose a content type](/en/documentation/style-guide/content/choose-a-content-type.md): The page kinds these components serve.
