diff --git a/apps/web/src/features/i18n/locales/en-US.json b/apps/web/src/features/i18n/locales/en-US.json
index 6a901d12ef..b4cc878dee 100644
--- a/apps/web/src/features/i18n/locales/en-US.json
+++ b/apps/web/src/features/i18n/locales/en-US.json
@@ -4190,40 +4190,40 @@
"prompt-dismiss": "No thanks",
"suspended-title-creator": "Your email digest is suspended (since {{since}})",
"suspended-title-community": "This community's email digest is suspended (since {{since}})",
- "suspended-reason-complaints": "Too many recipients marked recent issues as spam. Sending is paused to protect every Ecency sender's deliverability.",
+ "suspended-reason-complaints": "Too many recipients marked recent digests as spam. Sending is paused to protect every Ecency sender's deliverability.",
"suspended-reason-bounces": "Too many recent recipients could not be delivered to. Sending is paused to protect every Ecency sender's deliverability.",
- "suspended-reason-manual": "Sending is paused by Ecency. No new issues go out until it is lifted.",
+ "suspended-reason-manual": "Sending is paused by Ecency. No new digests go out until it is lifted.",
"suspended-help": "Existing subscribers are kept. Contact Ecency support to have the suspension reviewed.",
"send-to-subscribers": "Send to email subscribers",
"send-title": "Send to {{list}} email subscribers",
"send-loading": "Preparing the preview…",
- "send-readers": "{{weekly}} weekly and {{monthly}} monthly readers will get this as their current issue.",
+ "send-readers": "{{weekly}} weekly and {{monthly}} monthly readers will get this as their current digest.",
"send-no-readers": "Nobody is subscribed to this list yet.",
- "send-period-taken-some": "The {{cadences}} readers already received this period's issue; they will not get this one.",
- "send-period-taken-all": "This period's issue has already gone out to every reader. The next one can be sent in the next period.",
- "send-one-per-period": "Readers get at most one issue per period they chose (weekly or monthly). Sending this replaces the automatic digest for the period.",
+ "send-period-taken-some": "The {{cadences}} readers already received this period's digest; they will not get this one.",
+ "send-period-taken-all": "This period's digest has already gone out to every reader. The next one can be sent in the next period.",
+ "send-one-per-period": "Readers get at most one digest per period they chose (weekly or monthly). Sending this replaces the automatic digest for the period.",
"send-preview": "Email preview",
"send-now": "Send now",
"send-done": "Sent to {{count}} readers. Delivery is spread over the next hours.",
"send-done-line": "{{cadence}} readers: {{recipients}}",
- "send-already-sent": "This period's issue has already gone out. Try again in the next period.",
+ "send-already-sent": "This period's digest has already gone out. Try again in the next period.",
"send-suspended": "Sending is suspended for this list. See the notice on your profile or community page.",
"send-post-refused": "This post cannot be sent to the list.",
"send-post-not-found": "The post could not be found.",
"send-not-allowed": "You cannot send to this list.",
"cadence-weekly": "weekly",
"cadence-monthly": "monthly",
- "sent-issues": "Sent issues",
+ "sent-issues": "Sent digests",
"sent-issue-stats": "{{delivered}} delivered, {{bounced}} bounced",
- "send-taken-line": "{{cadence}} readers: the issue for the period starting {{period}} {{what}}",
+ "send-taken-line": "{{cadence}} readers: the digest for the period starting {{period}} {{what}}",
"send-taken-by-digest": "was the automatic digest",
"send-taken-by-send": "was sent by you or your team",
- "send-see-history": "See sent issues",
- "sent-issues-unavailable": "Sent issues could not be loaded right now.",
+ "send-see-history": "See sent digests",
+ "sent-issues-unavailable": "Sent digests could not be loaded right now.",
"sent-issue-rejected": "{{rejected}} rejected by receivers",
"compose-button": "Compose email digest",
"compose-title": "Compose an email digest for {{list}}",
- "compose-help": "Pick {{min}} to {{max}} recent posts, in the order they should appear, then add a subject and an intro. Readers get it as their current issue.",
+ "compose-help": "Pick {{min}} to {{max}} recent posts, in the order they should appear, then add a subject and an intro. Readers get it as their current digest.",
"compose-loading": "Loading your recent posts…",
"compose-candidates-unavailable": "Recent posts could not be loaded right now.",
"compose-no-candidates": "No recent posts can be sent yet.",
diff --git a/apps/web/src/features/newsletter/sent-issues.tsx b/apps/web/src/features/newsletter/sent-issues.tsx
index a18fae6452..b1306bed3a 100644
--- a/apps/web/src/features/newsletter/sent-issues.tsx
+++ b/apps/web/src/features/newsletter/sent-issues.tsx
@@ -24,7 +24,7 @@ export function SentIssues({
type,
target,
isSender,
- limit = 5,
+ limit = 3,
className
}: {
type: "creator" | "community";
diff --git a/apps/web/src/specs/features/newsletter/author-send.spec.tsx b/apps/web/src/specs/features/newsletter/author-send.spec.tsx
index 5146eaaed2..320a8658b2 100644
--- a/apps/web/src/specs/features/newsletter/author-send.spec.tsx
+++ b/apps/web/src/specs/features/newsletter/author-send.spec.tsx
@@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ReactElement, ReactNode } from "react";
import { QueryClientProvider } from "@tanstack/react-query";
import { NewsletterRuntimeProvider } from "@/features/newsletter/runtime";
-import { AuthorSendDialog, candidatesKey, communityDigestRoles, ComposeDigestButton, ComposeDigestDialog, sendPreviewKey, SentIssues, useAuthorSendTarget } from "@/features/newsletter";
+import { AuthorSendDialog, candidatesKey, communityDigestRoles, ComposeDigestButton, ComposeDigestDialog, sendPreviewKey, type SentIssue, SentIssues, useAuthorSendTarget } from "@/features/newsletter";
import { useActiveAccount } from "@/core/hooks/use-active-account";
import {
cleanupModalContainers,
@@ -221,6 +221,18 @@ describe("SentIssues", () => {
render();
await waitFor(() => expect(screen.getByText("newsletter.sent-issues-unavailable")).toBeInTheDocument());
});
+
+ it("shows only the 3 most recent issues, keeping the card compact", async () => {
+ const issue = (n: number): SentIssue => ({ id: String(n), cadence: "weekly", kind: "digest", period_start: `2026-08-0${n}`, subject: `Issue ${n}`, status: "sent", post_author: null, post_permlink: null, requested_by: null, created_at: `2026-08-0${n}T09:00:00Z`, delivered: n, bounced: 0, rejected: 0 });
+ fetchMock.mockReturnValue(json(200, { issues: [issue(4), issue(3), issue(2), issue(1)] }));
+ render();
+ const list = await screen.findByRole("list", { name: "newsletter.sent-issues" });
+ expect(list.querySelectorAll("li")).toHaveLength(3);
+ expect(list).toHaveTextContent("Issue 4");
+ expect(list).toHaveTextContent("Issue 3");
+ expect(list).toHaveTextContent("Issue 2");
+ expect(list).not.toHaveTextContent("Issue 1");
+ });
});
describe("ComposeDigestDialog", () => {