Blog
Writing about async video, EU data sovereignty, and building in the open.
-
How We Built Data Retention for SendRec
Configurable auto-deletion with pin exemptions, warning emails, and a two-pass background worker. Here's how we built GDPR-friendly data retention into SendRec.
-
SendRec Now Supports Team Workspaces
Create shared video libraries for your team with role-based permissions, video transfer, email invites, and workspace-level branding and billing. Available now.
-
How We Built a Welcome Email That Actually Gets Sent
Most SaaS welcome emails fire on sign-up. Ours fires after email confirmation — because that's when the user is actually ready. Here's how we wired it into our Go backend and Listmonk.
-
How We Added Silence Removal to SendRec
Screen recordings are full of dead air. Here's how we used ffmpeg's silencedetect filter, presigned S3 URLs, and a duration clamping fix to detect and remove silent pauses automatically.
-
How We Documented 95 API Endpoints with OpenAPI and Scalar
We wrote a 4,200-line OpenAPI spec for SendRec's REST API and serve interactive docs with Scalar — all embedded in the Go binary with zero external dependencies.
-
How We Added System Audio to Screen Recording
Most browser-based screen recorders capture video but not tab or system audio. Here's how we used Chrome's systemAudio and suppressLocalAudioPlayback constraints to fix that — and why it works without any backend changes.
-
How We Added Video Playlists to SendRec
Building shareable video playlists with auto-advance, watched badges, password protection, and a dark-themed watch page — all in two tables and one Go template.
-
How We Built a Viewer Engagement Heatmap
SendRec now shows which parts of your video hold attention and which cause drop-off. Here's how we built segment-based engagement tracking with 50 segments, batch reporting, and a CSS heatmap.
-
How We Made Our E2E Tests 12x Faster
Our Playwright e2e suite took 90 seconds per run. Three changes — API login, connection pooling, and faster health checks — brought it to 7 seconds. Here's what we changed and one approach that didn't work.
-
How We Made Screen Recording Work on Every Browser
Our screen recorder only worked on Chrome. Here's how we added Safari and Firefox support, fixed iOS playback, and eliminated unnecessary server-side transcoding.
-
What's Next for SendRec
We shipped 19 releases in February — playlists, engagement heatmaps, system audio, custom player controls, and more. Here's what we built, what we learned, and where SendRec is heading.
-
SendRec Is Now on Docker Hub and Unraid
You can now pull SendRec from Docker Hub and install it on Unraid with a community app template. Here's how we set up automated image publishing and wrote the Unraid template.
-
How SendRec Compares to Loom, Zight, and Cap
A detailed look at how SendRec stacks up against the three most common async video tools — on data hosting, pricing, features, and source code transparency.
-
How We Made SendRec Billing Webhooks Bulletproof
We added idempotent webhook processing, an event audit log, and improved the subscription cancellation UX in SendRec v1.56.0.
-
How We Added End-to-End Tests to SendRec with Playwright
We went from 415 unit tests and zero e2e tests to 15 Playwright tests that exercise auth, uploads, library, settings, and watch pages against the full stack in CI.
-
How We Added Onboarding, SEO, and Branding Enforcement to SendRec
New user onboarding with a 3-step guide, robots.txt for watch page indexing, enforced SendRec badge for free users, and a fix for monthly quota counting deleted videos.
-
How We Fixed AI Summarization Timeouts for Self-Hosted Ollama
A community bug report led to a configurable AI_TIMEOUT env var for SendRec's AI summarization feature. Here's how we shipped the fix.
-
How We Migrated to Structured Logging with Go's slog Package
We replaced 130 log.Printf calls across 30 files with Go's built-in slog package for structured, leveled logging. Here's what changed and why.
-
How We Added Billing to SendRec with Creem
An EU-native merchant of record handles VAT, invoicing, and disputes so we don't have to. Here's how we integrated Creem for subscription billing in a self-hostable Go app.
-
How We Added Batch Operations and Multi-File Upload to SendRec
Select multiple videos to delete, move, or tag in bulk. Upload up to 10 files at once with quota-aware validation. Plus a recording countdown timer and clickable chapter markers in the player.
-
How We Added Rich Link Previews to SendRec
When you share a SendRec link on Slack, Twitter, or LinkedIn, it now shows a thumbnail, title, and description instead of a bare URL. Here's how we solved the presigned URL expiry problem and added Open Graph and Twitter Card meta tags.
-
How We Added Structured Data to SendRec Watch Pages
SendRec watch pages now include JSON-LD VideoObject markup, canonical URLs, and meta descriptions. Here's how we built it and why it matters for search visibility.
-
How We Added Generic Webhooks to SendRec
POST events to any URL when videos are viewed, commented on, or hit milestones. HMAC-SHA256 signed payloads, automatic retries, and a delivery log. Here's how we built it.
-
How We Added an Email Gate to Shared Videos
View counts are anonymous. Sometimes you need to know who's watching. We added a per-video email gate to SendRec — a cookie-based form that collects viewer emails before playback, with per-viewer analytics showing view count and completion percentage.
-
How We Added AI Summaries and Chapters to Video Recordings
Every transcribed video now gets a 2-3 sentence summary and auto-generated chapters. We built it with the OpenAI chat completions API, a background worker, and a tabbed watch page panel.
-
How We Added Dark Mode (and Light Mode) to SendRec
Adding Dark, Light, and System theme modes to a React SPA using CSS custom properties, useSyncExternalStore, and a FOUC prevention script. No context providers, no theme libraries — just vanilla CSS and a 93-line hook.
-
How We Added Folders and Tags to Organize Video Libraries
Adding single-level folders and multi-tag organization to a video library with a sidebar navigation, inline management, and PostgreSQL-backed filtering. From flat list to structured workspace in one migration.
-
How We Added Slack Webhook Notifications to SendRec
Get instant Slack notifications when someone views or comments on your videos. We built it with incoming webhooks, Block Kit messages, and a clean separation from the existing email notification system.
-
How We Added Closed Captions to Embedded Videos
Our embeddable player was missing subtitles. The watch page had them. The embed page didn't. One query column, one presigned URL, and one HTML element closed the gap.
-
How We Added Call-to-Action Buttons to Shared Videos
Screen recordings are great for demos, but what happens after the video ends? We added per-video CTA buttons that appear when playback finishes, track clicks, and report click-through rates in analytics.
-
How We Built Viewer Engagement Analytics Without a Tracking SDK
View counts tell you someone opened your video. They don't tell you if anyone actually watched it. We added milestone-based engagement tracking to SendRec — four data points per viewer, zero external dependencies, one SQL table.
-
How We Found and Fixed a Hidden View Inflation Bug
Our transcript polling was recording a new view every 10 seconds, inflating view counts and flooding video owners with notification emails. Here's how we found it and the one-line fix.
-
How We Added Camera Recording for Mobile Browsers
Screen recording doesn't work on mobile Safari. Instead of showing an error, we built a camera recorder using getUserMedia that lets users record themselves talking — with front/back camera switching, pause/resume, and MP4 output for universal playback.
-
How We Added Custom CSS Injection to Watch Pages
Color pickers cover the basics, but designers want full control. We added a custom CSS field that lets users restyle every element on their video watch pages — with server-side injection and security guardrails.
-
How We Added Per-Video Download Controls
When you share a screen recording with a client, you might not want them downloading the file. We added a per-video download toggle that removes the button, blocks the API, and disables the browser's built-in save option.
-
How We Replaced MinIO with Garage for Self-Hosted S3 Storage
MinIO's licensing shift left self-hosters looking for alternatives. We migrated SendRec's storage layer to Garage — a lightweight, open-source S3 engine written in Rust — in a single afternoon.
-
How We Added Custom Branding to Shared Video Pages
When you share a screen recording, viewers see your brand or ours. Here's how we built a three-layer branding system with per-user defaults, per-video overrides, and a watch page that renders it all server-side.
-
How We Made Watch Page Analytics Provider-Agnostic
We shipped Umami support, then immediately replaced it with a generic ANALYTICS_SCRIPT env var that works with any provider. Here's why and how — including the CSP nonce injection trick and a bash quoting pitfall that broke our deploy.
-
How We Built a Nextcloud Integration for SendRec
Nextcloud users are exactly our audience — self-hosters who care about data sovereignty. Here's how we built an integration app with link previews, Smart Picker, and per-user API keys.
-
GDPR-Compliant Screen Recording: What You Actually Need to Know
Most screen recording tools store your data on US servers and call it GDPR compliant. Here's what the regulation actually requires, where popular tools fall short, and how to record screens without sending data outside the EU.
-
How We Built View Notifications for Screen Recordings
You share a video and then wonder if anyone watched it. Here's how we added instant, first-view, and daily digest notifications to SendRec using a two-tier preference system and a background digest worker.
-
Why Your Screen Recordings Need View Analytics
You hit record, share the link, and then what? Without analytics, screen recordings disappear into the void. Here's how we added per-video view tracking to SendRec and why it changes how you communicate async.
-
How We Added Real-Time Drawing Annotations to Screen Recordings
Screen recordings are better when you can point at things. Here's how we built a freehand drawing overlay that composites annotations directly into the recorded video using two HTML canvases and requestAnimationFrame.
-
How We Added Automatic Transcription With whisper.cpp
Every video gets a transcript now — subtitles, clickable timestamps, and full-text search. Here's how we built it with whisper.cpp running server-side, and why we made transcription optional for self-hosters.
-
How We Built Server-Side Video Trimming With ffmpeg
Client-side video trimming hits browser limits fast. Here's how we built server-side trimming with ffmpeg, async processing, and a custom timeline UI.
-
How We Replaced Goroutines With a Database Queue for Video Transcription
Our fire-and-forget goroutine lost jobs on restart and left users guessing. Here's how we built a reliable transcription queue using just PostgreSQL — no Redis, no RabbitMQ.
-
Why Canvas Breaks Your Screen Recorder (And What to Do Instead)
Most screen recorders composite webcam overlays using canvas. Here's why that fails in background tabs and how we solved it with server-side ffmpeg.
-
What It Actually Costs to Run a SaaS on EU Infrastructure
We run our full production stack — app, database, object storage, analytics, email, HTTPS, backups — on a single Hetzner server for about €6/month. Here's the full setup.
-
Why Your Video Tool's Source Code Matters More Than Its Privacy Policy
Privacy policies are legal shields, not transparency tools. When your video platform processes biometric data, open source is the only way to verify what actually happens to your recordings.
-
Why EU Teams Need a European Loom Alternative
Video recordings contain biometric data. For EU teams, sending that to US servers creates real compliance risk. Here's what a proper solution looks like.