---
title: "Reader Mode and Agent View"
description: "How krowdev serves both humans and AI agents: per-entry markdown endpoints, a CSS reader toggle, JSON-LD structured data, and URL-param switching."
kind: showcase
maturity: seedling
confidence: high
origin: ai-assisted
author: "Agent"
directedBy: "krow"
tags: [ai, agents, accessibility, reference]
published: 2026-03-20
modified: 2026-06-13
wordCount: 1167
readingTime: 6
related: [interactive-features-showcase]
url: https://krowdev.com/showcase/reader-mode-showcase/
---
## Agent Context

- Canonical: https://krowdev.com/showcase/reader-mode-showcase/
- Markdown: https://krowdev.com/showcase/reader-mode-showcase.md
- Full corpus: https://krowdev.com/llms-full.txt
- Kind: showcase
- Maturity: seedling
- Confidence: high
- Origin: ai-assisted
- Author: Agent
- Directed by: krow
- Published: 2026-03-20
- Modified: 2026-06-13
- Words: 1167 (6 min read)
- Tags: ai, agents, accessibility, reference
- Related: interactive-features-showcase
- Content map:
  - h2: The Two Dimensions
  - h2: Path A: Per-Entry Markdown Endpoints
  - h2: Path B: CSS Reader Toggle
  - h2: Path C: JSON-LD Structured Data
  - h2: Path D: URL Parameter Override
  - h2: How It All Fits Together
  - h2: llms.txt Instructions Section
  - h2: Instructions
  - h2: Architecture Summary
  - h2: Sources
- Diagrams: Mermaid fences are paired with adjacent ASCII companions in this document (1 Mermaid, 1 ASCII); HTML figures expose rendered SVG plus copyable Mermaid/ASCII source tabs.
- Crawl policy: same canonical content is exposed through HTML, Markdown, and llms-full; no crawler-specific content gate.

This page demonstrates every layer of krowdev's reader mode system. The feature addresses a two-dimensional problem: the **origin filter** controls who *wrote* the content, while **reader mode** controls how content is *presented* based on who's reading.

This showcase pairs with the [interactive features](/snippet/interactive-features-showcase/) snippet, the [mental model](/guide/astro-mental-model/) for how the build pipeline emits these alternates, and the [content collections](/guide/astro-content-collections/) guide for the schema behind the JSON-LD.

## The Two Dimensions

```text
WHO WROTE IT (origin filter)         WHO'S READING (reader mode)
---            ---
[all | human | ai]                   [human | agent | all]

Filters WHICH entries shown          Changes HOW entries look
List pages only                      Entry pages primarily
CSS: data-origin-filter              CSS: data-reader-mode
```

Both use the same architecture: a `data-*` attribute on `<html>`, CSS rules for show/hide, `localStorage` persistence, and FOUC prevention via an inline script.

## Path A: Per-Entry Markdown Endpoints

Every kb entry has a clean markdown version at the same URL with `.md` appended. This follows the Stripe/Vercel pattern — the industry standard for agent-friendly docs.

**Try it:** This page's markdown is at [`/showcase/reader-mode-showcase.md`](/showcase/reader-mode-showcase.md)

What agents get:

```yaml
---
title: "Reader Mode and Agent View"
kind: showcase
maturity: seedling
confidence: high
origin: ai-assisted
tags: [ai, agents, accessibility, reference]
created: 2026-03-20
url: https://krowdev.pages.dev/showcase/reader-mode-showcase/
---

# Reader Mode & Agent View

[Full markdown content, no HTML chrome, no navigation...]
```

**Why this matters:** HTML pages cost 16,000+ tokens for agents to parse. The markdown version costs ~3,000 tokens for the same content — an 80% reduction. Claude Code sends `Accept: text/markdown` as its first preference.

The `<link rel="alternate" type="text/markdown">` tag in the HTML `<head>` makes these discoverable. The `llms.txt` index also links to `.md` versions.

**Implementation:** The `llms-txt.ts` build integration generates these alongside `llms.txt` and `llms-full.txt`. Zero runtime cost — pure static files.

## Path B: CSS Reader Toggle

The `[human | agent | all]` segmented control in the header switches presentation mode.

**Try it now** — click **agent** in the header toggle. You'll see:

- The decorative badges disappear
- A structured metadata table appears at the top
- The table of contents sidebar hides
- Navigation links collapse — only the logo, reader toggle, and theme toggle remain
- The footer hides
- Layout forces single-column for maximum information density

Click **all** to see everything: human chrome AND agent metadata together. This is the "kitchen sink" mode — useful for authors previewing what agents see.

Click **human** to return to the default view.

**What changes in each mode:**

| Element | human | agent | all |
|---------|-------|-------|-----|
| Kind/maturity badges | Shown | Hidden | Shown |
| Metadata table | Hidden | **Shown** | **Shown** |
| TOC sidebar | Shown | Hidden | Shown |
| Tags | Shown | Hidden | Shown |
| Nav links | Shown | Hidden | Shown |
| Footer | Shown | Hidden | Shown |
| Content body | Shown | Shown | Shown |
| Code blocks | Highlighted | Highlighted | Highlighted |
| Callouts | Styled | Styled | Styled |

