diff --git a/packages/desktop-client/src/components/accounts/Account.jsx b/packages/desktop-client/src/components/accounts/Account.jsx
index 3153fd749fa3bd69450fa8392bff51830695b916..28f169dd7ce8998eaeaa558c65626fa61f7bd453 100644
--- a/packages/desktop-client/src/components/accounts/Account.jsx
+++ b/packages/desktop-client/src/components/accounts/Account.jsx
@@ -101,12 +101,15 @@ function AllTransactions({
   showBalances,
   filtered,
   children,
+  collapseTransactions,
 }) {
   const accountId = account.id;
-  const prependTransactions = usePreviewTransactions().map(trans => ({
-    ...trans,
-    _inverse: accountId ? accountId !== trans.account : false,
-  }));
+  const prependTransactions = usePreviewTransactions(collapseTransactions).map(
+    trans => ({
+      ...trans,
+      _inverse: accountId ? accountId !== trans.account : false,
+    }),
+  );
 
   transactions ??= [];
 
@@ -1453,6 +1456,9 @@ class AccountInternal extends PureComponent {
         balances={balances}
         showBalances={showBalances}
         filtered={transactionsFiltered}
+        collapseTransactions={ids =>
+          this.props.splitsExpandedDispatch({ type: 'close-splits', ids })
+        }
       >
         {(allTransactions, allBalances) => (
           <SelectedProviderWithItems
diff --git a/packages/desktop-client/src/components/mobile/transactions/Transaction.jsx b/packages/desktop-client/src/components/mobile/transactions/Transaction.jsx
index 285bbc4e7f742a69dff971f3bff8a13c19c59942..85c8100e9accd101a7e4af71ffab8a19a8ee9d8d 100644
--- a/packages/desktop-client/src/components/mobile/transactions/Transaction.jsx
+++ b/packages/desktop-client/src/components/mobile/transactions/Transaction.jsx
@@ -70,7 +70,6 @@ export const Transaction = memo(function Transaction({
     cleared,
     is_parent: isParent,
     is_child: isChild,
-    notes,
     schedule,
   } = transaction;
 
@@ -183,7 +182,7 @@ export const Transaction = memo(function Transaction({
               </TextOneLine>
             </View>
             {isPreview ? (
-              <Status status={notes} />
+              <Status status={categoryId} isSplit={isParent || isChild} />
             ) : (
               <View
                 style={{
diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
index 3cb7db7644b30284a644085e9d37a60be96499e4..b21dfbd3b45dc1c70098f4ebb31aeaff9f3ad982 100644
--- a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
+++ b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
@@ -132,7 +132,7 @@ export function lookupName(items, id) {
   return items.find(item => item.id === id)?.name;
 }
 
-export function Status({ status }) {
+export function Status({ status, isSplit }) {
   let color;
 
   switch (status) {
@@ -157,7 +157,7 @@ export function Status({ status }) {
         textAlign: 'left',
       }}
     >
-      {titleFirst(status)}
+      {titleFirst(status) + (isSplit ? ' (Split)' : '')}
     </Text>
   );
 }
diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx
index 34a310e531c52df3f3f3d36d4039f1bdfcc0a203..48c1dd97b1fdbe7ebca1369283739110d0e94001 100644
--- a/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx
+++ b/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx
@@ -138,6 +138,10 @@ export function TransactionList({
               key={section.id}
             >
               {section.data.map((transaction, index, transactions) => {
+                if (isPreviewId(transaction.id) && transaction.is_child) {
+                  return null;
+                }
+
                 return (
                   <Item
                     key={transaction.id}
diff --git a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
index c421da17e5c154b7c272081e97779fbdbadd2333..20ba4a19446deedc867cc12012ec3aaad19107d6 100644
--- a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
+++ b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
@@ -575,9 +575,11 @@ function PayeeCell({
           alignSelf: 'flex-start',
           borderRadius: 4,
           border: '1px solid transparent', // so it doesn't shift on hover
-          ':hover': {
-            border: '1px solid ' + theme.buttonNormalBorder,
-          },
+          ':hover': isPreview
+            ? {}
+            : {
+                border: '1px solid ' + theme.buttonNormalBorder,
+              },
         }}
         disabled={isPreview}
         onSelect={() =>
@@ -601,6 +603,12 @@ function PayeeCell({
             color: theme.pageTextSubdued,
           }}
         >
+          <PayeeIcons
+            transaction={transaction}
+            transferAccount={transferAccount}
+            onNavigateToTransferAccount={onNavigateToTransferAccount}
+            onNavigateToSchedule={onNavigateToSchedule}
+          />
           <SvgSplit
             style={{
               color: 'inherit',
@@ -1110,6 +1118,8 @@ const Transaction = memo(function Transaction({
         ) : (
           <Cell width={20} />
         )
+      ) : isPreview && isChild ? (
+        <Cell width={20} />
       ) : (
         <SelectCell
           /* Checkmark field for non-child transaction */
@@ -1246,45 +1256,52 @@ const Transaction = memo(function Transaction({
         />
       ))()}
 
-      {isPreview ? (
-        /* Notes field for all transactions */
-        <Cell name="notes" width="flex" />
-      ) : (
-        <InputCell
+      <InputCell
+        width="flex"
+        name="notes"
+        textAlign="flex"
+        exposed={focusedField === 'notes'}
+        focused={focusedField === 'notes'}
+        value={notes || ''}
+        valueStyle={valueStyle}
+        formatter={value => notesTagFormatter(value, onNotesTagClick)}
+        onExpose={name => !isPreview && onEdit(id, name)}
+        inputProps={{
+          value: notes || '',
+          onUpdate: onUpdate.bind(null, 'notes'),
+        }}
+      />
+
+      {(isPreview && !isChild) || isParent ? (
+        <Cell
+          /* Category field (Split button) for parent transactions */
+          name="category"
           width="flex"
-          name="notes"
-          textAlign="flex"
-          exposed={focusedField === 'notes'}
-          focused={focusedField === 'notes'}
-          value={notes || ''}
-          valueStyle={valueStyle}
-          formatter={value => notesTagFormatter(value, onNotesTagClick)}
-          onExpose={name => !isPreview && onEdit(id, name)}
-          inputProps={{
-            value: notes || '',
-            onUpdate: onUpdate.bind(null, 'notes'),
+          focused={focusedField === 'category'}
+          style={{
+            padding: 0,
+            flexDirection: 'row',
+            alignItems: 'center',
+            justifyContent: 'flex-start',
+            height: '100%',
           }}
-        />
-      )}
-
-      {isPreview ? (
-        // Category field for preview transactions
-        <Cell width="flex" style={{ alignItems: 'flex-start' }} exposed={true}>
-          {() => (
+          plain
+        >
+          {isPreview && (
             <View
               style={{
                 color:
-                  notes === 'missed'
+                  categoryId === 'missed'
                     ? theme.errorText
-                    : notes === 'due'
+                    : categoryId === 'due'
                       ? theme.warningText
                       : selected
                         ? theme.formLabelText
                         : theme.upcomingText,
                 backgroundColor:
-                  notes === 'missed'
+                  categoryId === 'missed'
                     ? theme.errorBackground
-                    : notes === 'due'
+                    : categoryId === 'due'
                       ? theme.warningBackground
                       : selected
                         ? theme.formLabelBackground
@@ -1294,23 +1311,12 @@ const Transaction = memo(function Transaction({
                 borderRadius: 4,
               }}
             >
-              {titleFirst(notes)}
+              {titleFirst(categoryId)}
             </View>
           )}
-        </Cell>
-      ) : isParent ? (
-        <Cell
-          /* Category field (Split button) for parent transactions */
-          name="category"
-          width="flex"
-          focused={focusedField === 'category'}
-          style={{ padding: 0 }}
-          plain
-        >
           <CellButton
             bare
             style={{
-              alignSelf: 'flex-start',
               borderRadius: 4,
               border: '1px solid transparent', // so it doesn't shift on hover
               ':hover': {
@@ -1318,7 +1324,7 @@ const Transaction = memo(function Transaction({
               },
             }}
             disabled={isTemporaryId(transaction.id)}
-            onEdit={() => onEdit(id, 'category')}
+            onEdit={() => !isPreview && onEdit(id, 'category')}
             onSelect={() => onToggleSplit(id)}
           >
             <View
@@ -1343,15 +1349,17 @@ const Transaction = memo(function Transaction({
                   }}
                 />
               )}
-              <Text
-                style={{
-                  fontStyle: 'italic',
-                  fontWeight: 300,
-                  userSelect: 'none',
-                }}
-              >
-                Split
-              </Text>
+              {!isPreview && (
+                <Text
+                  style={{
+                    fontStyle: 'italic',
+                    fontWeight: 300,
+                    userSelect: 'none',
+                  }}
+                >
+                  Split
+                </Text>
+              )}
             </View>
           </CellButton>
         </Cell>
@@ -1402,7 +1410,7 @@ const Transaction = memo(function Transaction({
                 : ''
           }
           exposed={focusedField === 'category'}
-          onExpose={name => onEdit(id, name)}
+          onExpose={name => !isPreview && onEdit(id, name)}
           valueStyle={
             !categoryId
               ? {
@@ -1532,7 +1540,7 @@ const Transaction = memo(function Transaction({
           isPreview={isPreview}
           status={
             isPreview
-              ? notes
+              ? categoryId
               : reconciled
                 ? 'reconciled'
                 : cleared
diff --git a/packages/desktop-client/src/hooks/usePreviewTransactions.ts b/packages/desktop-client/src/hooks/usePreviewTransactions.ts
index 4f4f57b3ef02c4db93fb84b5247e0987371ae894..786e369c311eccc4dc19854208410a89adff3cd4 100644
--- a/packages/desktop-client/src/hooks/usePreviewTransactions.ts
+++ b/packages/desktop-client/src/hooks/usePreviewTransactions.ts
@@ -1,34 +1,66 @@
-import { useMemo } from 'react';
+import { useState } from 'react';
 
 import {
   type ScheduleStatuses,
   useCachedSchedules,
 } from 'loot-core/client/data-hooks/schedules';
+import { send } from 'loot-core/platform/client/fetch';
+import { ungroupTransactions } from 'loot-core/shared/transactions';
 import { type ScheduleEntity } from 'loot-core/types/models';
 
-export function usePreviewTransactions() {
+import { type TransactionEntity } from '../../../loot-core/src/types/models/transaction.d';
+
+export function usePreviewTransactions(
+  collapseTransactions: (ids: string[]) => void,
+) {
   const scheduleData = useCachedSchedules();
+  const [previousScheduleData, setPreviousScheduleData] =
+    useState<ReturnType<typeof useCachedSchedules>>(scheduleData);
+  const [previewTransactions, setPreviewTransactions] = useState<
+    TransactionEntity[]
+  >([]);
+
+  if (scheduleData !== previousScheduleData) {
+    setPreviousScheduleData(scheduleData);
+
+    if (scheduleData) {
+      // Kick off an async rules application
+      const schedules =
+        scheduleData.schedules.filter(s =>
+          isForPreview(s, scheduleData.statuses),
+        ) || [];
 
-  return useMemo(() => {
-    if (!scheduleData) {
-      return [];
+      const baseTrans = schedules.map(schedule => ({
+        id: 'preview/' + schedule.id,
+        payee: schedule._payee,
+        account: schedule._account,
+        amount: schedule._amount,
+        date: schedule.next_date,
+        schedule: schedule.id,
+      }));
+
+      Promise.all(
+        baseTrans.map(transaction => send('rules-run', { transaction })),
+      ).then(newTrans => {
+        const withDefaults = newTrans.map(t => ({
+          ...t,
+          category: scheduleData.statuses.get(t.schedule),
+          schedule: t.schedule,
+          subtransactions: t.subtransactions?.map((st: TransactionEntity) => ({
+            ...st,
+            id: 'preview/' + st.id,
+            schedule: t.schedule,
+          })),
+        }));
+        setPreviewTransactions(ungroupTransactions(withDefaults));
+        collapseTransactions(withDefaults.map(t => t.id));
+      });
     }
 
-    const schedules =
-      scheduleData.schedules.filter(s =>
-        isForPreview(s, scheduleData.statuses),
-      ) || [];
-
-    return schedules.map(schedule => ({
-      id: 'preview/' + schedule.id,
-      payee: schedule._payee,
-      account: schedule._account,
-      amount: schedule._amount,
-      date: schedule.next_date,
-      notes: scheduleData.statuses.get(schedule.id),
-      schedule: schedule.id,
-    }));
-  }, [scheduleData]);
+    return previewTransactions;
+  }
+
+  return previewTransactions;
 }
 
 function isForPreview(schedule: ScheduleEntity, statuses: ScheduleStatuses) {
diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.jsx b/packages/desktop-client/src/hooks/useSplitsExpanded.jsx
index 15e1a3cdebbbb6bf46169db34950f49ae387c036..8b8bb4ed2495d1b5b74774d194309af34bd69be9 100644
--- a/packages/desktop-client/src/hooks/useSplitsExpanded.jsx
+++ b/packages/desktop-client/src/hooks/useSplitsExpanded.jsx
@@ -51,6 +51,17 @@ export function SplitsExpandedProvider({ children, initialMode = 'expand' }) {
           }
           return { ...state, ids };
         }
+        case 'close-splits': {
+          const ids = new Set([...state.ids]);
+          action.ids.forEach(id => {
+            if (state.mode === 'collapse') {
+              ids.add(id);
+            } else {
+              ids.delete(id);
+            }
+          });
+          return { ...state, ids };
+        }
         case 'set-mode': {
           return {
             ...state,
diff --git a/upcoming-release-notes/2923.md b/upcoming-release-notes/2923.md
new file mode 100644
index 0000000000000000000000000000000000000000..3fffdc22d4d8f11e2fcbd29fcfd4143bcecd265f
--- /dev/null
+++ b/upcoming-release-notes/2923.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [jfdoming]
+---
+
+Show split transactions in schedule previews.