fix: handle bare domain/path URLs in bio links (#701)

adds support for github.com/... style URLs without protocol prefix.
regex now matches domain.tld/path patterns and prepends https://.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

authored by zzstoatzz.io Claude Opus 4.5 and committed by GitHub 078bd384 ea576f27

Changed files
+7 -5
frontend
src
lib
components
+7 -5
frontend/src/lib/components/RichText.svelte
··· 5 * supports: 6 * - bare URLs: https://example.com -> clickable link 7 * - markdown links: [text](https://example.com) -> "text" as clickable link 8 */ 9 10 interface Props { ··· 23 function parseText(input: string): TextPart[] { 24 const parts: TextPart[] = []; 25 26 - // combined regex: markdown links OR bare URLs 27 // markdown: [text](url) 28 // bare URL: https?://... or www.... 29 const combinedRegex = 30 - /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)|(https?:\/\/[^\s<>)\]]+|www\.[^\s<>)\]]+)/gi; 31 32 let lastIndex = 0; 33 let match; ··· 49 href: match[2] 50 }); 51 } else if (match[3]) { 52 - // bare URL 53 let href = match[3]; 54 - if (href.startsWith('www.')) { 55 href = 'https://' + href; 56 } 57 parts.push({ ··· 79 </script> 80 81 <span class={className} 82 - >{#each parsed as part}{#if part.type === 'link'}<a 83 href={part.href} 84 target="_blank" 85 rel="noopener noreferrer"
··· 5 * supports: 6 * - bare URLs: https://example.com -> clickable link 7 * - markdown links: [text](https://example.com) -> "text" as clickable link 8 + * - domain/path URLs: github.com/user/repo -> clickable link 9 */ 10 11 interface Props { ··· 24 function parseText(input: string): TextPart[] { 25 const parts: TextPart[] = []; 26 27 + // combined regex: markdown links OR bare URLs OR domain/path 28 // markdown: [text](url) 29 // bare URL: https?://... or www.... 30 + // domain/path: github.com/... (must have path to avoid false positives) 31 const combinedRegex = 32 + /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)|(https?:\/\/[^\s<>)\]]+|www\.[^\s<>)\]]+|[a-z0-9][-a-z0-9]*\.[a-z]{2,}\/[^\s<>)\]]+)/gi; 33 34 let lastIndex = 0; 35 let match; ··· 51 href: match[2] 52 }); 53 } else if (match[3]) { 54 + // bare URL or domain/path 55 let href = match[3]; 56 + if (!href.startsWith('http://') && !href.startsWith('https://')) { 57 href = 'https://' + href; 58 } 59 parts.push({ ··· 81 </script> 82 83 <span class={className} 84 + >{#each parsed as part, i (i)}{#if part.type === 'link'}<a 85 href={part.href} 86 target="_blank" 87 rel="noopener noreferrer"