Index: src/services/PlatformIcons.js
===================================================================
--- src/services/PlatformIcons.js	(revision 31680c3360308110ee32435ada564ef21f612bce)
+++ src/services/PlatformIcons.js	(revision 746d98a771aa1e4a4241958d88582d516570cf4b)
@@ -127,3 +127,35 @@
 }
 
-export default { PLATFORMS, PLATFORM_ORDER, listPlatforms, CONTACT_PLATFORMS, linkHref };
+/**
+ * De profiellinks uit een formulier (profile_link_platform[] + profile_link_url[])
+ * als de JSON die in sites.profile_links staat, of null als er niets over is.
+ *
+ * Stond in routes/admin-sites.js, toen de links op de Appearance-pagina stonden.
+ * Sinds 30-9 bewerk je ze bij je profiel (/account), en een tweede kopie van
+ * deze keuring loopt gegarandeerd uit de pas -- dus hij staat hier.
+ */
+export function buildProfileLinks(body) {
+  const platforms = (body && body.profile_link_platform) || [];
+  const urls = (body && body.profile_link_url) || [];
+  const arr = [];
+  const platformsArr = Array.isArray(platforms) ? platforms : [platforms];
+  const urlsArr      = Array.isArray(urls)      ? urls      : [urls];
+  for (let i = 0; i < platformsArr.length; i++) {
+    const p = (platformsArr[i] || '').toString().trim();
+    const u = (urlsArr[i] || '').toString().trim();
+    if (!p || !u) continue;
+    if (!PLATFORMS[p]) continue;
+    if (!/^https?:\/\//i.test(u) && p !== 'email') continue;
+    if (p === 'email' && !/^mailto:|^[^\s@]+@[^\s@]+$/i.test(u)) continue;
+    arr.push({ platform: p, url: u });
+  }
+  return arr.length ? JSON.stringify(arr) : null;
+}
+
+/** sites.profile_links terug als lijst; een kapotte waarde is een lege lijst. */
+export function parseProfileLinks(json) {
+  if (!json) return [];
+  try { const a = JSON.parse(json); return Array.isArray(a) ? a : []; } catch { return []; }
+}
+
+export default { PLATFORMS, PLATFORM_ORDER, listPlatforms, CONTACT_PLATFORMS, linkHref, buildProfileLinks, parseProfileLinks };
Index: src/services/i18n.js
===================================================================
--- src/services/i18n.js	(revision 31680c3360308110ee32435ada564ef21f612bce)
+++ src/services/i18n.js	(revision 746d98a771aa1e4a4241958d88582d516570cf4b)
@@ -843,5 +843,5 @@
     'acct.tagline': 'Tagline',
     'acct.tagline_hint': '— korte oneliner (optioneel)',
-    'acct.site_save': 'Site opslaan',
+    'ward.followers_only': 'Berichten van {name} zijn alleen te zien voor volgers.', 'asite.links_moved': 'Je profiellinks staan nu bij je profiel.', 'asite.links_moved_link': 'Naar je profiel', 'acct.links_save': 'Links opslaan', 'acct.link_platform': 'Platform', 'acct.link_url': 'Adres', 'acct.link_remove': 'Link weghalen', 'acct.site_save': 'Site opslaan',
     'acct.password_change': 'Wachtwoord wijzigen',
     'acct.password_current': 'Huidig wachtwoord',
@@ -1852,5 +1852,5 @@
     'acct.tagline': 'Tagline',
     'acct.tagline_hint': '— short one-liner (optional)',
-    'acct.site_save': 'Save site',
+    'ward.followers_only': 'Posts by {name} are only visible to followers.', 'asite.links_moved': 'Your profile links now live with your profile.', 'asite.links_moved_link': 'Go to your profile', 'acct.links_save': 'Save links', 'acct.link_platform': 'Platform', 'acct.link_url': 'Address', 'acct.link_remove': 'Remove link', 'acct.site_save': 'Save site',
     'acct.password_change': 'Change password',
     'acct.password_current': 'Current password',
@@ -2861,5 +2861,5 @@
     'acct.tagline': 'Slogan',
     'acct.tagline_hint': '— kurzer Einzeiler (optional)',
-    'acct.site_save': 'Seite speichern',
+    'ward.followers_only': 'Beiträge von {name} sind nur für Follower sichtbar.', 'asite.links_moved': 'Deine Profil-Links findest du jetzt bei deinem Profil.', 'asite.links_moved_link': 'Zum Profil', 'acct.links_save': 'Links speichern', 'acct.link_platform': 'Plattform', 'acct.link_url': 'Adresse', 'acct.link_remove': 'Link entfernen', 'acct.site_save': 'Seite speichern',
     'acct.password_change': 'Passwort ändern',
     'acct.password_current': 'Aktuelles Passwort',
