Component Demo

A live demo of Keystatic-supported MDX components, including structured tabs, layouts, media, code blocks, timelines, and callouts.

·4 min read
metademo

This post exercises the structured, editor-supported MDX APIs. Use it as a round-trip fixture and a visual reference for component props and authored children.

Admonitions

Information

This is an info admonition. Use it for helpful context, tips, and neutral information the reader should be aware of.

Watch Out

This is a warning admonition. Use it when something could go wrong, or when the reader needs to proceed with caution.

Danger Zone

This is a danger admonition. Use it for destructive actions, breaking changes, or things that will cause problems if ignored.

Well Done

This is a success admonition. Use it to confirm something worked, or to highlight a positive outcome.

Steps

  1. Create the component. Add a new .astro file in src/components/ with the component’s template and logic.

  2. Define the Props interface. Export a TypeScript interface so the component is type-safe when used in MDX.

  3. Wire it into Keystatic. Create a matching component block in the Keystatic admin project so the editor knows about its schema.

  4. Use it in content. Insert the component without a manual import; Astro’s manifest-backed MDX pipeline supplies editor-supported imports.

Accordion

What is Keystatic?

Keystatic is a CMS that treats your content as files on disk — Markdown, MDX, YAML, JSON — rather than rows in a database. You get a rich editing UI that writes directly to your content repo, with no API layer between the editor and your files.

Why use MDX instead of plain Markdown?

MDX lets you import and use components directly in your Markdown files. This means you can create rich, interactive content — tabs, accordions, code comparisons, terminal windows — without leaving the Markdown authoring experience.

How do I add a new component?

Create a component block definition in the Keystatic admin project (one file per component, ~20 lines each), add it to the mdxComponents map, rebuild, and it appears in the editor toolbar immediately.

Tabs

npm

npm install @keystatic/core

pnpm

pnpm add @keystatic/core

yarn

yarn add @keystatic/core

Pros & Cons

Pros

  • Files on disk — works with git, no database migrations
  • Type-safe schema — TypeScript-powered field definitions
  • Local-first — no cloud dependency for the editing experience
  • Component blocks — rich MDX editing with custom React previews

Cons

  • Needs a running dev server (Vite) for the editing UI
  • Component schemas must be kept in sync manually
  • No built-in auth in local mode (needs a reverse proxy with basic auth)
  • Image handling requires the site repo for optimized imports

Side by Side

The SideBySide component puts text alongside media. On desktop, the two panels sit next to each other. On mobile, they stack vertically — no media query needed, it’s built into the component.

A tidy workspace with a laptop and monitor
A tidy workspace with a laptop and monitor

With the reverse prop, the media appears on the left and the text on the right. This is useful for alternating layouts in a long article — it keeps the visual rhythm from becoming monotonous.

Code on a dark-themed editor
Code on a dark-themed editor

Image Grid

Server rack with blinking lights
Server rack with blinking lights
Network switch and cables
Network switch and cables
Raspberry Pi cluster
Raspberry Pi cluster

Figure

Laptop showing code beside a notebook
Laptop showing code beside a notebook
A structured figure keeps its caption and source attached to the media.Unsplash

File Tree

src
pages
index.astro A
components
Hero.astro A
styles
global.css CSS
package.json {}

Keyboard Input

Press Ctrl + K to open search, then press Escape to close it.

Responsive Table

ComponentAuthoring shapeNo-JS behavior
TabsRepeating TabItem childrenLabeled stacked sections
TimelineDated TimelineItem childrenReadable ordered history

Content Grid

24Components

Nested content

Grid items can contain editor-supported components.

A two-column spanning item demonstrates responsive span behavior without exposing arbitrary CSS classes to editors.

Full-width content remains readable when the grid collapses on narrow screens.

API Endpoint

GET/api/users
POST/api/users
PUT/api/users/:id
PATCH/api/users/:id
DELETE/api/users/:id

Terminal Window

Setting up Keystatic
$ npm create vite@latest keystatic-admin -- --template react-ts$ cd keystatic-admin$ npm install @keystatic/core react react-dom$ npm run dev VITE v5.4.21 ready in 266 ms ➜ Local: http://localhost:5173/

Code Compare

const fs = require('fs');\nconst data = fs.readFileSync('./config.json', 'utf8');\nconst config = JSON.parse(data);\nconsole.log(config.port);

Case Study Header

Case Study

Cloud Migration: Bare Metal to k3s

Role

Infrastructure Engineer

Tech Stack

Dockerk3sTraefikAnsiblePrometheus

The Problem

A homelab running 15 Docker containers on a single Ubuntu server had no orchestration, no auto-restart on failure, and manual TLS certificate renewal. Every update required SSH + docker-compose down/up with downtime.

The Result

Migrated to a 3-node k3s cluster with Traefik ingress, cert-manager for automatic TLS, Longhorn for replicated storage, and GitOps via Flux. Zero-downtime deployments, automatic failover, and a 40% reduction in manual maintenance hours.

Video Embed

GitHub Repo Card

withastro/astro

The web framework for content-driven websites. ⭐️ Star to support our work!

TypeScript61,2513,655
Thinkmill/keystatic

First class CMS experience, TypeScript API, Markdown & YAML/JSON based, no DB

TypeScript2,230150

Pull Quote

The best code is the code you don’t write. Every line you don’t write is a line you don’t have to debug, test, or maintain.

Dan AbramovReact Core Team

Stat Blocks

15Containers
3Nodes
99.9%Uptime
2msP99 Latency

Keystatic

First-class CMS experience, TypeScript API, Markdown & YAML/JSON based, no database.

keystatic.dev

Astro

The web framework for content-driven websites. Zero JS by default, opt-in to interactivity.

astro.build

Aside

Timeline

  1. First commit. A single Ubuntu server running Docker Compose with Traefik as a reverse proxy.

  2. Added Ansible for configuration management. Playbooks replaced shell scripts.

  3. Migrated to a 3-node k3s cluster. GitOps with Flux, cert-manager for TLS, Longhorn for storage.

  4. Added monitoring with Prometheus + Grafana. Alerting via ntfy.sh push notifications.

  5. Keystatic admin panel deployed. Content authoring moved from hand-writing MDX to a rich editing UI.

Desk setup with monitor and keyboard
Desk setup with monitor and keyboard
Mechanical keyboard close-up
Mechanical keyboard close-up
Desk plant and coffee
Desk plant and coffee

Animate

This paragraph slides up into view when you scroll to it. The Animate component supports presets like fade, slide-up, zoom-focus, and stagger-grid. Apply it around any content you want to reveal on scroll.

A second animation block with a fade effect and a longer delay. Multiple Animate blocks can be chained to create sequenced reveals down the page.

Reveal

The Reveal component is a lighter alternative — pure CSS scroll-driven animation with no JavaScript. Use it for subtle content reveals that don’t need the full motion engine.

Includes four variants: fade-up, fade-in, slide-left, and slide-right. Like Animate, it respects prefers-reduced-motion automatically.