← All tools Syndicate elsewhere Open tool

Syndicate elsewhere

A simple, local-first publishing dashboard for syndicating blog posts and podcast episodes from RSS feeds to social platforms like Bluesky, Mastodon, Slack, LinkedIn, and Threads.

Overview

Syndicate Elsewhere is a lightweight, single-page HTML/JavaScript app that acts as a manual syndication inbox. It reads one or more RSS feeds, identifies content that has not yet been syndicated, and presents a queue of publishable items. You can review, edit, and publish a generated social post to one or more destinations with a single click.

The application is intentionally local-first, single-user, and manual rather than automated. RSS remains the source of truth — the app only stores references to feed entries plus your publication state. Everything lives in browser localStorage; there is no backend.

Note on Slack: Slack's webhook endpoint does not send CORS headers, so the browser cannot read its response. The app sends the post and treats a successful network request as success — it cannot detect a Slack-side rejection (e.g. a revoked webhook). Use Test Connection to confirm messages arrive.

Note on LinkedIn & Threads: Their APIs cannot be called from a backendless browser app (they block cross-origin requests and require an OAuth token that can't be stored safely client-side). These use assisted posting instead: publishing opens the platform's web composer with your draft prefilled where possible, and the item is marked published once the composer opens — you complete the post there. For Threads the text is prefilled via its web intent; for LinkedIn the share dialog opens for the article and your post text is copied to the clipboard (LinkedIn does not allow prefilling commentary). Allow pop-ups for this site so the composer can open.

Features

Usage

  1. Open index.html in a browser (or run npm start from the repo root).
  2. Go to Settings and enable the destinations you want. Bluesky, Mastodon, and Slack take credentials (use Test Connection to verify); for Slack, create an Incoming Webhook for the target channel and paste its URL. LinkedIn and Threads need no credentials — just enable them (they use assisted posting; see the note above).
  3. Go to Feeds, add an RSS feed (Name, URL, Type), optionally Validate Feed, then Save Feed.
  4. Click ↻ Refresh Feeds in the header.
  5. On the Queue, click Compose & Publish on a card, edit the draft, choose destinations, and Publish Selected.
  6. Return later and refresh — only content you haven't fully published (and haven't skipped) appears.

CORS proxy

Most RSS feeds do not send CORS headers, so browsers block fetching them directly. Syndicate Elsewhere tries a direct fetch first and falls back to a configurable CORS proxy (set in Settings → General). The Bluesky and Mastodon APIs themselves are called directly and support CORS.

The default proxy is /rss-proxy?url=, served by the bundled Netlify edge function at netlify/edge-functions/rss-proxy.ts (the deployed equivalent of a Cloudflare Worker). It works automatically on the deployed Netlify site, or locally when you run netlify dev. The function only proxies http(s) URLs and refuses localhost / private-network targets to avoid being an abusable open proxy.

For other local setups (e.g. opening the file directly or npm start), either run netlify dev, or change the proxy to a public one such as https://api.allorigins.win/raw?url=, or clear it to disable the fallback.

Templates

Each content type has an editable template. Available variables:

{title} · {url} · {summary} · {shortDescription} · {description} · {author} · {feedName} · {publishedDate}

Defaults:

Blog:    New post: {title}\n\n{url}
Podcast: New episode: {title}\n\n{shortDescription}\n\nListen: {url}

Data & Security

All state — feeds, templates, credentials, and publication history — is stored under the syndicateElsewhere key in browser localStorage. Credentials (Bluesky app password, Mastodon token, Slack webhook URL) are stored in plain text locally, which is acceptable for a single-user, local-first tool with no shared backend. LinkedIn and Threads store no credentials at all (assisted posting). Use app passwords / scoped tokens, treat the Slack webhook URL as a secret, and use Reset All Data to wipe everything.

Technical Details

Browser Compatibility

Works in modern Chrome, Firefox, Safari, and Edge.

Roadmap

Planned future enhancements include image/OpenGraph support, platform-specific drafts and preview cards, scheduling, batch publishing, AI-assisted drafts, and additional destinations (Discord, Ghost, Micro.blog, etc.). Slack support could be extended with Block Kit formatting and per-post channel overrides (it currently posts the body plus a content-card attachment); LinkedIn and Threads could gain true one-click API posting if a small backend/OAuth relay is added (they currently use assisted posting).

License

See repository root for license information.