API Portal
Markdoc components
The Markdoc tags and variables you can use in API Portal pages: layout components from the editor toolbar, product and article cards, buttons, links, the contact form, and the product tags that only work in the Product Page. Includes the exact attribute each tag reads.
Markdoc components are tags you write in API Portal page content to render layout blocks and live data from your portal, such as product cards, article lists, buttons and a contact form. You write them in the page editor under Portal, Pages. This page lists each tag with the attributes it actually reads.
How do you write a component tag?
A tag opens with a name and attributes in curly braces and percent signs. Tags that wrap content have a closing tag. Tags that stand alone close themselves with a slash.
{% productCard slug="weather-api" /%}
{% callout title="Rate limits" %}
Each plan sets its own limits.
{% /callout %}Attribute values in quotes are text. Numbers and true or false go without quotes, for example numberOfProducts=3.
Where can you use each component?
The same layout components work in every portal page. Product tags and variables depend on which page you are editing.
| Where you write | What works there |
|---|---|
Portal pages, shown at /your-page-slug | Layout components, product and article cards, buttons, links and the contact form. Variable: $isAuthenticated. |
| Landing Page and Mobile Landing Page | The same components. Variables: $isAuthenticated and the landing page texts from Theme. |
| Product Page | The same components, plus productFeatures, productPlanTable and productDocumentation. Variable: $product only. |
A product's Product Overview, which you edit on the product, supports the layout components and the product and article cards.
How do you discover every component on your portal?
Open /kitchen_sink on your own portal, for example https://your-portal-domain/kitchen_sink. It renders each layout component with its source, lists the portal's colour variables, and ends with a sandbox where you can try tags.
| Address | What it shows |
|---|---|
/kitchen_sink | Each layout component rendered next to its source, the Colors list of CSS variables, and a Markdoc Sandbox. |
/kitchen_sink/examples/examplePage1 | A complete example page built from components. |
/kitchen_sink/examples/examplePage2 | A second complete example page. |
/kitchen_sink/css | A mock page layout labelled with the class names of its main regions. |
The gallery focuses on layout components. The product, article and contact form tags are covered on this page.
Which components does the page editor insert?
The editor's Insert toolbar has three groups. Media holds Image and Video, Content holds Callout and Linkwrap, and Layout holds Section and Grid. Each opens a short dialog, then writes the tag at your cursor.
| Tag | What it renders | Main attributes |
|---|---|---|
image | An image, picked from the media library by the toolbar. | src, alt, width, height, aspectRatio (default 16/9), objectFit |
video | A video. A YouTube link embeds the YouTube player, any other address plays as a video file. | src (required), width (default 100%), height (default 360px), controls, autoplay, loop, muted |
callout | A highlighted information box around its content. | title |
linkwrap | Makes everything inside it a link. | link (default /), target (default _blank, a new tab) |
section | A full-width band with a background colour behind its content. | bgColor (default #f4f6f7), padding, margin |
grid with gridItem | A grid of items. | grid: columns, rows, columnGap, rowGap, backgroundColor. gridItem: columnSpan, rowSpan, link |
columns and rows take a CSS grid template, for example columns="repeat(3, 1fr)" for three equal columns. Set columnGap and rowGap, for example columnGap="1.5rem", to space the items, because both default to zero.
Which other layout components can you use?
The rest of the layout set has no toolbar button, so you type the tag. /kitchen_sink shows most of them with working source you can copy.
| Tag | What it renders | Main attributes |
|---|---|---|
roundedButton | A button that links to a portal path or a full web address. Its content is the label. | target, variant (primary or secondary), scrollToId, rounded |
cta | A call-to-action block with two headings above its content. | title, title2, backgroundImage, maxWidth, minHeight |
tabs with tab | Tabbed panels. Each tab becomes one tab. | tab: label |
sidebyside | Places its first block beside the rest, stacked on narrower screens. | maxHeight |
smalltext | Smaller body text. | textAlign, maxWidth, textSize |
frame | A padded box with a background colour. With link, the whole box is a link. | bgColor, padding, margin, link |
stack with item | A flexible row and column layout. | stack: type, columns, rows, columnGap, rowGap. item: justify, align |
iframe | Embeds another web page. | src, height (default 910px) |
verticalSpacer | Vertical space. | height |
resource | A card that opens its link in a new tab. | title, subtitle, description, image, link, view (card or list) |
br | A line break. | none |
Which product and article components can you use?
These tags pull live data from your portal. Product and article cards work on any portal page. The three product detail tags work only in the Product Page.
| Tag | What it renders | Attributes it reads |
|---|---|---|
productCard | One product's card, with its image, title and categories. | slug: the product's slug, the last part of its address, for example weather-api in /products/weather-api |
productCards | Cards for your first active public products. | numberOfProducts (default 2) |
articleCard | One article's card, with its title, description, image and tags. | id: the article's slug. The tag does not read slug. |
articlesCollection | A list of articles from one collection. | collection: the collection's name. Leave it empty to list all articles. view: card or list (default list) |
productFeatures | The overview of the product being viewed. | none, Product Page only |
productPlanTable | The plans of the product being viewed, as a comparison table. | none, Product Page only |
productDocumentation | The documentation of the product being viewed. | none, Product Page only |
contactForm | A contact form, as a button that opens it or inline in the page. | label (default Contact Us), mode (modal or inline, default modal) |
{% productCards numberOfProducts=3 /%}
{% articleCard id="getting-started" /%}
{% articlesCollection collection="guides" view="card" /%}
{% roundedButton target="/products" variant="primary" %}
Browse APIs
{% /roundedButton %}
{% contactForm mode="inline" /%}What variables can you use in a page?
Variables start with a dollar sign and are filled in by the portal. Which ones exist depends on the page you are editing.
| Variable | Where it exists | What it holds |
|---|---|---|
$isAuthenticated | Portal pages, Landing Page, Mobile Landing Page | Whether the visitor is signed in. |
$heroText1, $heroText2 | Landing Page, Mobile Landing Page | Hero Title and Hero Text from Theme. |
$heroDescription1, $heroDescription2 | Landing Page, Mobile Landing Page | Hero Body and Hero Body 2. |
$ctaButton1, $ctaButton2 | Landing Page, Mobile Landing Page | CTA Button 1 and CTA Button 2. |
$heroImage | Landing Page, Mobile Landing Page | The Hero Image address. |
$showVideo, $videoUrl, $videoText | Landing Page, Mobile Landing Page | Show video component, Embed video url and Video Text. |
$productText1, $productText2, $productsLink | Landing Page, Mobile Landing Page | Product Text 1, Product Text 2 and Products link. |
$product | Product Page | The product being viewed, for example $product.name or $product.description. |
Use $isAuthenticated with Markdoc's if tag to show a different block to signed-in developers, for example a link to their subscriptions in place of a sign-up button. This changes what each visitor sees. It does not keep content private, so do not put anything confidential inside it.
{% if $isAuthenticated %}
[Go to your subscriptions](/subscriptions)
{% else /%}
[Create an account](/signup)
{% /if %}Troubleshooting
| What you see | What to do |
|---|---|
productFeatures, productPlanTable or productDocumentation shows nothing | These work only in the Product Page. On other pages, use productCard or link to the product. |
articleCard renders an empty card | Set id to the article's slug. The tag ignores slug. |
| A landing page variable is empty on a portal page | Portal pages only get $isAuthenticated. The landing page texts exist only on the Landing Page and Mobile Landing Page. |
| The contact form shows "Network error. Please check your connection and try again." | No recipient is saved. Set one under Templates, Form Templates, then try again. |
| A callout from the toolbar looks the same whatever type you picked | Callouts have one style. Use title to tell them apart. |
| A grid shows one column, or not the number you chose | Set columns to a CSS template such as repeat(3, 1fr). |
Where to next
Portal pages
Create the pages where you write these components.
Custom CSS and Markdoc partials
Reuse blocks across products and restyle them with custom CSS.
Theme
Set the colours and the landing page texts behind the variables.
Email domain and templates
Set the recipient for contact form messages.