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
Search¶
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