Index: src/config/database.js
===================================================================
--- src/config/database.js	(revision fb02cc0d85ca7497ae12dbbd7a0599190932ae72)
+++ src/config/database.js	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
@@ -172,4 +172,7 @@
     );
   `);
+
+  // Tags van de originele post — getoond in de cirkel (comma-separated string).
+  ensureColumn('remote_posts', 'tags', 'TEXT');
 }
 
Index: src/routes/circle.js
===================================================================
--- src/routes/circle.js	(revision fb02cc0d85ca7497ae12dbbd7a0599190932ae72)
+++ src/routes/circle.js	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
@@ -30,5 +30,5 @@
 
   const rows = db.prepare(`
-    SELECT p.id, p.published, p.title, p.summary, p.media_json,
+    SELECT p.id, p.published, p.title, p.summary, p.media_json, p.tags,
            a.name AS actor_name
     FROM remote_posts p
@@ -51,5 +51,5 @@
       created_at: r.published,
       type: 'post',
-      tags: '',
+      tags: r.tags || '',
       pinned: 0,
       status: 'published',
@@ -81,5 +81,5 @@
 
   const row = db.prepare(`
-    SELECT p.id, p.published, p.title, p.summary, p.url, p.media_json,
+    SELECT p.id, p.published, p.title, p.summary, p.url, p.media_json, p.tags,
            a.name AS actor_name, a.url AS actor_url, a.avatar AS actor_avatar
     FROM remote_posts p
@@ -100,4 +100,6 @@
     sourceAvatar: safeUrl(row.actor_avatar),
     originalUrl: safeUrl(row.url),
+    tags: (row.tags || '').split(',').map((t) => t.trim()).filter(Boolean),
+    sourceTagBase: safeUrl(row.actor_url) ? safeUrl(row.actor_url).replace(/\/+$/, '') : null,
   };
 
Index: src/services/CircleFederation.js
===================================================================
--- src/services/CircleFederation.js	(revision fb02cc0d85ca7497ae12dbbd7a0599190932ae72)
+++ src/services/CircleFederation.js	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
@@ -85,4 +85,12 @@
 }
 
+// Tags-kolom (JSON-array of comma-separated) -> nette string-array.
+function parseTags(raw) {
+  if (!raw) return [];
+  if (Array.isArray(raw)) return raw.map((t) => String(t).trim()).filter(Boolean);
+  try { const j = JSON.parse(raw); if (Array.isArray(j)) return j.map((t) => String(t).trim()).filter(Boolean); } catch { /* geen JSON */ }
+  return String(raw).split(',').map((t) => t.trim()).filter(Boolean);
+}
+
 function iso(d) {
   const t = d ? new Date(d) : new Date();
@@ -136,5 +144,5 @@
 
   const rows = db.prepare(`
-    SELECT slug, title, excerpt, content, cover_image_url, published_at, created_at, type
+    SELECT slug, title, excerpt, content, cover_image_url, published_at, created_at, type, tags
     FROM posts
     WHERE site_id = ? AND status = 'published'
@@ -148,4 +156,5 @@
     const published = iso(p.published_at || p.created_at);
     const summary = (p.excerpt || stripHtml(p.content)).slice(0, 500);
+    const tags = parseTags(p.tags).slice(0, 12);
     return {
       type: 'Create',
@@ -161,4 +170,6 @@
         published,
         ...(p.cover_image_url ? { image: { type: 'Image', url: abs(base, p.cover_image_url) } } : {}),
+        // ActivityStreams: tags als Hashtag-objecten (href naar de bron-tagpagina).
+        ...(tags.length ? { tag: tags.map((t) => ({ type: 'Hashtag', name: '#' + String(t).replace(/^#/, ''), href: `${base}/tag/${encodeURIComponent(t)}` })) } : {}),
       },
     };
Index: src/services/CircleService.js
===================================================================
--- src/services/CircleService.js	(revision fb02cc0d85ca7497ae12dbbd7a0599190932ae72)
+++ src/services/CircleService.js	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
@@ -29,4 +29,14 @@
 function baseOf(remoteUrl) {
   return String(remoteUrl).replace(/\/+$/, '');
+}
+
+// AS Hashtag-array -> comma-separated tagnamen (zonder #), gesanitized.
+function extractTags(tag) {
+  if (!Array.isArray(tag)) return null;
+  const names = tag
+    .map((t) => String((t && t.name) || '').replace(/^#/, '').trim())
+    .filter(Boolean)
+    .slice(0, 12);
+  return names.length ? names.join(', ') : null;
 }
 
@@ -83,9 +93,10 @@
     `),
     upsertPost: db.prepare(`
-      INSERT INTO remote_posts (id, actor_id, published, title, summary, url, media_json, raw_json, fetched_at)
-      VALUES (@id, @actor_id, @published, @title, @summary, @url, @media_json, @raw_json, CURRENT_TIMESTAMP)
+      INSERT INTO remote_posts (id, actor_id, published, title, summary, url, media_json, tags, raw_json, fetched_at)
+      VALUES (@id, @actor_id, @published, @title, @summary, @url, @media_json, @tags, @raw_json, CURRENT_TIMESTAMP)
       ON CONFLICT(id) DO UPDATE SET
         published=excluded.published, title=excluded.title, summary=excluded.summary,
-        url=excluded.url, media_json=excluded.media_json, raw_json=excluded.raw_json, fetched_at=CURRENT_TIMESTAMP
+        url=excluded.url, media_json=excluded.media_json, tags=excluded.tags,
+        raw_json=excluded.raw_json, fetched_at=CURRENT_TIMESTAMP
     `),
   };
@@ -169,4 +180,5 @@
       url: obj.url || obj.id,
       media_json: media.length ? JSON.stringify(media) : null,
+      tags: extractTags(obj.tag),
       raw_json: JSON.stringify(obj).slice(0, 20000),
     });
Index: src/views/pages/circle-post.ejs
===================================================================
--- src/views/pages/circle-post.ejs	(revision fb02cc0d85ca7497ae12dbbd7a0599190932ae72)
+++ src/views/pages/circle-post.ejs	(revision 221a2097e364410e12aa34d7c668aab224bd16b4)
@@ -23,4 +23,16 @@
   <div class="cirkel-post-body"><%= post.body %></div>
 
+  <% if (post.tags && post.tags.length) { %>
+    <div class="cirkel-post-tags">
+      <% post.tags.forEach(function(t){ %>
+        <% if (post.sourceTagBase) { %>
+          <a class="cirkel-tag" href="<%= post.sourceTagBase %>/tag/<%= encodeURIComponent(t) %>" target="_blank" rel="noopener">#<%= t %></a>
+        <% } else { %>
+          <span class="cirkel-tag">#<%= t %></span>
+        <% } %>
+      <% }); %>
+    </div>
+  <% } %>
+
   <% if (post.originalUrl) { %>
     <p class="cirkel-post-readmore">
@@ -42,4 +54,7 @@
 .cirkel-post-cover { width: 100%; border-radius: var(--radius); margin: 0 0 1.5rem; display: block; }
 .cirkel-post-body { font-size: 1.05rem; line-height: 1.7; white-space: pre-wrap; color: var(--ink); }
+.cirkel-post-tags { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.25rem; }
+.cirkel-tag { font-size: .8rem; color: var(--ink-muted); background: var(--paper-2); border: 1px solid var(--rule); border-radius: 999px; padding: .15rem .6rem; text-decoration: none; }
+.cirkel-tag:hover { border-color: var(--accent); color: var(--accent); }
 .cirkel-post-readmore { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }
 .cirkel-post-readmore a { color: var(--accent); text-decoration: none; font-weight: 600; }
