This Devvit app tests the ability to take screenshots of content rendered inside an iframe. It compares two popular screenshot libraries:
- html-to-image - Converts DOM to canvas using foreignObject
- html2canvas - Renders DOM to canvas by parsing styles
Test screenshot libraries in a production Devvit environment to ensure they can accurately capture complex CSS features, modern color formats, Canvas/WebGL graphics, and various edge cases.
- Devvit: Reddit's developer platform for immersive web apps
- Vite: For compiling the WebView
- React: For UI
- Hono: For backend logic
- TRPC: Type-safe RPCs from server to client
- Tailwind: For styles
- TypeScript: For type safety
- html-to-image & html2canvas: Screenshot libraries
The app contains 9 comprehensive test pages:
- Linear and radial gradients
- OKLCH/OKLAB modern color formats
- Box shadows, text shadows, drop shadows
- Advanced multi-layer shadows
- 2D transforms: rotate, scale, skew, translate
- 3D transforms with preserve-3d
- Rotating 3D cubes
- Multiple transform combinations
- Server-loaded images via tRPC (pattern for Reddit uploads)
- Data URI images (working within CSP)
- Inline SVG graphics
- SVG gradients (linear and radial)
- Complex SVG with opacity layers
- Custom fonts and typography
- Text effects (shadows, glows, strokes, layered)
- Text decorations (underline, strikethrough, overline)
- Gradient text fill
- Multi-column text layouts
- Canvas 2D graphics
- Canvas-based bar charts
- WebGL 3D rendering
- CSS filters: blur, brightness, contrast, saturate, hue-rotate, grayscale, sepia
- Complex gradients: conic, repeating-linear, repeating-radial
- Blend modes: multiply, screen, overlay
- Backdrop filters
- Overflow and scrollable content
- Absolute/fixed positioning
- Nested iframes (iframe inception)
- Z-index layering
- Video elements with posters
- Audio player controls
- Media elements with various attributes
- Media in different layout contexts
- PDF via iframe, embed, and object tags (native - won't capture)
- Styled PDF containers with borders and shadows
- PDF scaling and sizing tests
- Fallback content rendering
- PDF.js with blob URLs (working solution but complex!)
- Demonstrates real pain point for Devvit developers
Make sure you have Node 22 downloaded on your machine before running!
# Install dependencies
npm install
# Build the project
npm run build
# Start local development server
npm run dev
# Deploy to Reddit
npm run deploy
# Publish for review
npm run launch- Deploy the app to your test subreddit
- Create a post using the app's menu item
- Click "Start Testing" on the splash screen
- Navigate through pages using Prev/Next buttons
- Capture screenshots using:
- π· html-to-image - Capture with html-to-image only
- π· html2canvas - Capture with html2canvas only
- π· Both - Capture with both libraries for comparison
- Compare the screenshots side-by-side with the original content
- Look for differences in:
- Color accuracy (especially OKLCH/OKLAB)
- Gradient rendering quality
- Shadow effects
- Transform accuracy
- Canvas/WebGL content capture
- Missing or blank content (iframes, images)
- CSS filter effects
npm run dev: Starts a development server for live development on Redditnpm run build: Builds client and server projectsnpm run deploy: Uploads a new version of your appnpm run launch: Publishes your app for reviewnpm run login: Logs your CLI into Redditnpm run type-check: Runs TypeScript type checkingnpm run lint: Lints your codenpm run test: Runs tests
Most screenshot libraries cannot capture content inside nested iframes - they typically show a blank rectangle.
GPU-rendered content may not transfer to screenshots or may appear blank.
External images without proper CORS headers may appear blank in screenshots.
Complex 3D CSS (preserve-3d, perspective) may flatten or render incorrectly in screenshots.
OKLCH/OKLAB colors may need preprocessing for canvas APIs, as they're not natively supported.
Backdrop filters like backdrop-blur may not render correctly in screenshots.
src/
βββ game.tsx # Main app with screenshot capture logic
βββ splash.tsx # Landing page
βββ pages/ # Test page components
β βββ GradientsColors.tsx
β βββ Transforms.tsx
β βββ ImagesSvg.tsx
β βββ FontsText.tsx
β βββ CanvasWebgl.tsx
β βββ FiltersAdvanced.tsx
β βββ Layout.tsx
β βββ Media.tsx
β βββ Pdf.tsx
βββ server/ # Backend code
β βββ index.ts
β βββ trpc.ts
β βββ routes/
βββ index.css # Global styles
- Issue: External images (e.g.,
picsum.photos) are blocked by Devvit's CSP - Solution: Use Reddit media upload API or data URIs (see
IMAGE_UPLOAD_NOTES.md) - Current: Pattern implemented with data URIs, ready for
reddit.uploadMedia()
- Issue: Native PDF embeds don't capture in screenshots
- Solution: PDF.js with blob URL conversion (implemented and working)
- Video/audio elements show poster/controls, not playback
- WebGL content may appear black depending on library support
- Nested iframes typically show blank
- External fonts may not load before screenshot
See individual page documentation for detailed workarounds.
- Visual comparison: Compare screenshots with original content
- Feature detection: Check if specific CSS features render correctly
- Cross-library comparison: Compare html-to-image vs html2canvas results
- Performance metrics: Capture time is displayed for each library
- Edge case validation: Test all identified edge cases systematically
This is a test app for evaluating screenshot library capabilities. Feel free to add more edge cases or test scenarios.
BSD-3-Clause