Skip to main content

Publishing

Media

Screenshots, diagrams, videos, embeds — what to capture, how to annotate, how to size, how to write alt text that serves both humans and LLMs. Media discipline that actually ships.

The difference between good docs and great docs is often how media is handled. Bad: blurry screenshots from arbitrary zoom levels, hero videos that autoplay loudly, "see the image below" with no fallback for readers who can't. Good: purposeful media that carries information prose can't, annotated for clarity, captioned for scannability, alt-texted for accessibility + LLM ingestion.

This guide covers the media discipline for docs.

When to use media

UI screenshots — yes

Any step that says "click the X in the Y of the dashboard" should have a screenshot showing where. Prose alone forces the reader to hunt.

Architecture diagrams — yes

System overviews, data flow, request lifecycles. One diagram can replace five paragraphs. Use Mermaid for maintainability.

Short videos / GIFs — sometimes

Interactions that can't be captured in a single screenshot (drag-and-drop, hover-reveal, animation timing). Keep under 15 seconds. Always pair with prose fallback.

Decorative hero images — rarely

Only when the image is the product (a design tool, a data visualisation product). Otherwise cut — hero images delay first-paint and agents can't see them anyway.

Screenshot discipline

Capture

  • Browser zoom 100% + device pixel ratio @2x — retina-sharp on modern displays.

  • Same browser, same OS, same theme across the whole docs site. Mixed Safari / Firefox / macOS / Windows chrome is distracting.

  • Crop to the relevant UI. Full-window screenshots are 1400×900 of which 10% is useful. Crop to 600×400 of the dashboard panel being discussed.

  • Hide personal data — your real email, your real API keys, your real customers' names. Use demo@acme.com and sk_test_demo....

  • Consistent window chrome — either keep the browser title bar / URL bar visible (if URL is informative) or hide entirely (distracting). Pick one and stick with it.

Recommended tools:

ToolGood for
macOS Cmd+Shift+4, SpaceWindow capture with shadow, @2x
CleanShot XAnnotation + cropping + scrolling capture
ShottrFree alternative, fewer annotation features
FlameshotCross-platform OSS

Annotation

Annotate only what the reader needs to find. Arrows, numbered circles, red outlines around the specific clickable area. Don't annotate the whole screenshot — it defeats the purpose.

❌ Arrow 1 → Settings. Arrow 2 → General. Arrow 3 → Save. Arrow 4 → ...
   (Seven arrows across the whole screenshot.)

✅ Arrow → "Custom domains" section in the Settings sidebar.
   (One arrow, one focus point, one prose step.)

