Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision cb3001e6d3bf4bb9612f2f29fd9500d493bf84bb)
+++ src/services/ActivityPubService.js	(revision aed0092c4492bca99e1c9a5c82332c1d08fe1bee)
@@ -29,5 +29,5 @@
 import Blocklist from './BlocklistService.js';
 import * as Guardianship from './guardianship/index.js';
-import { PUBLIC, AP_CONTEXT, safeUrl, actorId, noteId, guessMediaType, normalizeTags, tagParts, hashtagTags, buildHashtagList } from './ap-core.js';
+import { PUBLIC, AP_CONTEXT, safeUrl, actorId, noteId, guessMediaType, normalizeTags, tagParts, hashtagTags, buildHashtagList, pagedCollection } from './ap-core.js';
 // Doorgeven wat hier altijd vandaan kwam, zodat elke bestaande aanroep blijft werken.
 export { AP_CONTEXT, actorId, noteId, guessMediaType };
@@ -1043,24 +1043,5 @@
   // wie hem vandaag leest hoort er morgen niet voor te hoeven pagineren. Er is
   // precies een pagina, dus first en last wijzen naar dezelfde.
-  const eerste = `${id}?page=1`;
-  if (page) {
-    return {
-      '@context': AP_CONTEXT,
-      id: eerste,
-      type: 'OrderedCollectionPage',
-      partOf: id,
-      totalItems: items.length,
-      orderedItems: items,
-    };
-  }
-  return {
-    '@context': AP_CONTEXT,
-    id,
-    type: 'OrderedCollection',
-    totalItems: items.length,
-    first: eerste,
-    last: eerste,
-    orderedItems: items,
-  };
+  return pagedCollection(id, items, { page });
 }
 
@@ -1070,11 +1051,6 @@
 export function buildFollowers(base, site, count, items = null) {
   const id = `${actorId(base, site.slug)}/followers`;
-  return {
-    '@context': AP_CONTEXT,
-    id,
-    type: 'OrderedCollection',
-    totalItems: items ? items.length : (count || 0),
-    orderedItems: items || [], // count-only for the public; full for the owner
-  };
+  // count-only for the public; full for the owner
+  return pagedCollection(id, items || [], { totalItems: items ? items.length : (count || 0) });
 }
 
@@ -1083,11 +1059,6 @@
 export function buildFollowing(base, site, count, items = null) {
   const id = `${actorId(base, site.slug)}/following`;
-  return {
-    '@context': AP_CONTEXT,
-    id,
-    type: 'OrderedCollection',
-    totalItems: items ? items.length : (count || 0),
-    orderedItems: items || [], // count-only for the public; full for the owner
-  };
+  // count-only for the public; full for the owner
+  return pagedCollection(id, items || [], { totalItems: items ? items.length : (count || 0) });
 }
 
@@ -1098,11 +1069,5 @@
   const id = `${actorId(base, site.slug)}/featured`;
   const items = (posts || []).map((p) => buildNote(base, site, p));
-  return {
-    '@context': AP_CONTEXT,
-    id,
-    type: 'OrderedCollection',
-    totalItems: items.length,
-    orderedItems: items,
-  };
+  return pagedCollection(id, items);
 }
 
@@ -6555,5 +6520,5 @@
 
 export default {
-  AP_CONTEXT, getOrCreateKeys, apWants, sendAP, actorId, noteId, stripLeadingMentions,
+  AP_CONTEXT, getOrCreateKeys, apWants, sendAP, actorId, noteId, stripLeadingMentions, pagedCollection,
   buildActor, buildNote, buildCreate, buildOutbox, buildFollowers, buildFollowing, buildFeatured,
   channelUrls, channelCategory, timelineFields, guessMediaType,
