Express

A plain Express middleware + route pattern for strict Accept negotiation with Markdown siblings, Vary: Accept, 406, and Link: rel="alternate".

Express is the most portable baseline: one middleware picks representation, routes return markdown or HTML accordingly.

server.js

import express from 'express';
import fs from 'node:fs/promises';
import path from 'node:path';

const app = express();
const PRODUCES = ['text/html', 'text/markdown'];

function parseAccept(header) {
  return header
    .split(',')
    .map((raw) => {
      const parts = raw.trim().split(';').map((s) => s.trim());
      const type = (parts[0] || '').toLowerCase();
      if (!type) return null;
      let q = 1;
      for (const param of parts.slice(1)) {
        const [name, value] = param.split('=').map((s) => s.trim());
        if (name === 'q') {
          const parsed = Number(value);
          if (!Number.isNaN(parsed)) q = Math.max(0, Math.min(1, parsed));
        }
      }
      const specificity = type === '*/*' ? 0 : type.endsWith('/*') ? 1 : 2;
      return { type, q, specificity };
    })
    .filter(Boolean);
}

function matches(entry, candidate) {
  if (entry.type === '*/*') return true;
  if (entry.type.endsWith('/*')) return candidate.startsWith(entry.type.slice(0, -1));
  return entry.type === candidate;
}

function preferredType(header, produces) {
  if (!header) return produces[0] || null;
  const entries = parseAccept(header);
  if (!entries.length) return produces[0] || null;

  let best = null;
  let bestQ = -1;
  let bestPos = Infinity;

  for (const candidate of produces) {
    let matched = null;
    let matchedPos = Infinity;
    for (let i = 0; i < entries.length; i++) {
      const e = entries[i];
      if (!matches(e, candidate)) continue;
      if (matched === null || e.specificity > matched.specificity || (e.specificity === matched.specificity && i < matchedPos)) {
        matched = e;
        matchedPos = i;
      }
    }
    if (!matched || matched.q <= 0) continue;
    if (matched.q > bestQ || (matched.q === bestQ && matchedPos < bestPos)) {
      best = candidate;
      bestQ = matched.q;
      bestPos = matchedPos;
    }
  }

  return best;
}

app.use((req, res, next) => {
  const chosen = preferredType(req.header('accept') ?? null, PRODUCES);
  res.vary('Accept');
  req.prefersMarkdown = chosen === 'text/markdown';

  if (chosen === null && req.header('accept')) {
    return res
      .status(406)
      .type('text/plain; charset=utf-8')
      .send('Not Acceptable\n\nAvailable: text/html, text/markdown\n');
  }

  next();
});

async function exists(p) {
  try { await fs.access(p); return true; } catch { return false; }
}

// Explicit .md sibling. Matched before /docs/:slug via regex so a
// request for `/docs/foo.md` doesn't fall into the canonical route.
app.get(/^\/docs\/([^/]+)\.md$/, async (req, res) => {
  const slug = req.params[0];
  try {
    const md = await fs.readFile(
      path.join(process.cwd(), 'content', 'docs', `${slug}.md`),
      'utf8',
    );
    return res
      .type('text/markdown; charset=utf-8')
      .set('Vary', 'Accept')
      .send(md);
  } catch {
    return res.status(404).send('Not found');
  }
});

app.get('/docs/:slug', async (req, res) => {
  const slug = req.params.slug;
  const base = path.join(process.cwd(), 'content', 'docs', slug);

  if (req.prefersMarkdown) {
    try {
      const md = await fs.readFile(`${base}.md`, 'utf8');
      return res.type('text/markdown; charset=utf-8').send(md);
    } catch {
      // Markdown missing. Only fall through to HTML if HTML is still
      // acceptable — `Accept: text/markdown, text/html;q=0` forbids it.
      if (!preferredType(req.header('accept') ?? null, ['text/html'])) {
        return res
          .status(406)
          .type('text/plain; charset=utf-8')
          .send('Not Acceptable\n\nMarkdown representation not available and HTML is not acceptable.\n');
      }
    }
  }

  try {
    const html = await fs.readFile(`${base}.html`, 'utf8');
    res.type('text/html; charset=utf-8');
    // Advertise the .md sibling via Link: rel="alternate" (RFC 8288)
    // so agents (like Codex) can discover it without sending Accept.
    if (await exists(`${base}.md`)) {
      res.set('Link', `</docs/${slug}.md>; rel="alternate"; type="text/markdown"`);
    }
    return res.send(html);
  } catch {
    return res.status(404).send('Not found');
  }
});

app.listen(3000);

Verify

curl -sI -H "Accept: text/markdown" http://localhost:3000/docs/intro
curl -sI -H "Accept: application/pdf" http://localhost:3000/docs/intro