From 826f8383d12ab8446367e0448a9a7c4c31850e53 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:09:46 +0200 Subject: [PATCH 1/2] docs: add ClickHouse analytics blog post A first-person post on how librechat.ai's analytics run on Plausible backed by ClickHouse, including the recent cloud-to-cloud cluster move. Adds two reusable blog components: AnalyticsArchitecture, a theme-aware data-flow diagram, and SiteStats, a server component that reads live numbers from the Plausible Stats API when PLAUSIBLE_STATS_API_KEY is set and falls back to a static snapshot otherwise. Includes the cover image and registers both components in mdx-components. --- components/blog/AnalyticsArchitecture.tsx | 86 +++++++++++++ components/blog/SiteStats.tsx | 116 ++++++++++++++++++ .../blog/2026-06-25_clickhouse-analytics.mdx | 92 ++++++++++++++ lib/mdx-components.tsx | 4 + .../blog/2026-06-25_clickhouse-analytics.png | Bin 0 -> 115700 bytes 5 files changed, 298 insertions(+) create mode 100644 components/blog/AnalyticsArchitecture.tsx create mode 100644 components/blog/SiteStats.tsx create mode 100644 content/blog/2026-06-25_clickhouse-analytics.mdx create mode 100644 public/images/blog/2026-06-25_clickhouse-analytics.png diff --git a/components/blog/AnalyticsArchitecture.tsx b/components/blog/AnalyticsArchitecture.tsx new file mode 100644 index 000000000..56cccb895 --- /dev/null +++ b/components/blog/AnalyticsArchitecture.tsx @@ -0,0 +1,86 @@ +import { Globe, BarChart3, Database, Server, Gauge, ArrowRight } from 'lucide-react' +import { cn } from '@/lib/utils' +import type { ComponentType } from 'react' + +/** + * Diagram for the ClickHouse analytics blog post: the path a pageview takes from + * the browser through Plausible CE into ClickHouse, with PostgreSQL and the + * separate Core Web Vitals store shown as satellites rather than in the hot path. + * + * Server-rendered, theme-aware via the fd-* tokens. The arrows are decorative + * (aria-hidden); the node labels carry the meaning, and the whole figure has an + * aria-label that reads the flow as one sentence for screen readers. + */ + +function Node({ + icon: Icon, + title, + subtitle, + muted = false, +}: { + icon: ComponentType<{ className?: string }> + title: string + subtitle: string + muted?: boolean +}) { + return ( +
+ +
{title}
+
{subtitle}
+
+ ) +} + +function Arrow() { + return ( +