ADR-010: Social Share URL Generation Utility
Status
Section titled “Status”Accepted
Context
Section titled “Context”Social sharing URLs were previously generated inline within BlogLayout.astro, leading to:
- Code duplication risk when adding sharing to other pages (projects, case studies)
- Inconsistent URL encoding across different implementations
- Lack of unit test coverage for URL generation logic
- Difficulty maintaining platform-specific URL formats
Decision
Section titled “Decision”Extract social share URL generation into a dedicated utility module at src/utils/socialShare.ts with:
- Type-safe platform definitions:
SharePlatformtype for supported platforms - Consistent encoding: All URLs use
encodeURIComponent()for safety - Flexible API: Both single-platform and multi-platform generation functions
- Comprehensive testing: Unit tests covering edge cases and special characters
API Design
Section titled “API Design”// Generate single platform URLgenerateShareUrl(platform: SharePlatform, options: ShareUrlOptions): string
// Generate all platform URLsgenerateAllShareUrls(options: ShareUrlOptions): Record<SharePlatform, string>Supported Platforms
Section titled “Supported Platforms”- Twitter (X)
- Email (mailto)
Implementation
Section titled “Implementation”Before (BlogLayout.astro):
```typescriptconst encodedTitle = encodeURIComponent(title);const encodedUrl = encodeURIComponent(currentUrl);
const shareUrls = { twitter: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`, linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`, facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`, reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedTitle}`,};After:
```typescriptimport { generateAllShareUrls } from "@utils/socialShare";
const shareUrls = generateAllShareUrls({ url: currentUrl, title, description,});Consequences
Section titled “Consequences”Positive
Section titled “Positive”- ✅ DRY Principle: Single source of truth for share URL generation
- ✅ Reusability: Can be used in blog posts, projects, case studies, etc.
- ✅ Testability: 11 unit tests covering edge cases and encoding
- ✅ Maintainability: Platform URL changes only need updates in one place
- ✅ Type Safety: TypeScript ensures valid platform names
- ✅ Security: Consistent
encodeURIComponent()usage prevents XSS
Neutral
Section titled “Neutral”- Platform-specific URL formats are centralized (easier to update, but requires utility changes)
Negative
Section titled “Negative”- None identified - this is a pure improvement following DRY principles
Compliance
Section titled “Compliance”- User Rules: ✅ Follows “action-object” naming pattern (
generateShareUrl) - User Rules: ✅ Uses TypeScript strict mode with proper interfaces
- User Rules: ✅ Includes comprehensive unit tests
- User Rules: ✅ Uses semantic naming conventions
- Performance: ✅ Zero runtime overhead (compile-time only)
Related Files
Section titled “Related Files”src/utils/socialShare.ts- Utility implementationsrc/utils/__tests__/socialShare.test.ts- Unit testssrc/layouts/BlogLayout.astro- Primary consumersrc/pages/projects/[slug].astro- Potential future consumer
Future Considerations
Section titled “Future Considerations”- Add support for additional platforms (WhatsApp, Telegram, etc.)
- Consider adding analytics tracking parameters to share URLs
- Explore server-side share count APIs if needed
Enforcement
Section titled “Enforcement”- Testable consequences:
- TC-1:
src/utils/socialShare.tsunit tests (including encoding edge cases) pass.
- TC-1:
- Checks:
- TC-1 →
test:unitviaquality:ci(status: block, pre-existing gate)
- TC-1 →
- Not machine-checkable: platform list appropriateness.
- Graduation log: (empty at creation; entries added when a check changes status)
Date: 2025-10-01 (footer backfilled 2026-07-05 from git history; this record predates the footer convention)
Participants: Template maintainers
Outcome: Accepted