Skip to content

Feature/badge endpoint - #158

Merged
sajeetharan merged 15 commits into
sajeetharan:mainfrom
HereIsMuhammad:feature/badge-endpoint
Aug 15, 2026
Merged

Feature/badge endpoint#158
sajeetharan merged 15 commits into
sajeetharan:mainfrom
HereIsMuhammad:feature/badge-endpoint

Conversation

@HereIsMuhammad

Copy link
Copy Markdown
Contributor

Summary

Adds an embeddable SVG badge that developers can drop into a GitHub README or personal site to show a live-updating DevGlobe stat, similar to shields.io / committers.top badges.

[![devglobe](https://www.devglobe.dev/api/badge/YOUR_GITHUB_USERNAME.svg)](https://www.devglobe.dev/share/YOUR_GITHUB_USERNAME)

Closes #145

What's included

  • app/badge/[login]/route.js — public GET /api/badge/[login].svg endpoint. Validates the login, validates the ?stat= query param, and falls back to a grey "unranked"/"unavailable" badge instead of a broken image on any error or missing data.
  • lib/badge.js — SVG rendering + stat resolution. Supports globalRank (default), countryRank, cityRank, score, and stars. Auto-sizing width based on text length, XML-escaped values.
  • lib/badge-lookup.js — badge-safe developer lookup (only fields already public via /api/developer), backed by Cosmos DB with a fallback to bundled sample data, same pattern as /api/card.
  • components/BadgeSnippet.jsx — "Get your badge" UI on the developer's share page: pick a stat, pick Markdown/HTML format, copy the snippet.
  • components/DetailPanel.jsx — adds a "Get Badge ↗" link from the developer detail panel to their share page's badge section, and an onCardGenerated callback hook.
  • docs/prd/badge.md — usage docs (embed snippet, available stats, caching/freshness behavior).
  • tests/badge.test.js — coverage for stat resolution, unranked/error fallback, SVG escaping, and auto-width.

Design

  • Two-segment flat badge: black label segment ("Devglobe rank") + #1d4ed8 value segment, white text on both.
  • Response is cached at the edge for 1 hour (s-maxage=3600, stale-while-revalidate=86400) so it stays cheap on frequent README reads while staying reasonably fresh.
  • Never 404s for a syntactically valid login — always returns a badge (ranked or "unranked") so embeds never show a broken-image icon.

Testing

  • npm test — all badge unit tests pass.
  • Manually verified /api/badge/<login>.svg renders correctly for a ranked developer, an unranked developer, and an invalid login/stat.

Notes for reviewers

styles/main.css also includes a few pre-existing local changes unrelated to the badge feature (search bar / sidebar top offset, activity banner block, header button visibility at 768px) that were already present in my working copy — flagging in case you'd rather I split those out.

This component allows users to generate and copy embeddable badges for their DevGlobe stats in Markdown or HTML format.
This document provides instructions on how developers can embed a live-updating badge in their GitHub README, personal site, or blog. It includes examples in Markdown and HTML, options for customizing the badge display, and details on how the badge updates automatically.
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

@HereIsMuhammad is attempting to deploy a commit to the sajeetharan's projects Team on Vercel.

A member of the Team first needs to authorize it.

@HereIsMuhammad

Copy link
Copy Markdown
Contributor Author

@sajeetharan this is ready for review whenever you get a chance — closes #145

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new embeddable SVG badge feature intended to let developers display live DevGlobe stats in READMEs/sites, plus supporting UI/docs/tests. The core functionality is in a new badge renderer/stat resolver and a new route handler, with a snippet UI for copy-paste embeds.

Changes:

  • Introduces badge stat resolution + SVG rendering utilities (lib/badge.js) and a badge-safe developer lookup (lib/badge-lookup.js).
  • Adds a route handler for serving the SVG badge and unit tests for rendering/stat behavior.
  • Adds UI/CSS/docs for a “Get your badge” snippet experience and a link from the developer detail panel.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
app/badge/[login]/route.js Adds the badge SVG route handler (currently located under /badge/...).
lib/badge.js Implements supported stats, fallback behavior, and SVG rendering/escaping.
lib/badge-lookup.js Fetches a badge-safe developer record from Cosmos with sample-data fallback.
components/BadgeSnippet.jsx New “Get your badge” snippet UI for choosing stat + Markdown/HTML formats.
components/DetailPanel.jsx Adds “Get Badge” link and a new callback hook; updates share text composition.
docs/prd/badge.md Documents embedding, supported stats, and caching/fallback behavior.
tests/badge.test.js Unit tests for stat resolution, SVG escaping, and auto-width behavior.
styles/main.css Adds styling for the badge snippet card and includes other layout/UI adjustments.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1 to +4
import { BADGE_STATS, DEFAULT_BADGE_STAT, renderBadgeSvg, resolveBadgeStat } from '../../../../lib/badge.js';
import { getBadgeDeveloper } from '../../../../lib/badge-lookup.js';

export const runtime = 'nodejs';
Comment thread app/badge/[login]/route.js
Comment thread lib/badge-lookup.js
Comment on lines +28 to +34
async function getFromSampleData(login) {
const filePath = path.join(process.cwd(), 'data', 'developers-sample.json');
const raw = await fs.readFile(filePath, 'utf-8');
const data = JSON.parse(raw);
const developers = addDeveloperRanks(scoreAll(data));
return developers.find(d => d.login.toLowerCase() === login.toLowerCase()) || null;
}
Comment thread docs/prd/badge.md
Comment on lines +29 to +32
| `globalRank` (default) | `Global #4` |
| `countryRank` | `USA #2` |
| `score` | `91/100` |
| `stars` | `182.0K stars` |
Comment thread styles/main.css Outdated
Comment on lines +46 to +53
<div className="badge-card__stats" role="tablist" aria-label="Badge stat">
{STAT_OPTIONS.map(option => (
<button
key={option.value}
type="button"
role="tab"
aria-selected={stat === option.value}
className={`badge-card__stat${stat === option.value ? ' badge-card__stat--active' : ''}`}
Comment on lines +13 to +15
export default function BadgeSnippet({ login, siteUrl }) {
const [stat, setStat] = useState('globalRank');
const [format, setFormat] = useState('markdown');
Comment thread components/DetailPanel.jsx Outdated
Comment thread components/DetailPanel.jsx
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@sajeetharan

Copy link
Copy Markdown
Owner

@HereIsMuhammad there are some comments from copilot, can you fix if they are valid

@HereIsMuhammad

Copy link
Copy Markdown
Contributor Author

@sajeetharan
Hi! Yes I do

@sajeetharan
sajeetharan merged commit d84fc5f into sajeetharan:main Aug 15, 2026
2 of 3 checks passed

@HereIsMuhammad HereIsMuhammad left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve

@sajeetharan

Copy link
Copy Markdown
Owner

@HereIsMuhammad what the difference between is get badge and generate card? it looks the same to me based on the deployed version!

@HereIsMuhammad

Copy link
Copy Markdown
Contributor Author

@sajeetharan Get Badge provides an embeddable Markdown badge specifically for GitHub profile READMEs, whereas Generate Card creates a larger visual preview meant for sharing or portfolio displays

@sajeetharan

sajeetharan commented Aug 15, 2026

Copy link
Copy Markdown
Owner

oh can you try this on deployed version and works as expected? because when i click on get badge it takes me to the same ui as card! if its the same image, can we have the get badge as parr of the generate image? somewhere after generated image!

@HereIsMuhammad

Copy link
Copy Markdown
Contributor Author

ok will push changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Embeddable live developer badge for READMEs and personal sites

3 participants