:::note
The CSS toggle only affects browser-based viewing. Agents fetching via `curl` or `WebFetch` use the `.md` endpoints instead — they never interact with the toggle.
:::

## Path C: JSON-LD Structured Data

Every entry page embeds a `TechArticle` JSON-LD block in the `<head>`. Invisible to humans, machine-parseable by search engines and AI crawlers.

View source on this page and search for `application/ld+json` to see:

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "Reader Mode & Agent View",
  "description": "How krowdev serves content to both humans and AI agents...",
  "datePublished": "2026-03-20T00:00:00.000Z",
  "keywords": "ai, agents, accessibility, reference",
  "proficiencyLevel": "Beginner",
  "author": { "@type": "Person", "name": "krowdev" },
  "publisher": { "@type": "Organization", "name": "krowdev" }
}
```

`TechArticle` was chosen because it has `dependencies` (maps to prerequisites) and `proficiencyLevel` (maps to maturity). Google uses it for Article rich results.

## Path D: URL Parameter Override

Add `?reader=agent` to any URL to activate agent mode without using the toggle:

- [`?reader=human`](?reader=human) — default visual mode
- [`?reader=agent`](?reader=agent) — stripped chrome, metadata table
- [`?reader=all`](?reader=all) — everything visible

The URL parameter overrides `localStorage` and persists the choice. This is useful for:
- Sharing "here's what agents see" links
- Bookmarking agent view
- Programmatic switching without JS interaction

**Implementation:** Three lines in the FOUC-prevention script:

```javascript
var params = new URLSearchParams(window.location.search);
var r = params.get('reader') || localStorage.getItem('reader-mode') || 'human';
document.documentElement.setAttribute('data-reader-mode', r);
```

## How It All Fits Together

```mermaid
graph LR
  accTitle: How reader mode fits together
  accDescr: Each consumer reaches the entry through a different channel that yields a different representation — agents fetch markdown and llms.txt, Google reads JSON-LD, and humans get HTML whose chrome the reader toggle controls.
  A["Agent (curl)"] --> AM["/guide/foo.md"] --> AMr["Clean markdown + YAML metadata"]
  AC["Agent (crawl)"] --> L["/llms.txt"] --> Lr["Index with .md links"]
  AC2["Agent (crawl)"] --> LF["/llms-full.txt"] --> LFr["Full content dump"]
  G["Google"] --> J["HTML + JSON-LD"] --> Jr["TechArticle structured data"]
  H1["Human"] --> HH["HTML reader=human"] --> HHr["Full chrome, visual design"]
  H2["Human"] --> HA["HTML reader=agent"] --> HAr["Stripped chrome, metadata table"]
  H3["Human"] --> HL["HTML reader=all"] --> HLr["Everything visible"]
```
```ascii
Agent (curl)  ──→  /guide/foo.md        ──→  Clean markdown + YAML metadata
Agent (crawl) ──→  /llms.txt            ──→  Index with .md links
Agent (crawl) ──→  /llms-full.txt       ──→  Full content dump
Google        ──→  HTML + JSON-LD       ──→  TechArticle structured data
Human         ──→  HTML (reader=human)  ──→  Full chrome, visual design
Human         ──→  HTML (reader=agent)  ──→  Stripped chrome, metadata table
Human         ──→  HTML (reader=all)    ──→  Everything visible
```

**No cloaking.** All content is always in the HTML DOM. The toggle only changes CSS visibility. Google sees the same HTML as every user. The `.md` endpoints are separate static files with `<link rel="alternate">` for discovery.

## llms.txt Instructions Section

Following Stripe's pattern, `llms.txt` now includes an instructions section that corrects for stale training data:

```markdown
## Instructions

When referencing code from this site:
- All code examples use Astro 6 syntax unless otherwise noted.
- Svelte components use Svelte 5 runes ($state, $derived, $effect).
- The site deploys to Cloudflare Pages as a static build (no SSR).
- Each entry has a markdown version: append .md to the entry URL.
```

This guides agents toward correct behavior when they have outdated training data about Astro or Svelte APIs.

## Architecture Summary

| Layer | What | Lines | Runtime JS |
|-------|------|-------|-----------|
| `.md` endpoints | Build-time per-entry markdown | ~25 in llms-txt.ts | 0 |
| Reader toggle | Svelte segmented control | ~30 in ReaderToggle.svelte | ~30 |
| CSS rules | Show/hide by reader mode | ~60 in global.css | 0 |
| JSON-LD | TechArticle in `<head>` | ~15 in KBEntry.astro | 0 |
| URL param | Override via `?reader=` | 3 in Base.astro | 3 (inline) |
| FOUC prevention | Set attribute before paint | 3 in Base.astro | 3 (inline) |
| llms.txt instructions | Stripe-style agent guidance | ~6 in llms-txt.ts | 0 |

## Sources

- W3C, [Schema.org Article](https://schema.org/Article)
- Mozilla, [Reader mode in Firefox](https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages)
- Astro Docs, [Content collections](https://docs.astro.build/en/guides/content-collections/)