Repository navigation
Description
Background
Newsletter tools give every issue its own public web page, which search engines can find. They also offer a "view in browser" link and a per-publication archive. beehiiv, Substack and Kit all have this, and Marc Lou's MailCheap (open source, a "cheaper beehiiv" on your own SES, launched 17 Oct 2026) lists it as a headline feature: "Every issue gets its own web page that search engines can find."
SendLit doesn't have it today. The only public routes are /track/*, unsubscribe and /health. Nothing renders a broadcast as a web page, there's no archive, and no merge tag links to a browser version. That's a gap for the newsletter persona, and it loses SEO and discovery that would otherwise compound for senders. Comparisons with beehiiv and Substack will mark SendLit down on it.
Proposed fix
Data and API
- Add web publishing settings per broadcast:
webPublished(bool, default off, or a team-level default),slug,publishedAt,seoTitle,seoDescription,ogImage,noindex. - Add team-level archive settings:
archiveEnabled, a title and description, and an optional custom domain later. - Expose these in
@sendlit/api-contractand the OpenAPI doc, plus read endpoints so platforms can render the archive themselves:GET /web/issues: a paginated list of published broadcasts for a team, giving title, slug, publishedAt and excerpt.GET /web/issues/:slug: rendered, sanitized HTML plus metadata.
- MCP tools for publishing and unpublishing, so agents can manage it too.
Hosted pages (SendLit-hosted option)
- A public issue page at
/{team-handle}/p/{slug}, or on a team subdomain. It renders the broadcast HTML with all personal and tracking content removed (see below). - A public archive at
/{team-handle}, listing published issues newest first, with a subscribe form that creates a contact (sosubscriber:addedsequences fire). - SEO tags on both: title and description, a canonical URL (or a sender-supplied canonical when a platform hosts the page), Open Graph and Twitter tags,
ArticleJSON-LD, an RSS feed and a sitemap, plusnoindexwhen the sender asks for it.
Email side
- A
{{web_version_url}}merge tag (a "view in browser" link) and an optional default footer link when the issue is published.
Safety
- Before rendering on the web, strip merge-tag personalization, unsubscribe and tracking links, open pixels and any per-contact content. Fall back to a generic value for each personal field.
- Unpublished or draft broadcasts return 404. Unpublishing removes the page and the sitemap entry.
- Sanitize HTML (no scripts), and cache with sensible headers.
Embedded and platform use (CourseLit and others)
- A platform can turn off SendLit hosting and use the API above (and later the SDK, TypeScript SDK for SendLit (for CourseLit campaign sending; CLI-ready, MediaLit-style) #61) to render issues inside its own site, with its own canonical URL.
Acceptance criteria
- A broadcast can be marked "publish to web" in the UI, through the API and through MCP. It gets a stable slug, and the setting can be turned off again.
- Published issues render at a public URL, with no personal data, tracking pixels or unsubscribe tokens. Tests cover this.
- A team archive page lists published issues and includes a working subscribe form that creates a contact and triggers
subscriber:added. - Pages include title, meta description, canonical, OG and Twitter tags, and
ArticleJSON-LD. Thenoindexoption is respected. An RSS feed and sitemap are generated. - The
{{web_version_url}}merge tag works in broadcasts and resolves to the public page. -
GET /web/issuesandGET /web/issues/:slugare in api-contract and OpenAPI, so a platform can render the archive itself. - Unpublished or deleted broadcasts return 404 and are removed from the sitemap and RSS feed.
- Docs page explaining web publishing and the platform API option.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity