Overview

HolyDocs supports images, videos, and static assets as first-class content. Images are served through the /_assets/ endpoint with automatic optimization, and the build pipeline validates all asset references to catch broken links before deployment.

Need to embed a live capture of a webpage rather than a static file? Use the <Screenshot> component. It renders device-framed, gradient-backed screenshots from any URL at build time and caches the result on the CDN — no manual PNG uploads required.

Image Syntax

Use standard Markdown syntax or HTML <img> tags in your MDX files:

mdx
![Screenshot of the dashboard](/images/dashboard.png)
mdx
<img src="/images/dashboard.png" alt="Screenshot of the dashboard" />

Both approaches are equivalent. The Markdown syntax is shorter, while the HTML tag gives you access to additional attributes like width, height, and className.

Always include descriptive alt text for accessibility. Screen readers and search engines rely on alt text to understand image content. Avoid generic text like "image" or "screenshot."

Image Paths

Image paths starting with / are resolved relative to your docs root directory and served via the /_assets/ endpoint at build time.

text
docs/ docs.json introduction.mdx images/ logo-light.svg logo-dark.svg dashboard.png guides/ setup-step-1.png setup-step-2.png

Reference images from any MDX file using their path from the docs root:

mdx
![Dashboard overview](/images/dashboard.png)![Setup step 1](/images/guides/setup-step-1.png)

You can also use absolute URLs for externally hosted images:

mdx
![Company logo](https://cdn.example.com/logo.png)

Supported Formats

FormatExtensionBest For
PNG.pngScreenshots, diagrams, images with transparency
JPEG.jpg, .jpegPhotographs, complex images where file size matters
SVG.svgLogos, icons, diagrams that need to scale cleanly
WebP.webpModern format with superior compression for photos and graphics
GIF.gifShort animations, simple visual demos

Prefer SVG for logos and line-art diagrams — they scale perfectly at any resolution and are typically smaller than raster equivalents. Use WebP over PNG or JPEG when browser support is not a concern (all modern browsers support WebP).

Image Sizing

Control image dimensions using HTML attributes:

mdx
<img src="/images/logo.svg" alt="HolyDocs logo" width={200} />
mdx
<img src="/images/architecture.png" alt="System architecture diagram" width={600} height={400}/>

For responsive behavior, combine with CSS utility classes:

mdx
<img src="/images/banner.png" alt="Feature banner" className="w-full max-w-2xl mx-auto rounded-lg"/>

Image Alignment

Center an image using wrapper utilities:

mdx
<div className="flex justify-center"> <img src="/images/diagram.svg" alt="Flow diagram" width={500} /></div>

Place images side-by-side using a grid:

mdx
<div className="grid grid-cols-2 gap-4"> <img src="/images/before.png" alt="Before redesign" /> <img src="/images/after.png" alt="After redesign" /></div>

Light and Dark Mode Images

Documentation often needs different image variants for light and dark modes — diagrams with white backgrounds look wrong on a dark page, and vice versa.

Using the picture Element

The <picture> element lets the browser select the right image based on the user's color scheme preference:

mdx
<picture> <source media="(prefers-color-scheme: dark)" srcSet="/images/diagram-dark.png" /> <img src="/images/diagram-light.png" alt="Architecture diagram" /></picture>

Using CSS Classes

Alternatively, use CSS utility classes to show and hide images based on the active theme:

mdx
<img src="/images/diagram-light.png" alt="Architecture diagram" className="block dark:hidden" /><img src="/images/diagram-dark.png" alt="Architecture diagram" className="hidden dark:block" />

When using the CSS approach, both images are loaded but only one is visible. The <picture> element is more efficient because the browser only downloads the matching source. For large images, prefer <picture>.

Logo Configuration

Configure your site logo in docs.json with separate variants for light and dark modes:

json
{ "logo": { "light": "/images/logo-light.svg", "dark": "/images/logo-dark.svg" }}

If both modes use the same logo, provide a single string:

json
{ "logo": "/images/logo.svg"}

The logo appears in the top-left corner of the navigation header. HolyDocs automatically switches between variants based on the active theme.

Logo Sizing

Logos are displayed at a maximum height of 28px in the header. For best results:

  • Use SVG format for crisp rendering at any display density
  • Design your logo to be legible at small sizes
  • Keep the aspect ratio reasonable (wide logos up to ~160px wide work well)

Favicon Configuration

Set your site favicon in docs.json:

json
{ "favicon": "/images/favicon.svg"}

For separate light and dark mode favicons:

json
{ "favicon": { "light": "/images/favicon-light.svg", "dark": "/images/favicon-dark.svg" }}

SVG favicons are recommended because they scale to any size and support prefers-color-scheme media queries for automatic light/dark switching within a single file.

Videos

YouTube

Embed a YouTube video using a standard iframe:

mdx
<iframe width="100%" height="400" src="https://www.youtube.com/embed/VIDEO_ID" title="Video title" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen/>

Vimeo

Embed a Vimeo video:

mdx
<iframe width="100%" height="400" src="https://player.vimeo.com/video/VIDEO_ID" title="Video title" frameBorder="0" allow="autoplay; fullscreen; picture-in-picture" allowFullScreen/>

Self-Hosted Video

For short video clips and screen recordings, use the <video> element with a file in your images directory:

mdx
<video src="/images/demo.mp4" controls width="100%" className="rounded-lg border"> Your browser does not support the video element.</video>

Responsive Video Wrapper

Wrap video embeds in a responsive container to maintain aspect ratio across screen sizes:

mdx
<div className="relative w-full" style={{ paddingBottom: '56.25%' }}> <iframe className="absolute inset-0 w-full h-full rounded-lg" src="https://www.youtube.com/embed/VIDEO_ID" title="Getting started with HolyDocs" frameBorder="0" allowFullScreen /></div>

Static Assets Directory

Organize your static assets in a consistent directory structure:

text
docs/ images/ logo-light.svg logo-dark.svg favicon.svg og/ default.png getting-started.png guides/ setup-step-1.png setup-step-2.png screenshots/ dashboard.png editor.png

All files in the images/ directory are included in the build output and served at /_assets/images/. Other asset directories work the same way — any file referenced from MDX is bundled automatically.

File Size Best Practices

Compress PNG and JPEG files using tools like ImageOptim, TinyPNG, or Squoosh before adding them to your repository. A 2MB screenshot can often be reduced to 200KB without visible quality loss.

SVG for logos and simple diagrams. WebP or JPEG for photographs and complex graphics. PNG for screenshots that need pixel-perfect clarity or transparency. GIF only for simple animations under 500KB.

Always provide width and height attributes on images. This prevents layout shift (CLS) during page load, which impacts both user experience and Core Web Vitals scores.

Aim for no more than 3-4 images per page, with each image under 500KB. If a page requires many screenshots (e.g., a step-by-step guide), consider lazy-loading images below the fold.

Name files descriptively: dashboard-overview.png is better than IMG_4023.png. Good filenames improve SEO, make the codebase navigable, and help when reviewing pull requests.

Ask a question... ⌘I