A collection of self-hosted widgets designed for use with Homepage (or any dashboard) as iframes. Serves all widgets via a lightweight Python HTTP server.
| Widget | Description |
|---|---|
docker |
Docker container status & controls via AnyApp |
streams |
Plex active streams via Tautulli |
watchHistory |
Recent watch history via Tautulli |
recentRequests |
Recent media requests via Overseerr |
recentlyAdded |
Recently added media |
sabnzbd |
SABnzbd download queue |
tautulli |
Tautulli stats |
gamesCountdown |
Upcoming game release countdown |
indexers |
Indexer status |
All widgets fetch data from local services (Tautulli, Overseerr, etc.) directly in the browser. Because these are cross-origin requests, a CORS proxy must be running on your network.
The corsPort in your config (default 8885) must point to a running cors-anywhere instance.
Quick setup with Docker:
docker run -d \
--name cors-anywhere \
-p 8885:8080 \
--restart unless-stopped \
redocly/cors-anywhereOr run it with Node.js:
npx cors-anywhereWithout the CORS proxy running, all widgets will show
ERR_CONNECTION_REFUSEDerrors and fail to load data.
Copy the example config and fill in your values:
cp config/config.example.js config/config.jsEdit config/config.js with your server details and API keys.
docker run -d \
--name homepage-widgets \
-p 8321:8321 \
-v /path/to/your/config.js:/app/config/config.js:ro \
ghcr.io/alsharad/homepage-widgets:latestservices:
homepage-widgets:
image: ghcr.io/alsharad/homepage-widgets:latest
container_name: homepage-widgets
ports:
- "8321:8321"
volumes:
- /path/to/your/config.js:/app/config/config.js:ro
restart: unless-stoppedThen access widgets at: http://your-server-ip:8321/widgets/<widget-name>/
Create config/config.js based on config/config.example.js:
// config.js
const config = {
baseIP: "192.168.1.100" // Your server's local IP
, corsPort: "8885" // CORS proxy port
, tautulliPort: "8181"
, tautulliApiKey: ""
, plexToken: ""
, overseerrPort: "5055"
, overseerrApiKey: ""
, prowlarrPort: "9696"
, prowlarrApiKey: ""
, twitchClientSecret: ""
, igdbClientId: ""
, showIMDbScore: true
, showBackdrops: false
, anyAppPort: "8855"
, sabnzbdPort: "8080"
, sabApiKey: ""
};
export default config;Important:
config/config.jsis excluded from the Docker image. Always mount it as a volume — never bake secrets into the image.
The image is built and pushed automatically via GitHub Actions on every push to main.
It's available at:
ghcr.io/alsharad/homepage-widgets:latest
| Port | Description |
|---|---|
8321 |
HTTP server serving all widgets |
- My Streams:
widget:
type: iframe
src: http://your-server-ip:8321/widgets/streams/
classes: h-full