When users share content from the Bluesky platform via screenshots, the application automatically injects a branded watermark. This feature, while seemingly trivial, requires a robust client-side implementation that balances performance, image quality, and [browser](/blog/how-browsers-render-web-pages-the-critical-rendering-path-explained) compatibility across web and mobile environments.
Rather than relying on server-side rendering, which would introduce latency and increase infrastructure costs, Bluesky leverages the HTML5 Canvas API to perform compositing directly in the user’s browser or webview. This approach ensures that the original source image remains untouched while a new, branded version is generated on-the-fly.
The Mechanics of Client-Side Compositing
The core of the process involves drawing an existing image—often a captured DOM element or a media file—onto a secondary off-screen canvas. By initializing a canvas element with dimensions matching the target image, the application can programmatically overlay the logo asset at specific coordinates.
async function applyWatermark(sourceImage: HTMLImageElement, logo: HTMLImageElement) {
const canvas = document.createElement('canvas');
canvas.width = sourceImage.naturalWidth;
canvas.height = sourceImage.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(sourceImage, 0, 0);
// Calculate position: bottom-right with padding
const x = canvas.width - logo.width - 20;
const y = canvas.height - logo.height - 20;
ctx.drawImage(logo, x, y);
return canvas.toDataURL('image/png');
}
Handling Cross-Origin Constraints
A common pitfall in canvas-based image manipulation is the ‘tainted canvas’ security restriction. If the source image is served from a different origin, the browser prevents the canvas from exporting its data unless the image resource includes appropriate CORS headers.
Bluesky manages this by ensuring that image assets are fetched with the ‘crossorigin’ attribute set to ‘anonymous’. This triggers a CORS preflight request, allowing the browser to verify permissions before the image is drawn onto the canvas. Without this, the ‘toDataURL’ method would throw a security exception, effectively breaking the screenshot feature.
Maintaining Aspect Ratio and Scaling
One challenge in UI-based screenshot tools is ensuring the logo remains proportional regardless of the screenshot’s dimensions. If a user captures a small avatar versus a large full-post image, a fixed-size logo might look either overwhelming or invisible.
- Relative Scaling: Calculating logo dimensions as a percentage of the canvas width.
- Padding Logic: Maintaining consistent margins relative to the canvas edge.
- Resolution Handling: Using high-DPI assets for the logo to ensure clarity on Retina displays.
Performance Considerations
Because this operation occurs on the main thread, large images can cause noticeable UI jank. To mitigate this, the implementation uses off-screen canvas instances and ensures that the rendering happens asynchronously. By keeping the canvas lifecycle short-lived and avoiding unnecessary memory retention, the application maintains a smooth user experience.
Conclusion
The Bluesky implementation demonstrates the power of modern client-side APIs to handle what were once exclusively server-side tasks. By offloading the compositing work to the client, the architecture remains lightweight and scalable. Engineers looking to replicate this pattern should prioritize CORS configuration and careful memory management to ensure the system remains performant under varying load conditions.