Description
The handleCopyMarkdown function in ShareSheet.tsx constructs the badge URL using:
PROFILE_URL(username).replace(username, `api/streak?user=${username}`)
PROFILE_URL(username) returns https://commitpulse.vercel.app/dashboard/{username}. String.prototype.replace() replaces the first occurrence of the substring. If the username happens to appear as a substring of the domain name (e.g., "vercel", "commit", "pulse", "app"), the replace hits the domain instead of the path segment, producing a completely broken URL.
Concrete example: Username = vercel
PROFILE_URL("vercel") → https://commitpulse.vercel.app/dashboard/vercel
.replace("vercel", "api/streak?user=vercel") → https://commitpulse.api/streak?user=vercel.app/dashboard/vercel
The result is a nonsensical URL pointing to commitpulse.api (a non-existent domain) with the path mangled. The user copies this broken markdown and pastes it into their README, where the badge image silently fails to load.
The same corruption happens for any username that is a substring of commitpulse.vercel.app: commit, pulse, app, vercel, commitpulse, etc.
Affected Files
components/dashboard/ShareSheet.tsx (line 173 — handleCopyMarkdown)
Expected Behaviour
The markdown snippet should always produce a valid badge URL:

Actual Behaviour
For usernames that are substrings of the domain name (commitpulse.vercel.app), the String.replace matches the domain instead of the path segment, producing a mangled URL like:

The badge image fails to load in the user's README, and the copied markdown is broken. There is no error feedback — the copy succeeds, the user pastes it, and only discovers the issue when the badge doesn't render.
Proposed Fix
Replace the fragile String.replace with explicit URL construction using a known base URL and encodeURIComponent:
// components/dashboard/ShareSheet.tsx — replace handleCopyMarkdown
const BADGE_BASE = 'https://commitpulse.vercel.app/api/streak';
const handleCopyMarkdown = async () => {
setOptionState('markdown', 'loading');
try {
// Construct the badge URL directly from a constant base URL,
// avoiding any string-matching on the profile URL that could
// accidentally hit the domain name.
const badgeUrl = `${BADGE_BASE}?user=${encodeURIComponent(username)}`;
const markdown = ``;
await navigator.clipboard.writeText(markdown);
setOptionState('markdown', 'success');
setTimeout(() => onClose(), 800);
} catch {
setOptionState('markdown', 'error');
}
};
Additionally, since BADGE_BASE is now a constant, it should be extracted to a shared constants file (e.g., lib/constants.ts) so it can be reused across the app:
// lib/constants.ts
export const SITE_URL = 'https://commitpulse.vercel.app';
export const BADGE_BASE_URL = `${SITE_URL}/api/streak`;
This also handles edge-case usernames with special characters (e.g., usernames containing &, ?, #) by using encodeURIComponent, which the original String.replace approach did not account for.
Description
The
handleCopyMarkdownfunction inShareSheet.tsxconstructs the badge URL using:PROFILE_URL(username)returnshttps://commitpulse.vercel.app/dashboard/{username}.String.prototype.replace()replaces the first occurrence of the substring. If the username happens to appear as a substring of the domain name (e.g.,"vercel","commit","pulse","app"), thereplacehits the domain instead of the path segment, producing a completely broken URL.Concrete example: Username =
vercelPROFILE_URL("vercel")→https://commitpulse.vercel.app/dashboard/vercel.replace("vercel", "api/streak?user=vercel")→https://commitpulse.api/streak?user=vercel.app/dashboard/vercelThe result is a nonsensical URL pointing to
commitpulse.api(a non-existent domain) with the path mangled. The user copies this broken markdown and pastes it into their README, where the badge image silently fails to load.The same corruption happens for any username that is a substring of
commitpulse.vercel.app:commit,pulse,app,vercel,commitpulse, etc.Affected Files
components/dashboard/ShareSheet.tsx(line 173 —handleCopyMarkdown)Expected Behaviour
The markdown snippet should always produce a valid badge URL:
Actual Behaviour
For usernames that are substrings of the domain name (
commitpulse.vercel.app), theString.replacematches the domain instead of the path segment, producing a mangled URL like:The badge image fails to load in the user's README, and the copied markdown is broken. There is no error feedback — the copy succeeds, the user pastes it, and only discovers the issue when the badge doesn't render.
Proposed Fix
Replace the fragile
String.replacewith explicit URL construction using a known base URL andencodeURIComponent:Additionally, since
BADGE_BASEis now a constant, it should be extracted to a shared constants file (e.g.,lib/constants.ts) so it can be reused across the app:This also handles edge-case usernames with special characters (e.g., usernames containing
&,?,#) by usingencodeURIComponent, which the originalString.replaceapproach did not account for.