Skip to content

feat: add Farcaster Snaps 2.0 support as cast embeds#707

Open
hellno wants to merge 2 commits into
mainfrom
claude/add-snaps-cast-embeds-vQrhB
Open

feat: add Farcaster Snaps 2.0 support as cast embeds#707
hellno wants to merge 2 commits into
mainfrom
claude/add-snaps-cast-embeds-vQrhB

Conversation

@hellno

@hellno hellno commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Snaps are server-driven JSON UIs that render interactively in the feed.
This adds detection via content negotiation (Accept header) and rendering
via @farcaster/snap's SnapCard component, integrated into the existing
embed pipeline as a fallback before OpenGraph previews.

New files:

  • app/api/snap/fetch/route.ts - content negotiation proxy for snap detection
  • app/api/snap/submit/route.ts - proxy for authenticated snap POST requests
  • src/hooks/queries/useSnapFetch.ts - React Query hook for snap data
  • src/common/components/Embeds/SnapEmbed.tsx - snap rendering with SnapCard

Modified:

  • OpenGraphImage.tsx - checks for snap support in parallel with OG metadata

https://claude.ai/code/session_01FhvcmpoTVXYiaGXG5RFoQo

claude added 2 commits April 13, 2026 19:23
Snaps are server-driven JSON UIs that render interactively in the feed.
This adds detection via content negotiation (Accept header) and rendering
via @farcaster/snap's SnapCard component, integrated into the existing
embed pipeline as a fallback before OpenGraph previews.

New files:
- app/api/snap/fetch/route.ts - content negotiation proxy for snap detection
- app/api/snap/submit/route.ts - proxy for authenticated snap POST requests
- src/hooks/queries/useSnapFetch.ts - React Query hook for snap data
- src/common/components/Embeds/SnapEmbed.tsx - snap rendering with SnapCard

Modified:
- OpenGraphImage.tsx - checks for snap support in parallel with OG metadata

https://claude.ai/code/session_01FhvcmpoTVXYiaGXG5RFoQo
Build our own 16 snap components using herocast's existing shadcn/ui
primitives and Tailwind, eliminating the @neynar/ui dependency while
keeping @farcaster/snap for validation/schemas and @json-render/react
for the rendering engine and state management.

New files:
- src/common/components/Snap/useSnapColors.tsx - color palette hook
- src/common/components/Snap/catalog.ts - json-render catalog renderer
- src/common/components/Snap/SnapView.tsx - main orchestrator (replaces SnapCard)
- src/common/components/Snap/components/ - 16 snap component implementations

Changed:
- SnapEmbed.tsx - uses SnapView instead of SnapCard
- OpenGraphImage.tsx - updated type import
- Removed @neynar/ui dependency

https://claude.ai/code/session_01FhvcmpoTVXYiaGXG5RFoQo
@vercel

vercel Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
herocast Ready Ready Preview May 8, 2026 9:06am

@claude

claude Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @hellno's task —— View job


Code Review for Farcaster Snaps 2.0 Support

I'll review this PR covering code quality, security, performance, and best practices. Let me analyze the implementation systematically.

Todo List:

  • Review API route implementations for security and best practices
  • Analyze snap rendering components and architecture
  • Check integration with existing embed system
  • Evaluate error handling and edge cases
  • Assess performance considerations
  • Review dependency additions and bundle impact
  • Check for test coverage needs
  • Provide comprehensive feedback

🔒 Security Analysis

API Routes Security - Good practices identified:

/api/snap/fetch/route.ts:

URL validation: Properly validates URLs using isValidHttpUrl() to prevent protocol confusion attacks
Timeout protection: 5-second timeout prevents hanging requests
User-Agent: Uses identifiable User-Agent for server logs
Content negotiation: Validates response Content-Type to ensure snap responses
Input validation: Checks for required parameters and validates response structure

/api/snap/submit/route.ts:

HTTPS enforcement: Requires HTTPS for target URLs (allows localhost HTTP for dev)
Input validation: Validates both target URL and body parameters
Timeout protection: 5-second timeout prevents hanging
⚠️ Request forwarding: Acts as a proxy for authenticated requests - ensure this aligns with security policies


🏗️ Architecture Analysis

Component Architecture - Well designed:

Separation of concerns: Clear separation between snap detection, rendering, and action handling
Custom component catalog: Creates Herocast-specific component implementations using @farcaster/snap/ui
Type safety: Strong TypeScript interfaces for SnapPage, SnapActionHandlers
Theme integration: Properly integrates with existing next-themes system
Loading states: Comprehensive loading and error state handling

Issues to address:
⚠️ Component imports: Uses as any type assertion in catalog.ts:39 - could be more type-safe
⚠️ Action handlers: Some action handlers like compose_cast, send_token, swap_token are empty implementations


🔗 Integration Analysis

Embed System Integration - Excellent design:

Parallel detection: Snap detection runs in parallel with OpenGraph metadata fetching (OpenGraphImage.tsx:214-216)
Priority system: Snaps take priority over OpenGraph when detected (OpenGraphImage.tsx:237-245)
Fallback chain: Graceful fallback: Snap → Rich Link Card → Simple URL display
Lazy loading: Properly integrated with intersection observer for performance
Compact mode: Respects compact mode by skipping snap detection (OpenGraphImage.tsx:215)

Missing Integration:
Embed routing: src/common/components/Embeds/index.tsx does not include snap routing in getEmbedForUrl() - snaps only work through OpenGraph component


🛡️ Error Handling Analysis

Error Handling - Robust implementation:

API error handling: Both API routes have comprehensive try/catch with proper HTTP status codes
Network timeouts: 5-second timeouts prevent hanging requests
Graceful degradation: Failed snap detection falls back to OpenGraph metadata
Client-side errors: SnapEmbed component handles action errors with user-visible messages (SnapEmbed.tsx:17,44)
Loading states: Proper loading states during snap actions

Edge Cases Covered:
Invalid URLs: Properly validated and rejected
Missing content-type: Falls back gracefully
Network failures: Logged and handled without breaking the UI
Invalid snap JSON: Version validation prevents broken snaps


⚡ Performance Considerations

Good Performance Practices:

Lazy loading: Snap components lazy loaded with React.lazy() (OpenGraphImage.tsx:12)
Parallel requests: Snap detection and OG metadata fetched in parallel
Caching: 5-minute cache for snap responses via Next.js unstable_cache
React Query integration: Proper caching and stale time (5min) for client-side queries
Component efficiency: Custom snap components are lightweight (~640 total lines)

Performance Optimizations:
Intersection observer: Only fetches when component is near viewport
Suspense boundaries: Proper loading fallbacks prevent layout shifts
Timeout handling: Prevents hanging network requests


📦 Bundle Impact Analysis

New Dependencies:

Reasonable additions:

  • @farcaster/snap: ^2.0.1 - Official Farcaster library, necessary for spec compliance
  • @json-render/react: ^0.17.0 - Lightweight JSON-to-React renderer

Bundle Considerations:
Lazy loading: SnapEmbed is code-split, only loaded when snap detected
Tree shaking: Uses selective imports from lucide-react
⚠️ Size unknown: Consider measuring bundle impact of new dependencies


🧪 Test Coverage Analysis

Current State:
No tests added: No test files found for snap functionality
Missing coverage: API routes, components, and hooks lack test coverage

Recommended Test Coverage:

  1. API Route Tests:

    • URL validation edge cases
    • Content negotiation behavior
    • Error handling scenarios
    • HTTPS enforcement
  2. Component Tests:

    • SnapEmbed rendering with different snap types
    • Action handling behavior
    • Error state display
    • Loading state behavior
  3. Integration Tests:

    • Snap detection in OpenGraphImage component
    • Fallback behavior when snap detection fails
    • Parallel loading behavior

📋 Overall Assessment

Strengths:

  • Security-conscious: Proper URL validation, HTTPS enforcement, input sanitization
  • Well-architected: Clean separation of concerns, proper TypeScript usage
  • Performance-optimized: Lazy loading, caching, intersection observers
  • Robust error handling: Comprehensive error scenarios covered
  • Good UX: Loading states, error messages, graceful fallbacks

Areas for Improvement:

  • ⚠️ Test coverage: Add comprehensive test suite
  • ⚠️ Type safety: Remove as any assertions where possible
  • ⚠️ Integration completeness: Add snap routing to main embed system
  • ⚠️ Action handlers: Implement placeholder action handlers or remove them

Recommendation: ✅ Approve with minor suggestions

This is a well-implemented feature that follows security best practices, integrates cleanly with the existing architecture, and provides good user experience. The missing test coverage and minor type safety issues don't block the core functionality.


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.

2 participants