Colour choice: high-contrast red (#DC2626) or yellow (#EAB308) against most UI. Avoid green (reads as "success") or purple (too subtle).

Where the file lives

Two places work, and the choice matters more than it looks.

In your repo, under public/. The file is versioned with the page that uses it, and <Image> runs it through the image optimizer: the reader gets a resized AVIF or WebP sized to their screen, not the file you committed. A 340KB screenshot can reach a phone as about 40KB without you doing anything.

On a CDN or object store, as an https:// URL. Nothing enters your repo. No push waits on the upload, no clone re-downloads it, and the file can be replaced without a commit.

An external URL is served as-is. Next.js does not optimize images it doesn't host — a 3MB PNG behind an https:// URL arrives as 3MB, on every device. The optimizer is the thing you give up, so the size you upload is the size readers pay for.

Which one depends on the file:

FilePut itWhy
Screenshots, diagrams, iconspublic/Small enough that Git doesn't care, and optimization is free
Video (.mp4, .webm)CDNVideo never goes through the optimizer, so public/ costs repo weight and returns nothing
Anything over a few MBCDNSee below
Assets you already hostCDNNo reason to copy them into the repo

The reason to keep large binaries out of Git is that they never leave. Git stores each version of a binary in full — it can't diff them — so a 5MB video replaced three times is 15MB in the history of every clone, forever, including the versions nobody uses. Deleting the file doesn't shrink it. Text files don't behave this way, which is why a repo of pure MDX stays small for years.

That weight is paid on every git clone, every CI checkout, and every sync, because a sync fetches the whole repository — a 200MB media folder is re-downloaded when you fix a typo in one page.

Sizing

Target dimensions for common slots in NookDocs layouts:

Use caseDimensionsFile size
Inline full-width1600 × 900 (16:9)<200KB
Inline narrow (next to text)800 × 600<80KB
Hero / section break1600 × 900 or 1200 × 600<250KB
Small inline (icon-size)200 × 200<30KB

These are firm for external URLs, where the number you upload is the number the reader downloads. Under public/ they are a guide to keeping the repo light — the optimizer is already handling what reaches the browser, so a retina screenshot landing somewhat over is not a problem worth solving twice.

Compress before committing:

  • PNG → TinyPNG (free up to 20/month, retains transparency).

  • JPG → 85% quality in most tools; 70% is usually the sweet spot between size + quality.

  • WebP → modern replacement, 25-35% smaller than JPG at same quality. Supported in all modern browsers.

# Bulk compress a directory
find ./images -name "*.png" -exec pngquant --ext .png --force {} \;
find ./images -name "*.jpg" -exec jpegoptim --max=85 {} \;

Alt text that works

Alt text serves three audiences:

  1. Screen reader users — hear the alt text read aloud.

  2. Users on slow connections — see alt text while the image loads (or if it fails).

  3. LLMs ingesting the page — can't see the image, extract meaning from alt + surrounding prose.

Good alt text names what the image shows + why it's in the doc.

❌ alt="screenshot.png"
❌ alt="dashboard"
❌ alt="Image of the dashboard"

✅ alt="Custom Domains panel in Settings showing docs.acme.com verified with a green check"
✅ alt="Mermaid diagram: request flow from browser through CDN to origin, with cached response returning in 15ms"
✅ alt="Code editor sidebar showing _snippets folder expanded with three mdx files inside"

Rules of thumb:

  • Name what the image shows, not the image type. "Image of X" is noise — screen readers already announce "image".

  • Mention the key UI element or data point. If the screenshot shows the "Save" button, name it.

  • Be as short as possible while being specific. ~8-15 words is usually right.

  • Decorative images get alt="". Empty alt = screen reader skips. Missing alt = screen reader reads the filename.

Captions

Captions serve sighted readers — they reinforce what the image shows AND what to do with it:

<Frame caption="After adding a custom domain, the entry flips to 'Verified' once DNS propagates. Typical: 30-60 seconds.">
  ![Custom Domains panel with docs.acme.com showing as Verified with a green check](/images/custom-domain-verified.png)
</Frame>

Alt text names the content. Caption explains the implication. Together they cover both "what is this showing me" and "so what".

Diagrams — prefer Mermaid

Diagrams render as images when you ship PNG / SVG. Mermaid diagrams render as live SVG from Markdown-like source — which means:

  • Searchable text (SEO + accessibility).

  • Version-controlled sourcegit diff shows what changed in the diagram.

  • Editable in-repo — update without round-tripping through a design tool.

  • Automatically theme-aware — respects light / dark mode via NookDocs's theme tokens.

<Mermaid>
```mermaid
sequenceDiagram
  Browser->>CDN: GET /docs/quickstart
  CDN->>Origin: cache miss, fetch
  Origin-->>CDN: HTML + headers
  CDN-->>Browser: HTML (cached 5 min)
```
</Mermaid>

Use PNG/SVG only when:

  • The diagram is too complex for Mermaid syntax (hand-drawn, annotated with multiple overlays).

  • You need photo-real elements (product screenshots composited into a flow).

Video + animation

Video is tempting for "show the interaction" cases but carries real costs: file size, auto-play UX debates, screen reader + accessibility overhead, LLM invisibility.

Rules for when to use:

  • ≤15 seconds — anything longer, split into smaller clips or use static screenshots with numbered steps.

  • Silent — no voiceover. Users reading docs are often in shared workspaces. The doc's prose carries narration.

  • No autoplay — reader presses play. Exception: ultra-short GIFs (under 3 seconds) documenting a single interaction.

  • Provide transcript or caption — describe what happens in prose either above or below the video. LLMs + screen readers need this; sighted users benefit too.

Formats:

FormatBest forCaveats
MP4 (H.264)Longer demos (5-15s)Needs <video> element. Supports audio if you ever need it.
GIFMicro-interactions (<3s)Huge files. Prefer MP4 + poster image for anything over 2s.
WebMSame as MP4Smaller than MP4. Browsers auto-fall back to MP4 via <source> chain.
APNGHigh-fidelity short animationsLimited tooling. Rarely worth the effort.

Embed with the <Video> component:

<Video
  src="/videos/custom-domain-setup.mp4"
  poster="/images/custom-domain-setup-poster.png"
  caption="Adding a CNAME record in Cloudflare, pasting the target into Acme dashboard, and watching the verification flip green."
/>

Third-party embeds

YouTube, Loom, Vimeo — use the <Embed> component:

<Embed
  src="https://www.youtube.com/embed/dQw4w9WgXcQ"
  title="Walkthrough: Setting up a custom domain"
/>

NookDocs whitelists YouTube, Loom, Vimeo, Figma, CodePen, and StackBlitz. Other origins render as a notice with a link to the external resource (avoids XSS from untrusted iframes).

Loom vs YouTube:

  • Loom — internal demos, quick walkthroughs, no publishing to YouTube. Loom handles the loading / hosting.

  • YouTube — evergreen content, marketing videos, anything you want to rank in YouTube search. More control over thumbnails + end screens.

Media organisation in the repo

docs/
  images/
    features/
      copy-for-llms-dropdown.png
      copy-for-llms-menu-open.png
    api/
      rate-limit-headers.png
    concepts/
      architecture-overview.svg
  videos/
    custom-domain-setup.mp4

Conventions:

  • Organise by doc path, not by media type. images/features/copy-for-llms.png beats images/screenshots/copy-for-llms.png.

  • Lowercase, hyphenated filenames. custom-domain-setup.png beats CustomDomainSetup.png.

  • No version numbers in filenames. If the screenshot gets updated, replace in place — Git tracks the history.

  • Reference with absolute paths in MDX: /images/features/custom-domain.png. Relative paths break when the page moves.

Image optimisation at serve time

NookDocs doesn't yet ship Next.js <Image> auto-optimisation (lazy loading, responsive srcset, modern format delivery) for user-repo images — they serve as-is from /api/assets/<path>. Compress before committing.

Roadmap: /images/<path>?w=800&q=85 responsive URLs with on-the-fly resize. Until then, ship the right size at commit time.

Common media mistakes

Related

Was this page helpful?

Last updated September 14, 2026