Command Palette

Search for a command to run...

Command Palette

Search for a command to run...

Showcase

Trakt Widgets

Dynamically generated PNG cards showing what you last watched on Trakt.tv — embeddable in any README, website, or profile.

Trakt Widgets screenshot

Trakt Widgets is an image API that generates real-time "last watched" cards from any public Trakt.tv profile. The endpoint returns a PNG — not JSON, not HTML — so you can drop it as an <img> tag anywhere images are accepted: GitHub READMEs, personal sites, Notion pages, or profile readmes. It updates automatically every time the URL is fetched.

Overview

The core idea is dead simple: an Express server exposes /:username/watched.png. When that URL is hit, it fetches the user's watch history from the Trakt.tv API, pulls the matching backdrop from TMDB, composites title text and metadata on top using @napi-rs/canvas, and streams the PNG response directly. No pre-rendering, no scheduled jobs, no storage — every request generates a fresh card on the fly.

The companion web UI is a dark-themed landing page where users can preview their card and copy the embed snippet.

Usage

![Last Watched](https://trakt-widgets.vercel.app/your-username/watched.png)

Paste this into any GitHub README. Replace your-username with your public Trakt.tv username. The card updates every time someone views the README.

Features

FeatureDetails
PNG image API/:username/watched.png returns a fully rendered image, not JSON
Trakt.tv integrationFetches the most recent watched movie or episode from the user's public history
TMDB backdropPulls a high-resolution landscape backdrop for the watched title
Server-side canvas rendering@napi-rs/canvas composites text, backdrop, and overlay server-side
Zero client-side JS neededWorks in any <img> tag — Markdown, HTML, Notion, anywhere
Self-hostableRuns on any Node.js host; environment variables configure both API keys
Dark UI with glassmorphism navbarLanding page for previewing and copying the embed snippet

Tech Stack

ToolRole
ExpressHTTP server, route handling, PNG response streaming
@napi-rs/canvasServer-side canvas rendering for PNG card composition
Trakt.tv APIPublic watch history — no OAuth needed for public profiles
TMDB APIHigh-resolution movie and TV show backdrops
Tailwind CSSUI styling via CDN; no build step on the frontend

How the Card is Generated

src/routes/watched.js

import { createCanvas, loadImage } from "@napi-rs/canvas"
import { getLastWatched } from "../services/trakt.js"
import { getBackdrop } from "../services/tmdb.js"
 
export async function watchedCard(req, res) {
  const { username } = req.params
  const watched = await getLastWatched(username)
  const backdropUrl = await getBackdrop(watched)
 
  const canvas = createCanvas(400, 200)
  const ctx = canvas.getContext("2d")
 
  // Draw backdrop
  const backdrop = await loadImage(backdropUrl)
  ctx.drawImage(backdrop, 0, 0, 400, 200)
 
  // Gradient overlay
  const gradient = ctx.createLinearGradient(0, 0, 0, 200)
  gradient.addColorStop(0, "rgba(0,0,0,0)")
  gradient.addColorStop(1, "rgba(0,0,0,0.85)")
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, 400, 200)
 
  // Title text
  ctx.fillStyle = "#ffffff"
  ctx.font = "bold 18px Inter"
  ctx.fillText(watched.title, 16, 165)
 
  // Subtitle
  ctx.fillStyle = "#ef4444" // Trakt red
  ctx.font = "13px Inter"
  ctx.fillText(watched.subtitle, 16, 185)
 
  res.setHeader("Content-Type", "image/png")
  res.setHeader("Cache-Control", "no-cache, max-age=0")
  canvas.createPNGStream().pipe(res)
}

Environment Configuration

VariableDescription
TRAKT_CLIENT_IDTrakt.tv application client ID (create one at trakt.tv/oauth/applications)
TMDB_API_KEYTMDB v3 API key (free at themoviedb.org)
PORTOptional — defaults to 3000

Both API keys are free to obtain. Trakt.tv public history requires no user OAuth — only a client ID for rate-limiting identification.