What a custom plugin is
A Pinodock plugin is a live widget that sits on your new tab dashboard. It fetches data from a source you specify and displays it in a format you choose. The data refreshes automatically in the background, so every time you open a new tab, your numbers are current.
Out of the box, Pinodock ships with built-in plugins for Hacker News, Crypto prices, Reddit, Gmail, GitHub, Google Calendar, Spotify, Todoist, AWS, and YouTube Studio. Custom plugins let you go further — any public API, any internal endpoint, any page you're already logged into.
Three modes, three different use cases
Fetch mode — public APIs and anything with CORS
Fetch mode makes a direct HTTP GET request from your browser to a JSON endpoint. It works with any API that allows cross-origin requests, which covers most public APIs: CoinGecko, OpenWeatherMap, GitHub API, Linear, PagerDuty, Stripe (public data), Notion, Vercel, Render, and hundreds more.
You paste the URL, add any headers (Bearer tokens, API keys), define which JSON fields to extract, and pick a display template. That's the whole setup.
https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd, extract bitcoin.usd, and you have a live Bitcoin price widget with zero configuration beyond that URL.
Relay mode — private APIs where credentials stay server-side
Some APIs can't be called directly from the browser — either because they block CORS, or because you don't want your API key sitting in browser storage. Relay mode solves this by routing the request through a small serverless function you control.
Your relay function (a Vercel function, Cloudflare Worker, or AWS Lambda — about 10 lines of code) holds the credentials and returns sanitized JSON. Pinodock POSTs {"key": "your-plugin-key", "params": {...}} to your relay, the relay calls the real API, and sends back only what you need to display.
This is the same architecture that TRMNL uses for its plugin webhooks — except you own the relay, and Pinodock renders it live in your browser rather than pushing to a device.
Scrape mode — anything you're already logged into
If a site has no API but renders the data you need in its HTML, scrape mode reads it directly from your open tab. You provide a CSS selector, and Pinodock extracts the matching text every time you refresh.
This works for internal company dashboards, legacy tools, Retool apps, or any site where the data is there but hidden behind a login that only you have.
Field extraction and JSON paths
Most APIs don't return a flat object — they return nested structures. Pinodock's field system handles this with dot-notation paths:
bpi.USD.rate_float— nested object access[0].title— first element of a top-level arraydata.items[2].name— array indexing inside a nested object
The built-in API Explorer lets you paste your endpoint URL and browse the live JSON response tree, clicking a field to copy its path automatically. No manual path construction needed.
Display templates
Once you've extracted your fields, you choose how to show them:
- Stat — one big number with secondary metrics underneath. Best for a single key figure (MRR, unread count, CPU usage).
- Table — label/value grid. Best when you have 3–8 fields of roughly equal importance.
- List — stacked rows with labels. Best for feeds and ranked lists.
- Text — freeform prose. Best for scraped content or a single long string.
Advanced field options
Each field also supports optional upgrades that you toggle per-field in the settings UI:
- Transforms — format the raw value:
currency,number,date,percent,truncate,uppercase,lowercase - Threshold colors — set warn/danger thresholds; the value turns amber or red automatically when crossed
- Sparklines — if the field value is an array of numbers, Pinodock auto-renders a mini line chart using your plugin's accent color
- URL click-through — mark the field as a URL and a ↗ button appears next to the value, opening the link without navigating away from the new tab
- Badge count — surface one field's value as a number badge on the extension icon itself, visible without opening a new tab
Auto-refresh in the background
Set a refresh interval (5 min, 15 min, or 1 hour) and Pinodock's background service worker refreshes the data even when no new tab is open. When you do open a tab, the widget renders from the warm cache instantly — no loading state, no spinner.
What you can build
A few real-world examples from the same plugin system, configured entirely from Settings:
- GitHub open PR count, shown in red when above your team's WIP limit
- Stripe MRR with a 30-day sparkline
- PagerDuty active incident count via relay (API key stays server-side)
- Linear P0 bug count, amber above 2, red above 5
- Render deploy status for your production app
- OpenWeatherMap current temperature with a danger threshold for extreme weather
- Internal Retool dashboard metric via scrape mode
- Notion task count via relay (Notion API blocks CORS direct calls)