github-stats — dynamiczne widgety GitHub SVG na Cloudflare Workers

· 2 min czytania

Zbudowałem self-hosted Cloudflare Worker, który generuje dynamiczne widgety SVG z GitHub API — z systemem motywów, dark/light mode, cache KV i przezroczystymi tłami do embeddowania wszędzie.

Zbudowałem self-hosted Cloudflare Worker, który generuje dynamiczne widgety SVG z GitHub API — z systemem motywów, dark/light mode, cache KV i przezroczystymi tłami do embeddowania wszędzie.

Problem

Każdy profil GitHub opowiada historię — commity, streak, najpopularniejsze języki, heatmapa aktywności. Ale istniejące serwisy z widgetami mają ograniczenia: sztywne motywy kłócące się z designem, brak kontroli nad cachowaniem, problemy z rate-limitami i brakiem możliwości dopasowania palety kolorów do własnego portfolio.

Chciałem widgetów, które:

  • pasują dokładnie do ciemnej niebieskiej palety spoko.space
  • automatycznie przełączają się między dark i light mode przez prefers-color-scheme
  • działają bez tła, żeby bezszwowo wtapiały się w dowolną stronę
  • są cachowane na edge, żeby były szybkie i nie przeciążały GitHub API

Więc je zbudowałem.

Efekt

GitHub Profile StatsNajpopularniejsze językiKalendarz aktywności

Widgety działają na żywo — renderowane w czasie rzeczywistym z moich danych GitHub, cachowane na edge Cloudflare i automatycznie zmieniające motyw zgodnie z preferencjami systemu.

Architektura

Całość wdrożona jest na Cloudflare Pages — serverless z globalnym zasięgiem. Stos technologiczny jest celowo uproszczony:

  • TypeScript — type-safe pipeline renderowania bez żadnego frameworka
  • Cloudflare KV — edge key-value store cachuje odpowiedzi API na 24 godziny, więc GitHub API jest odpytywane co najwyżej raz dziennie na każdy typ danych
  • GitHub GraphQL API — jedno zapytanie pobiera dane o aktywności, streak i statystyki repozytoriów
  • Czyste generowanie SVG — żadnego canvas, headless browsera ani bibliotek do obrazów; tylko szablony string tworzące poprawny SVG

SVG to świadomy wybór: wyświetla się piksel w piksel na każdym ekranie (łącznie z Retina), waży kilka kilobajtów i pozwala zmieniać kolory wyłącznie przez parametry URL — bez żadnego przetwarzania obrazów po stronie serwera.

Projekt obsługuje dziewięć endpointów (/langs, /stats, /streak, /contrib, /repos, /trophies, /stack, /profile, /icon) i zwraca odpowiedzi image/svg+xml z właściwymi nagłówkami Cache-Control.

System motywów

Każdy endpoint przyjmuje parametry query do nadpisania kolorów:

/langs?theme=light
/langs?bg=0d1117&primary=58a6ff&text=c9d1d9&radius=6
/profile?bg=transparent&border=transparent

W pakiecie dostępnych jest dziesięć gotowych motywów: dark, light, tokyonight, dracula, github-dark, nord, radical, synthwave, catppuccin, gruvbox, aura, discord. Obsługa przezroczystego tła — dodana specjalnie na potrzeby embeddów w portfolio — pozwala widgetom wtapiać się w dowolną stronę niezależnie od jej tła.

Do embeddów w README na GitHubie element <picture> automatycznie obsługuje przełączanie dark/light:

<picture>
  <source media="(prefers-color-scheme: light)"
    srcset="https://github.spoko.space/langs?theme=light">
  <img src="https://github.spoko.space/langs" alt="Języki">
</picture>

Ikony technologii z simple-icons

Widget /stack pobiera ścieżki ikon i kolory marek bezpośrednio z paczki npm simple-icons — bez ręcznego kopiowania SVG, bez nieaktualnych kolorów. Dzięki bundlerowi esbuild Cloudflare z tree-shakingiem do bundla trafiają tylko zaimportowane ikony.

Tech Stack

Fork i deploy

Projekt jest open source na licencji MIT. Wdrożenie własnej instancji zajmuje około pięciu minut:

git clone https://github.com/spokospace/github-stats
cd github-stats
npm install
npx wrangler secret put GITHUB_TOKEN
npx wrangler secret put CACHE_BUST_TOKEN
npx wrangler pages deploy .

Dodaj swój login GitHub do tablicy OWNERS w src/index.ts i gotowe. Pełna dokumentacja na github.spoko.space.

Powrót do bloga

Powiązane wpisy

Czytaj więcej