Summary
Enable users to contribute URL metadata when server-side fetching fails (blocked by Cloudflare, bot protection, etc.). Creates a crowdsourced metadata cache that improves over time.
Problem
Current server-side metadata fetching (Trek → Microlink → Neynar) fails for ~30% of URLs due to:
- Cloudflare bot protection
- Rate limiting
- Datacenter IP blocking
Result: Many URLs show empty/broken previews.
Proposed Solution
When server fails, signal the client to attempt fetching via a CORS proxy (allorigins.win), parse with Trek WASM (same parser as server), and contribute metadata back to a persistent Supabase cache.
Server fails → Client tries allorigins.win → Parse with Trek WASM → POST to /api/embeds/metadata/contribute → Cached for all users
Key Design Decisions
- Parser: Trek WASM on client (same as server, consistent results)
- Storage: New
url_metadata Supabase table with RLS
- Source tracking: Track where metadata came from (
server-trek, client-allorigins, client-manual)
- Auth: Require login for contributions (existing Supabase auth)
- Rate limiting: Skip for now, can add later
- Manual fallback UI: Not in v1, but DB schema supports it
Database Schema
CREATE TABLE url_metadata (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
url TEXT NOT NULL,
url_hash TEXT NOT NULL, -- SHA256 for indexing
title TEXT,
description TEXT,
image TEXT,
favicon TEXT,
source TEXT NOT NULL, -- 'server-trek', 'client-allorigins', 'client-manual'
contributed_by UUID REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
status TEXT DEFAULT 'active',
metadata JSONB, -- Future extensibility
UNIQUE(url_hash)
);
API Changes
GET /api/embeds/metadata - Returns { needsClientFetch: true } when server fails
POST /api/embeds/metadata/contribute (NEW) - Accepts user-contributed metadata
Implementation Phases
- Database: Create
url_metadata table + RLS policies
- Server: Check contributed cache, return
needsClientFetch signal
- Client: Trek WASM loading, allorigins fetch, contribute endpoint call
- Future: Manual contribution UI, voting, moderation
Full PRD
See docs/prd-client-metadata-contribution.md for complete technical design.
Open Questions
Related
- Current metadata route:
app/api/embeds/metadata/route.ts
- Trek integration added in recent commits
Summary
Enable users to contribute URL metadata when server-side fetching fails (blocked by Cloudflare, bot protection, etc.). Creates a crowdsourced metadata cache that improves over time.
Problem
Current server-side metadata fetching (Trek → Microlink → Neynar) fails for ~30% of URLs due to:
Result: Many URLs show empty/broken previews.
Proposed Solution
When server fails, signal the client to attempt fetching via a CORS proxy (allorigins.win), parse with Trek WASM (same parser as server), and contribute metadata back to a persistent Supabase cache.
Key Design Decisions
url_metadataSupabase table with RLSserver-trek,client-allorigins,client-manual)Database Schema
API Changes
GET /api/embeds/metadata - Returns
{ needsClientFetch: true }when server failsPOST /api/embeds/metadata/contribute (NEW) - Accepts user-contributed metadata
Implementation Phases
url_metadatatable + RLS policiesneedsClientFetchsignalFull PRD
See
docs/prd-client-metadata-contribution.mdfor complete technical design.Open Questions
Related
app/api/embeds/metadata/route.ts