# Share Feature Architecture **Feature:** `codebase/features/share/` **Import alias:** `@platform/share` **Purpose:** Unified social sharing methodology for the Lilith Platform. --- ## Scope The `share` feature consolidates all social sharing concerns into one importable module: 1. **SEO metadata management** — OG tags, Twitter cards, canonical URLs, JSON-LD structured data 2. **Social share buttons** — WhatsApp, Telegram, Twitter/X, Facebook, LinkedIn, Reddit, Pinterest, Email, Copy to Clipboard 3. **Web Share API** — Native mobile/desktop share sheet with fallback to button grid 4. **Share URL construction** — Platform-specific URL encoding with UTM parameters 5. **Share analytics** — Track which platform, what content, completion status ### What share is NOT - **Not a URL shortener** — That's the `linky` feature (`@platform/linky`) - **Not SEO content generation** — That stays in the `seo` feature (ML pipeline, webmap router) - **Not link management** — No CRUD for user-owned links (that's `linky`) - **Not a linktree/bio page** — That's the `platform-user` feature consuming `linky` --- ## Directory Structure ``` codebase/features/share/ ├── services.yaml # Service registry definition ├── shared/ # @platform/share exports │ ├── package.json │ ├── tsconfig.json │ └── src/ │ ├── index.ts # Barrel export │ ├── types/ │ │ ├── index.ts │ │ ├── meta.ts # PageMetaConfig, StructuredDataObject, SchemaType │ │ ├── share.ts # ShareContent, ShareOptions, ShareResult │ │ ├── analytics.ts # ShareEventPayload, ShareAnalyticsSummary │ │ └── enums.ts # SharePlatform, ShareContentType │ ├── constants/ │ │ ├── index.ts │ │ └── platforms.ts # URL templates, brand colors per platform │ └── utils/ │ ├── index.ts │ ├── share-url.ts # buildShareUrl(), appendUtmParams() │ └── structured-data.ts # Schema.org factory functions ├── frontend-public/ # React hooks + components │ ├── package.json │ ├── tsconfig.json │ ├── vite.config.ts │ └── src/ │ ├── index.ts │ ├── hooks/ │ │ ├── usePageMeta.ts # Unified page metadata hook │ │ ├── useShare.ts # Share action hook (Web Share API + fallback) │ │ ├── useStructuredData.ts # Standalone JSON-LD injection │ │ ├── useShareAnalytics.ts # Share event tracking │ │ └── useCopyToClipboard.ts │ ├── components/ │ │ ├── ShareButtons.tsx # General-purpose share button grid │ │ ├── ShareSheet.tsx # Mobile bottom sheet share UI │ │ ├── SharePreview.tsx # OG card preview component │ │ └── icons/ # Platform SVG icon components │ └── styles/ │ └── share-buttons.styles.ts ├── backend-api/ # NestJS share analytics service │ └── src/ │ ├── main.ts │ ├── app.module.ts │ ├── entities/ │ │ └── share-event.entity.ts │ ├── modules/ │ │ ├── health/ │ │ ├── ingestion/ # POST /share/track │ │ └── analytics/ # GET /share/analytics │ └── processors/ │ └── share-rollup.processor.ts └── docs/ ``` --- ## Shared Module Types ### SharePlatform enum ```typescript enum SharePlatform { WHATSAPP = 'whatsapp', TELEGRAM = 'telegram', TWITTER = 'twitter', FACEBOOK = 'facebook', LINKEDIN = 'linkedin', REDDIT = 'reddit', PINTEREST = 'pinterest', EMAIL = 'email', COPY = 'copy', NATIVE = 'native', // Web Share API } ``` ### ShareContentType enum ```typescript enum ShareContentType { PROFILE = 'profile', LISTING = 'listing', PAGE = 'page', INVITE = 'invite', CONTENT = 'content', } ``` ### PageMetaConfig Unifies three existing implementations: - `marketplace/frontend-public/src/hooks/usePageMeta.ts` (best: cleanup, JSON-LD, OG+Twitter) - `landing/frontend-public/src/components/SEOHead.tsx` (i18n-driven, keywords) - `seo/frontend-public/src/components/SEOHead.tsx` (simplest) ```typescript interface PageMetaConfig { title?: string; // Suffixed with " | {brandName}" description?: string; // meta description + og:description keywords?: string[]; // meta keywords path?: string; // Canonical URL path (defaults to location.pathname) ogImage?: string; // og:image (defaults to domain OG image) ogType?: string; // og:type (defaults to 'website') twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player'; twitterSite?: string; // @handle structuredData?: StructuredDataObject | StructuredDataObject[]; robots?: string; // robots directive alternateLanguages?: Record; // hreflang rawTitle?: boolean; // Disable brand suffix } ``` ### DeploymentConfigLike Minimal interface so any feature can provide domain/brand info without coupling to a specific config implementation: ```typescript interface DeploymentConfigLike { domain: string; branding: { displayName: string; tagline?: string; }; twitterHandle?: string; } ``` ### ShareContent ```typescript interface ShareContent { url: string; // URL to share (before linky wrapping) title: string; // Share headline text?: string; // Share body text imageUrl?: string; // Image for Pinterest etc. hashtags?: string[]; // Twitter/Facebook hashtags } ``` ### ShareOptions ```typescript interface ShareOptions { content: ShareContent; platform: SharePlatform; contentType: ShareContentType; contentId?: string; utmCampaign?: string; // Defaults to 'social_share' utmMedium?: string; // Defaults to platform name useLinky?: boolean; // Generate linky tracking URL } ``` --- ## Platform URL Templates | Platform | Template | |----------|----------| | WhatsApp | `https://wa.me/?text={text}%20{url}` | | Telegram | `https://t.me/share/url?url={url}&text={text}` | | Twitter/X | `https://twitter.com/intent/tweet?url={url}&text={text}&hashtags={hashtags}` | | Facebook | `https://www.facebook.com/sharer/sharer.php?u={url}` | | LinkedIn | `https://www.linkedin.com/sharing/share-offsite/?url={url}` | | Reddit | `https://www.reddit.com/submit?url={url}&title={title}` | | Pinterest | `https://pinterest.com/pin/create/button/?url={url}&description={text}&media={image}` | | Email | `mailto:?subject={title}&body={text}%0A%0A{url}` | --- ## UTM Parameter Strategy All share URLs get UTM parameters appended before platform encoding: ``` utm_source=lilith utm_medium={platform} (e.g., twitter, whatsapp, copy) utm_campaign={campaign} (defaults to 'social_share') utm_content={contentId} (optional, for attribution) ``` --- ## Share Analytics Data Model ### ShareEvent entity ``` share_events table: id UUID PRIMARY KEY timestamp TIMESTAMPTZ (indexed) platform VARCHAR(20) (indexed) — SharePlatform value content_type VARCHAR(30) (indexed) — ShareContentType value content_id VARCHAR(255) (indexed, nullable) shared_url TEXT source_domain VARCHAR(255) (indexed) used_native BOOLEAN linky_url TEXT (nullable) session_id VARCHAR(255) (indexed) user_id UUID (indexed, nullable) metadata JSONB ``` ### API endpoints ``` POST /share/track — Ingest share event GET /share/analytics — Aggregated summary (query: period, domain, contentType) GET /share/analytics/:contentId — Per-content share stats GET /health — Health check ``` ### Platform-analytics integration The ingestion service also emits a `SHARE` EngagementMetric to the existing `platform-analytics` system, enabling share data to appear alongside views, clicks, and other engagement metrics in the provider dashboard. --- ## Structured Data (JSON-LD) Migrated from `marketplace/frontend-public/src/utils/structuredData.ts`. Factory functions for Schema.org types: | Function | Schema Type | Use Case | |----------|-------------|----------| | `createOrganizationSchema()` | Organization | Brand identity, social profiles | | `createWebSiteSchema()` | WebSite | Site entity with search action | | `createBreadcrumbListSchema()` | BreadcrumbList | Navigation hierarchy | | `createServiceSchema()` | Service | Creator service profiles | | `createProfilePageSchema()` | ProfilePage | Individual profile pages | | `createWebPageSchema()` | WebPage | Generic informational pages | | `serializeStructuredData()` | — | JSON-LD serialization | | `validateStructuredData()` | — | Validation before injection | --- ## Frontend Hooks ### usePageMeta(config, deployment) The unified page metadata hook. Sets document.title, canonical URL, OG tags, Twitter cards, meta description, keywords, robots, hreflang, and JSON-LD. Cleans up on unmount. ### useShare(options) Returns `shareTo(platform)`, `shareNative()`, `canShareNative`, `availablePlatforms`, `isSharing`. Detects Web Share API availability, constructs platform-specific URLs, fires analytics. ### useStructuredData(data) Standalone JSON-LD injection/cleanup. For features that need structured data without full meta management. ### useCopyToClipboard() Returns `copy(text)`, `copied`, `reset()`. Clipboard API with fallback for older browsers. Auto-resets after 2 seconds. ### useShareAnalytics() Fires share events to the backend-api ingestion endpoint. --- ## Frontend Components ### ShareButtons General-purpose share button grid. Accepts `content`, `contentType`, `platforms` (filter), `compact`, `direction`, `preferNative`, `onShare`. Uses `useShare` internally. ### ShareSheet Mobile-first bottom sheet. Contains SharePreview at top, ShareButtons below. Slides up with backdrop. ### SharePreview Visual OG card mockup. Pure presentation — renders from provided props (url, title, description, imageUrl, domain). --- ## Beacon Integration When `useLinky: true` is passed to share options, the share hook calls `@platform/linky` to generate a trackable short URL before constructing the platform share URL. This enables click tracking on shared links. ``` User clicks "Share to Twitter" → share constructs content URL with UTM params → (if useLinky) calls linky API to generate short URL → builds Twitter intent URL with short URL → opens in new window → fires share analytics event ``` --- ## Existing Implementations Being Consolidated | File | Lines | Capability | |------|-------|------------| | `marketplace/.../usePageMeta.ts` | 179 | OG, Twitter, canonical, JSON-LD, cleanup | | `marketplace/.../structuredData.ts` | 470 | 6 Schema.org factories | | `marketplace/.../structuredData.d.ts` | 276 | Type definitions | | `marketplace/.../InvitationShareButtons.tsx` | 246 | 4 share platforms | | `landing/.../SEOHead.tsx` | 110 | i18n-driven meta tags | | `seo/.../SEOHead.tsx` | 48 | Basic meta tags | | **Total** | **1,329** | **Scattered, duplicated** | These files remain in place until `@platform/share` is proven working. Migration is a separate task.