Index: src/routes/admin-stats.js
===================================================================
--- src/routes/admin-stats.js	(revision 91094a44a78eaba7694534a039a5d0843f451e10)
+++ src/routes/admin-stats.js	(revision 37edecd7c1a492799587f07cc44fb88fbd1567ee)
@@ -10,4 +10,5 @@
 
 import express from 'express';
+import db from '../config/database.js';
 import { renderPage } from '../middleware/render.js';
 import { requireGod } from '../middleware/auth.js';
@@ -21,8 +22,18 @@
     return res.status(403).send('Statistieken is een premium-functie — koppel Patreon in Beheer → Instellingen.');
   }
+  // Link-in-bio klikken (premium #6) voor de huidige site.
+  let linkClicks = [];
+  if (res.locals.site) {
+    try {
+      linkClicks = db.prepare(
+        'SELECT url, clicks FROM link_clicks WHERE site_id = ? AND clicks > 0 ORDER BY clicks DESC LIMIT 50'
+      ).all(res.locals.site.id);
+    } catch { linkClicks = []; }
+  }
   renderPage(req, res, 'pages/admin-stats', {
     pageTitle: 'Statistieken',
     bodyClass: 'on-admin',
     stats: getStats(14),
+    linkClicks,
   });
 });
Index: src/routes/linkbio.js
===================================================================
--- src/routes/linkbio.js	(revision 37edecd7c1a492799587f07cc44fb88fbd1567ee)
+++ src/routes/linkbio.js	(revision 37edecd7c1a492799587f07cc44fb88fbd1567ee)
@@ -0,0 +1,61 @@
+/**
+ * Link-in-bio + klikstats (premium feature #6).
+ *
+ *   GET /links          -> Linktree-achtige pagina met de profile_links van de site
+ *   GET /links/go/:i     -> telt de klik (per url) en stuurt door naar de externe URL
+ *
+ * Hergebruikt de bestaande sites.profile_links (JSON [{platform,url}]) + de
+ * PLATFORMS-iconen/labels. Klikken landen in link_clicks (zie /admin/stats).
+ * Open-redirect-veilig: /links/go/:i stuurt ALLEEN door naar een url die in de
+ * eigen profile_links staat. Hub: via /user/:slug/links.
+ */
+
+import express from 'express';
+import db from '../config/database.js';
+import { renderPage } from '../middleware/render.js';
+import { premiumUnlocked } from '../services/PatreonService.js';
+import { PLATFORMS } from '../services/PlatformIcons.js';
+
+const router = express.Router();
+
+function parseLinks(site) {
+  if (!site || !site.profile_links) return [];
+  try { return JSON.parse(site.profile_links) || []; } catch { return []; }
+}
+
+router.get('/links', (req, res, next) => {
+  if (!premiumUnlocked()) return next();
+  const site = res.locals.site;
+  if (!site) return next();
+  const links = parseLinks(site).map((l, i) => {
+    const meta = PLATFORMS[l.platform] || {};
+    return { i, url: l.url, platform: l.platform, label: meta.label || l.platform, svg: meta.svg || '', brand: meta.brand || '' };
+  });
+  renderPage(req, res, 'pages/linkbio', {
+    pageTitle: (site.title || '') + ' — links',
+    bodyClass: 'on-linkbio',
+    lbLinks: links,
+  });
+});
+
+router.get('/links/go/:i', (req, res, next) => {
+  if (!premiumUnlocked()) return next();
+  const site = res.locals.site;
+  if (!site) return next();
+  const links = parseLinks(site);
+  const idx = parseInt(req.params.i, 10);
+  const link = (Number.isInteger(idx) && idx >= 0) ? links[idx] : null;
+  if (!link || !link.url) return next();
+  const url = String(link.url);
+  // Alleen externe http(s)- of mailto-links (geen open redirect / javascript:).
+  if (!/^https?:\/\//i.test(url) && !/^mailto:/i.test(url)) return res.status(400).send('Bad link');
+  try {
+    db.prepare(
+      `INSERT INTO link_clicks (site_id, url, clicks, updated_at) VALUES (?, ?, 1, CURRENT_TIMESTAMP)
+       ON CONFLICT(site_id, url) DO UPDATE SET clicks = clicks + 1, updated_at = CURRENT_TIMESTAMP`
+    ).run(site.id, url);
+  } catch { /* telling mag de redirect nooit breken */ }
+  res.redirect(302, url);
+});
+
+export default router;
