Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

thingiverse-web

Put your Thingiverse stats on your own website, and let your coding agent keep them current on a schedule. Designs published, total downloads, makes and collections, plus your six most-downloaded designs as image tiles.

The section, rendered

Packaged as an agent skill — a SKILL.md your agent reads and follows. /thingiverse-web walks you through the Thingiverse API token, installs the section into your page, and sets up the automatic refresh on whatever machine you have. Works with Claude Code, Cursor, the Grok CLI, or anything else that can read a skill file and run a shell. It is also a plain set of scripts — see Without an agent.

Companion skill: github-web — the same idea for your GitHub contributions, streaks and pinned repos.


What makes it different

The data is rendered into static HTML at build time. A Node script reads the Thingiverse REST API and rewrites marked-up regions of your page in place. That means:

  • No client-side JavaScript. Works on a site with script-src 'none', and with JS disabled entirely.
  • No token in the browser. The credential never leaves the machine that runs the sync.
  • No API call per visitor. No rate limits, no latency, no third-party request from your reader's browser.
  • Thumbnails are downloaded, not hotlinked. Thingiverse CDN URLs are signed and rotate; a hotlinked tile goes blank on its own schedule. The fetch saves each image under your site and points the tile at the local copy.
  • It is just HTML. Your page keeps working if this project disappears.

The trade-off is that it needs something to run on a schedule. That can be a server you own, or GitHub Actions for free — the package ships templates for both.


What it renders

Element Notes
Profile line thingiverse.com/<you> + a tagline you write
Designs published live count
Downloads · total summed across every published thing
Makes posted, collections live counts
Six design tiles your most-downloaded, with a local thumbnail, category and download count
Provenance line reads · sample data until a real sync has succeeded — see below

Desktop and mobile variants are both supported (data-tv-view="desktop" / "mobile"); a page can carry either or both. Mobile shows four tiles, desktop six.


Install

As an agent skill

git clone https://github.com/BlinkingSun/thingiverse-web-skill.git \
  ~/.claude/skills/thingiverse-web

Then run /thingiverse-web and answer the questions.

Other agents keep their skills elsewhere — Cursor and the Grok CLI can both be pointed at the same directory. The skill is plain Markdown and shell; nothing in it is Claude-specific.

Without an agent

git clone https://github.com/BlinkingSun/thingiverse-web-skill.git thingiverse-web
cd thingiverse-web

# 1. paste assets/section.html into your page, assets/section.css into your stylesheet
#    replace YOUR_THINGIVERSE_USERNAME, YOUR_TAGLINE and YOUR_BLURB

# 2. credentials
cp .env.example .env && chmod 600 .env    # then edit it

# 3. see it render before you have a token
mkdir -p data && cp reference/thingiverse.sample.json data/thingiverse.json
TARGETS=path/to/index.html node scripts/render-thingiverse.mjs

# 4. the real thing
./scripts/sync.sh

SKILL.md reads perfectly well as a manual setup guide — the phases are the same either way.


Requirements

  • Node 18+ (uses the built-in fetch)
  • A Thingiverse App Token — free, and issued instantly. See docs/API-SETUP.md.
  • Somewhere to run a scheduled job — or GitHub Actions.

If your site sets a Content-Security-Policy, the renderer emits inline-styled markup, so you need style-src ... 'unsafe-inline' or a nonce. Nothing else needs changing — in particular script-src 'none' is fine, which is the whole point.


Three things that will save you an hour

1. Thingiverse renders its design list client-side. You cannot scrape the profile page — there is nothing in the HTML to scrape. The REST API is the only route, which is why a token is not optional here.

2. Do not hotlink the CDN. cdn.thingiverse.com thumbnail URLs are signed and rotate. A page that references them directly looks perfect on the day you build it and quietly turns into six grey boxes later. fetch-thingiverse.mjs downloads each image to $SITE_DIR/assets/tv/<id>.jpg and writes the local path into the data file. Publish that directory with your page — it is part of the output, not a cache.

3. There is no year-to-date download figure. The API exposes a lifetime download_count per thing and nothing else. The stat is therefore labelled downloads · total, and the fetch appends {date, total} to a history array on each run. Once you have two entries you can derive a real delta; until then, do not label it YTD, because it is not.


How it behaves when things go wrong

Fail-closed, deliberately. A bad token, a network failure, a malformed response or a thumbnail that will not download aborts the run and leaves the data file at its last-good state, so the page keeps rendering the previous numbers and tiles rather than gaining a hole. A half-updated section is worse than a stale one, because it looks fine.

Data explicitly marked "stale": true is refused outright — the renderer exits non-zero rather than publish numbers a failed fetch left behind.

The provenance line is an honesty flag. Until a real sync has succeeded, the section reads channel 2 of 4 · sample data. Only a successful fetch clears the suffix — so a page that has never synced says so out loud instead of presenting invented numbers as yours. Do not delete the suffix by hand.

A missing container is fatal. If the renderer cannot find a [data-tv] region it expects, it exits non-zero and names it.

More in docs/TROUBLESHOOTING.md.


Layout

SKILL.md                          the guided setup (also a fine manual)
assets/section.html               the markup — [data-tv] hooks, no data
assets/section.css                self-contained styles + the tokens they need
scripts/fetch-thingiverse.mjs     REST + thumbnails -> data/thingiverse.json
scripts/validate-thingiverse.mjs  schema + sanity checks
scripts/render-thingiverse.mjs    data -> your HTML, in place
scripts/sync.sh                   fetch -> validate -> render -> (publish)
publish.sh.example                your deploy step; copy and edit
scheduling/                       launchd, systemd, cron, Task Scheduler, GitHub Actions
schema/                           JSON Schema for the data file
reference/                        sample data, so you can render before you have a token
docs/                             API setup, troubleshooting

A note on colour

Thingiverse blue #2b52fe is fine as a fill, but at 10px on the near-black card it measures 3.53:1 — below WCAG AA. Type uses a lightened #8fa4ff (≈6:1) instead. The data file keeps the two separate as theme.accent and theme.accentText. If you re-theme the section, keep that split rather than using one blue for both.


Provenance

Extracted from the Thingiverse section of makerinparadise.com, where it has been running against the live API since 2026-08-02.


Licence

MIT. See LICENSE.

Not affiliated with or endorsed by Thingiverse or MakerBot. "Thingiverse" is their trademark; this project only reads their public API with your own token.

About

Add your Thingiverse stats to your own website and keep them updated on a schedule by your coding agent — designs, downloads, makes and your top designs as tiles with locally cached thumbnails. Rendered to static HTML at build time: no client JS, no token in the browser.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages