diff --git a/keyserver/src/creators/thread-creator.js b/keyserver/src/creators/thread-creator.js
--- a/keyserver/src/creators/thread-creator.js
+++ b/keyserver/src/creators/thread-creator.js
@@ -33,7 +33,10 @@
 } from './role-creator.js';
 import type { UpdatesForCurrentSession } from './update-creator.js';
 import { dbQuery, SQL } from '../database/database.js';
-import { fetchMessageInfoByID } from '../fetchers/message-fetchers.js';
+import {
+  fetchLatestEditMessageContentByID,
+  fetchMessageInfoByID,
+} from '../fetchers/message-fetchers.js';
 import {
   determineThreadAncestry,
   personalThreadQuery,
@@ -421,13 +424,26 @@
       throw new ServerError('invalid_parameters');
     }
 
+    let editedSourceMessage = sourceMessage;
+    if (sourceMessageID && sourceMessage.type === messageTypes.TEXT) {
+      const editMessageContent = await fetchLatestEditMessageContentByID(
+        sourceMessageID,
+      );
+      if (editMessageContent) {
+        editedSourceMessage = {
+          ...sourceMessage,
+          text: editMessageContent.text,
+        };
+      }
+    }
+
     messageDatas.push(
       {
         type: messageTypes.SIDEBAR_SOURCE,
         threadID: id,
         creatorID: viewer.userID,
         time,
-        sourceMessage,
+        sourceMessage: editedSourceMessage,
       },
       {
         type: messageTypes.CREATE_SIDEBAR,
diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -15,6 +15,7 @@
   type RawRobotextMessageInfo,
   messageTypes,
   type MessageType,
+  type EditMessageContent,
   assertMessageType,
   type MessageSelectionCriteria,
   type MessageTruncationStatus,
@@ -645,7 +646,7 @@
 
 async function fetchMessageRowsByIDs(messageIDs: $ReadOnlyArray<string>) {
   const query = SQL`
-    SELECT m.id, m.thread AS threadID, m.content, m.time, m.type, m.creation, 
+    SELECT m.id, m.thread AS threadID, m.content, m.time, m.type, m.creation,
       m.user AS creatorID, m.target_message as targetMessageID,
       stm.permissions AS subthread_permissions, up.id AS uploadID,
       up.type AS uploadType, up.secret AS uploadSecret, up.extra AS uploadExtra
@@ -681,11 +682,14 @@
     return messagesByID;
   }
 
-  const result = await fetchMessageRowsByIDs([...requiredIDs]);
+  const [result, edits] = await Promise.all([
+    fetchMessageRowsByIDs([...requiredIDs]),
+    fetchLatestEditMessageContentByIDs([...requiredIDs]),
+  ]);
   const messages = await parseMessageSQLResult(result, new Map(), viewer);
 
   for (const message of messages) {
-    const { rawMessageInfo } = message;
+    let { rawMessageInfo } = message;
     if (rawMessageInfo.id) {
       invariant(
         rawMessageInfo.type !== messageTypes.SIDEBAR_SOURCE &&
@@ -693,6 +697,14 @@
           rawMessageInfo.type !== messageTypes.EDIT_MESSAGE,
         'SIDEBAR_SOURCE should not point to a SIDEBAR_SOURCE, REACTION or EDIT_MESSAGE',
       );
+      const editedContent = edits.get(rawMessageInfo.id);
+      if (editedContent && rawMessageInfo.type === messageTypes.TEXT) {
+        rawMessageInfo = {
+          ...rawMessageInfo,
+          text: editedContent.text,
+        };
+      }
+      invariant(rawMessageInfo.id, 'rawMessageInfo.id should not be null');
       messagesByID.set(rawMessageInfo.id, rawMessageInfo);
     }
   }
@@ -721,6 +733,44 @@
   return result[0].count;
 }
 
+async function fetchLatestEditMessageContentByIDs(
+  messageIDs: $ReadOnlyArray<string>,
+): Promise<$ReadOnlyMap<string, EditMessageContent>> {
+  const latestEditedMessageQuery = SQL`
+    SELECT m.id, (
+      SELECT m2.content
+      FROM messages m2
+      WHERE m.id = m2.target_message
+        AND m.thread = m2.thread
+        AND m2.type = ${messageTypes.EDIT_MESSAGE}
+      ORDER BY time DESC, id DESC
+      LIMIT 1
+    ) content
+    FROM messages m
+    WHERE m.id IN(${messageIDs})
+  `;
+
+  const [result] = await dbQuery(latestEditedMessageQuery);
+  const latestContentByID = new Map();
+  for (const row of result) {
+    if (!row.content) {
+      continue;
+    }
+    const content = JSON.parse(row.content);
+    latestContentByID.set(row.id.toString(), content);
+  }
+
+  return latestContentByID;
+}
+
+async function fetchLatestEditMessageContentByID(
+  messageID: string,
+): Promise<?EditMessageContent> {
+  const result = await fetchLatestEditMessageContentByIDs([messageID]);
+  const content = result.get(messageID);
+  return content;
+}
+
 export {
   fetchCollapsableNotifs,
   fetchMessageInfos,
@@ -730,4 +780,5 @@
   fetchMessageInfoForEntryAction,
   fetchMessageInfoByID,
   fetchThreadMessagesCount,
+  fetchLatestEditMessageContentByID,
 };
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -575,6 +575,10 @@
 export type EditMessagePayload = SendEditMessageResponse;
 export type SendEditMessageResult = SendEditMessageResponse;
 
+export type EditMessageContent = {
+  +text: string,
+};
+
 // Used for the message info included in log-in type actions
 export type GenericMessagesResult = {
   +messageInfos: RawMessageInfo[],