## Doc Server SEO upgrade & refactor

**2026-05-30**

A two-front update landed today: the content renderer was normalized across page types, and a full SEO pass shipped on top.

### Rendering refactor

- **Boards, lists, board groups, and board lists now share one card renderer.** Padding, background, shadow, and corner radius are identical across types. List titles use the same `h5` typography as boards.
- **One `<h1>` per page**, sitting in the last breadcrumb slot — natural placement, no extra visual real estate, single source of truth for the page heading.
- **HTML-escaped everywhere.** Every user-controlled string (names, descriptions, breadcrumb labels, canonical URL, OG image URL) now goes through `html_escape` before reaching the template. Names like `Q&A: when to use "file"` no longer corrupt attributes.
- **Small polish:** icon-to-text gap in card rows, list corner-radius matched to board, list title vertical padding aligned with the board card.

### SEO & multi-language URLs

- **`/zh/...` and `/ja/...` URLs.** Every page is reachable in each supported language at its own crawlable URL. The bare URL (e.g. `/policies/`) continues to serve the default language (English).
- **`<link rel="alternate" hreflang="...">`** in every page header — Google can surface the right language version to each visitor.
- **`canonical`, Open Graph, Twitter Card, and JSON-LD BreadcrumbList** tags on every page. Link previews on social platforms show titles, descriptions, and images correctly.
- **`/sitemap.xml`** generated and refreshed in the background every hour, listing every page with its hreflang alternates.
- **`/op/switch_lang/<code>`** — a new language switcher that keeps URL and cookie in sync. Click "中文" anywhere and you'll land on `/zh/<the page you were on>/`.

### Why

The render refactor pays down years of per-type duplication. The SEO/language work makes the docs discoverable and shareable: humans on the main site get a sticky language preference, and search engines index each language as a distinct, crawlable page.
