Render Markdown content as a page

Load a .md file via DataSource and display it with the Markdown component.

The Markdown component renders a markdown string as styled HTML. Pair it with a DataSource that fetches a .md file and feed the result into the content prop. When the URL changes, DataSource fetches the new file and the rendered page updates automatically.

<App var.activePage="intro.md">
  <HStack marginBottom="$space-3">
    <Button
      label="Introduction"
      variant="{activePage === 'intro.md' ? 'solid' : 'outlined'}"
      onClick="activePage = 'intro.md'" />
    <Button
      label="Getting started"
      variant="{activePage === 'getting-started.md' ? 'solid' : 'outlined'}"
      onClick="activePage = 'getting-started.md'" />
  </HStack>

  <DataSource
    id="pageContent"
    url="/api/docs/{activePage}"
  />

  <Spinner when="{!pageContent.loaded}" />
  <Markdown
    when="{pageContent.loaded}"
    content="{pageContent.value}"
    showHeadingAnchors="{true}"
    openLinkInNewTab="{true}"
  />
</App>
Markdown page from files
<App var.activePage="intro.md">
  <HStack marginBottom="$space-3">
    <Button
      label="Introduction"
      variant="{activePage === 'intro.md' ? 'solid' : 'outlined'}"
      onClick="activePage = 'intro.md'" />
    <Button
      label="Getting started"
      variant="{activePage === 'getting-started.md' ? 'solid' : 'outlined'}"
      onClick="activePage = 'getting-started.md'" />
  </HStack>

  <DataSource
    id="pageContent"
    url="/api/docs/{activePage}"
  />

  <Spinner when="{!pageContent.loaded}" />
  <Markdown
    when="{pageContent.loaded}"
    content="{pageContent.value}"
    showHeadingAnchors="{true}"
    openLinkInNewTab="{true}"
  />
</App>

In a real app, the URL can point directly to a static file such as /docs/intro.md. The playground example uses an API mock so the how-to remains self-contained.

Key points

DataSource fetches the markdown file: Set url to the path of the .md file. Binding the file name into the URL, as in /api/docs/{activePage}, makes document switching reactive.

Bind the fetched text to content: Pass content="{pageContent.value}" to Markdown. The component renders the string returned by the DataSource.

Show loading UI while the file is fetched: Use pageContent.loaded to hide the Markdown until the first response arrives and show a Spinner in its place.

showHeadingAnchors adds clickable links: Set showHeadingAnchors="{true}" to display an anchor icon on hover next to each heading. Users can click it to copy a deep link to that section.

openLinkInNewTab controls link targets: Set openLinkInNewTab="{true}" so every link inside the rendered markdown opens in a new browser tab. This is useful for documentation pages where users should not navigate away.

Inline CDATA is best for short embedded snippets: You can place markdown directly inside <Markdown><![CDATA[ ... ]]></Markdown>, but for page content, keep the markdown in .md files and load it through DataSource.


See also