Skip to content

Content Platform — Integrations

Third-party and self-hosted services that extend a content platform. GE defaults to EU-hosted, privacy-friendly, open-source-where-possible options.


Newsletter

Brevo (Default for GE)

IF: Client needs transactional + marketing email from one provider THEN: Use Brevo (FR) — EU-headquartered, GDPR-native, transactional + marketing in one platform

INCLUDES: Brevo API for email delivery INCLUDES: React Email templates (same component system as frontend) via SMTP or API INCLUDES: Double opt-in flow with confirmation email INCLUDES: Unsubscribe handling with one-click list-unsubscribe header INCLUDES: Bounce and complaint webhook processing COMPLIANCE: EU-headquartered (Paris, France), data stored in EU by default

// Newsletter signup with double opt-in
import * as SibApiV3Sdk from '@sendinblue/client';
const apiInstance = new SibApiV3Sdk.TransactionalEmailsApi();
apiInstance.setApiKey(SibApiV3Sdk.TransactionalEmailsApiApiKeys.apiKey, process.env.BREVO_API_KEY!);

async function subscribeNewsletter(email: string) {
  const token = crypto.randomUUID();
  await db.insert(newsletterSubscriptions).values({
    email,
    confirmToken: token,
    status: 'pending',
  });
  await apiInstance.sendTransacEmail({
    sender: { email: 'newsletter@client-domain.eu' },
    to: [{ email }],
    subject: 'Confirm your subscription',
    htmlContent: renderConfirmationEmail({ token }),
  });
}

Mailjet (EU Alternative)

IF: Client needs developer-first API with strong EU data residency THEN: Use Mailjet (FR) — EU-headquartered, strong API, React Email compatible

INCLUDES: Mailjet API v3.1 for email delivery INCLUDES: Template engine with Passport (Mailjet WYSIWYG) or custom HTML INCLUDES: Bounce and complaint webhook processing COMPLIANCE: EU-headquartered (Paris, France), EU data processing by default

Resend (Secondary)

IF: Client explicitly requires Resend for developer experience THEN: Integrate Resend with sovereignty acknowledgement

NOTE: US-based service. Use only if client explicitly requires. EU data sovereignty risk. INCLUDES: Resend SDK for email delivery INCLUDES: React Email templates (same component system as frontend)

Mailchimp (Secondary)

IF: Client already uses Mailchimp for marketing THEN: Integrate via Mailchimp API v3

INCLUDES: Audience sync — new subscribers added via API INCLUDES: Tag-based segmentation (map content categories to Mailchimp tags) INCLUDES: Campaign trigger webhook on content publish NOTE: US-based service. Use only if client explicitly requires. EU data sovereignty risk. CHECK: Mailchimp stores data in US by default — verify EU data processing addendum signed

Newsletter Digest Automation

SCOPE_ITEM: Automated weekly/monthly digest from recently published content SCOPE_ITEM: Content selection — latest N articles or editor's picks OPTIONAL: Per-subscriber personalized digest (based on followed topics) OPTIONAL: Manual newsletter composition with content picker in admin


Analytics

Plausible Analytics (Default for GE)

IF: Client prioritizes GDPR compliance and privacy THEN: Use Plausible — no cookies, no personal data, EU-hosted

INCLUDES: Script tag integration (< 1KB, no performance impact) INCLUDES: Page views, unique visitors, bounce rate, visit duration INCLUDES: Traffic sources, referrers, UTM tracking INCLUDES: Top pages and entry/exit pages INCLUDES: Device, browser, OS breakdown INCLUDES: Goal/event tracking via custom events COMPLIANCE: No cookies — no consent banner required for analytics COMPLIANCE: EU-hosted infrastructure (Hetzner, Germany)

// Custom event tracking
function trackEvent(name: string, props?: Record<string, string>) {
  if (typeof window !== 'undefined' && window.plausible) {
    window.plausible(name, { props });
  }
}

// Usage
trackEvent('Newsletter Signup', { location: 'article_footer' });
trackEvent('Article Share', { platform: 'twitter' });

Fathom Analytics

IF: Client wants simple analytics with stronger enterprise features THEN: Use Fathom — similar privacy stance, slightly different feature set

INCLUDES: EU data isolation option INCLUDES: Event tracking and custom dashboards INCLUDES: Uptime monitoring included

Google Analytics 4 (Secondary)

IF: Client specifically requires GA4 (existing marketing stack dependency) THEN: Integrate GA4 with consent mode v2 + server-side proxy

NOTE: US-based service. Use only if client explicitly requires. EU data sovereignty risk. CHECK: Cookie consent banner required CHECK: Consent mode v2 configured (required in EU since March 2024) CHECK: Data retention set to minimum needed (14 months max) CHECK: IP anonymization enabled CHECK: Consider server-side proxy to reduce direct data transfer to Google


PostgreSQL Full-Text Search (Default)

IF: Content volume < 10,000 articles AND simple search needs THEN: PostgreSQL tsvector/tsquery — zero additional infrastructure

INCLUDES: Full-text index on title, body, excerpt INCLUDES: Language-aware stemming (Dutch, English, German) INCLUDES: Ranked results by relevance

