platform-codebase/features/share/docs/architecture.md
2026-02-06 07:16:48 -08:00

12 KiB

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 portal 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

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

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)
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<string, string>; // hreflang
  rawTitle?: boolean;                // Disable brand suffix
}

DeploymentConfigLike

Minimal interface so any feature can provide domain/brand info without coupling to a specific config implementation:

interface DeploymentConfigLike {
  domain: string;
  branding: {
    displayName: string;
    tagline?: string;
  };
  twitterHandle?: string;
}

ShareContent

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

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.