-- Full-text search index
ALTER TABLE articles ADD COLUMN search_vector tsvector
  GENERATED ALWAYS AS (
    setweight(to_tsvector('dutch', coalesce(title, '')), 'A') ||
    setweight(to_tsvector('dutch', coalesce(excerpt, '')), 'B') ||
    setweight(to_tsvector('dutch', coalesce(body_text, '')), 'C')
  ) STORED;

CREATE INDEX articles_search_idx ON articles USING GIN(search_vector);

Meilisearch

IF: Content volume > 10,000 articles OR search-as-you-type required THEN: Meilisearch — self-hosted, sub-50ms, typo-tolerant

INCLUDES: Search-as-you-type with instant results INCLUDES: Typo tolerance and synonym support INCLUDES: Faceted filtering (by category, author, date) INCLUDES: Search analytics (popular queries, zero-result queries) OPTIONAL: AI-powered hybrid search (keyword + semantic vector) COMPLIANCE: Self-hosted on EU infrastructure — full data control

// Meilisearch sync on content publish
import { MeiliSearch } from 'meilisearch';
const meili = new MeiliSearch({ host: process.env.MEILI_URL, apiKey: process.env.MEILI_KEY });

async function indexArticle(article: Article) {
  await meili.index('articles').addDocuments([{
    id: article.id,
    title: article.title,
    excerpt: article.excerpt,
    body_text: stripHtml(article.bodyHtml),
    categories: article.categories.map(c => c.name),
    author: article.author.name,
    published_at: article.publishedAt?.getTime(),
  }]);
}

Algolia (Secondary)

IF: Client requires managed search with enterprise SLA AND explicitly chooses Algolia THEN: Algolia — hosted, fast, but US-based

NOTE: US-based service. Use only if client explicitly requires. EU data sovereignty risk. CHECK: Algolia processes data in US regions by default CHECK: Enterprise plan required for EU-dedicated infrastructure CHECK: Per-search pricing — estimate cost at expected traffic volume CHECK: Prefer Meilisearch (FR, self-hosted) as primary option


Social Media

Share Integration

SCOPE_ITEM: Share buttons for major platforms (X/Twitter, LinkedIn, Facebook, WhatsApp) SCOPE_ITEM: Pre-populated share text from article title and URL SCOPE_ITEM: UTM parameters on shared URLs for attribution tracking

Social Scheduling

OPTIONAL: Auto-post to social platforms on content publish OPTIONAL: Integration with Buffer or social scheduling API OPTIONAL: Custom social copy per platform (stored in CMS)


Translation Services

IF: Client needs multi-language content THEN: Integrate translation workflow

Manual Translation Workflow

SCOPE_ITEM: Mark content as "needs translation" per target locale SCOPE_ITEM: Translation assignment and status tracking in admin SCOPE_ITEM: Side-by-side editor (source language + target language)

Machine Translation Assist

OPTIONAL: DeepL API for initial translation draft OPTIONAL: Human review required before publishing machine translations OPTIONAL: Translation memory — reuse previously approved translations COMPLIANCE: DeepL Pro — EU-based, no data retention on API calls

CHECK: Machine translations are ALWAYS reviewed by human before publish CHECK: Translated content clearly indicates language to search engines (hreflang)


CDN

bunny.net (Default for GE)

IF: Client expects > 10,000 monthly visitors OR has media-heavy content THEN: bunny.net CDN — EU-headquartered, cost-effective, GDPR-friendly

INCLUDES: Pull zone from origin storage INCLUDES: Global edge caching with EU-primary PoPs INCLUDES: Automatic HTTPS INCLUDES: Cache purge API for content updates OPTIONAL: bunny.net Image Processing — on-the-fly resize, crop, format conversion OPTIONAL: bunny.net Stream — video hosting with adaptive streaming COMPLIANCE: EU-headquartered (Slovenia), GDPR-compliant by default

Cloudflare

IF: Client already uses Cloudflare for DNS/security THEN: Cloudflare CDN — broader security features, global network

CHECK: Verify Cloudflare data processing configuration for EU compliance


RSS and Syndication

SCOPE_ITEM: RSS 2.0 feed at /feed.xml SCOPE_ITEM: Feed includes latest 20 published articles SCOPE_ITEM: Full content or excerpt (configurable) OPTIONAL: Category-specific RSS feeds (/categories/[slug]/feed.xml) OPTIONAL: Atom feed for standards-compliant readers OPTIONAL: JSON Feed for modern feed readers


Webhooks (Outgoing)

OPTIONAL: Webhook dispatch on content events (publish, update, archive) OPTIONAL: Configurable webhook URLs per event type OPTIONAL: Retry with exponential backoff (3 attempts) OPTIONAL: Webhook delivery log with response codes


Integration Selection Guide

Need Default Choice Alternative EU-Hosted
Email/Newsletter Brevo (FR) Mailjet (FR), Resend (US) Brevo: yes
Analytics Plausible (EU) Fathom, GA4 (US — consent required) Plausible: yes
Search (small) PostgreSQL FTS yes
Search (large) Meilisearch (FR) Algolia (US — sovereignty risk) Meili: self-host
CDN bunny.net Cloudflare bunny.net: yes
Translation DeepL API DeepL: yes
Social scheduling Buffer API Custom Buffer: no

CHECK: Every integration evaluated for EU data residency compliance CHECK: API keys stored in Vault — never in environment files or code CHECK: Rate limits documented per integration CHECK: Fallback behavior defined when integration is unavailable