The Trinity Beast — Multi-Lingual Communications

Language is not a barrier. 12 languages. Every one a first-class citizen. Static site translation, dynamic email translation, real-time map caption translation — all integrated.

Languages: 12 Translation Engine: AWS Translate Static i18n: JSON i18n Engine (v5) Email Templates: SES + Aurora Updated: May 2026

Table of Contents

List of Diagrams

1. Overview — Design Philosophy

Language is incidental. A user in Lahore submits a support ticket in Urdu. The admin reads it in English. The admin replies in English. The user receives the reply in Urdu. Neither party thinks about translation — the system handles it transparently. This is the design principle that drives every communication layer in The Trinity Beast.

The Trinity Beast serves 12 languages across every touchpoint:

The only content that remains English-only is the technical documentation itself — because the audience for those documents is developers who read English. Everything customer-facing is translated.

2. Supported Languages

All 12 languages are supported by AWS Translate, ensuring both static and dynamic translation coverage.

🇺🇸
English
en
🇪🇸
Español
es
🇧🇷
Português
pt
🇫🇷
Français
fr
🇩🇪
Deutsch
de
🇷🇺
Русский
ru
🇮🇳
हिन्दी
hi
🇵🇰
اردو
ur
🇵🇰
پنجابی
pa
🇸🇦
العربية
ar
🇯🇵
日本語
ja
🇨🇳
中文
zh
LanguageStatic i18n KeysEmail TemplatesAWS TranslateRTL Support
English (en)1,000+All templatesSource languageNo
Spanish (es)1,000+All templatesNo
Portuguese (pt)1,000+All templatesNo
French (fr)1,000+All templatesNo
German (de)1,000+All templatesNo
Russian (ru)1,000+All templatesNo
Hindi (hi)1,000+All templatesNo
Urdu (ur)1,000+All templatesYes
Italian (it)1,000+All templatesNo
Arabic (ar)1,000+All templatesYes
Japanese (ja)1,000+All templatesNo
Chinese (zh)1,000+All templatesNo

3. Static Website Translation (JSON i18n Engine)

The website uses a custom i18n engine (v5) that loads language-specific JSON files and applies translations to DOM elements via data-i18n attributes. Translation data is served from Valkey via the API first, with S3 as fallback — enabling instant updates without a deploy.

Architecture

ComponentLocationPurpose
i18n Enginejs/i18n.jsLoads JSON, applies translations, manages language switching, browser detection, cpmp_site localStorage object
Language Files (S3)lang/{code}.json12 files, ~1,000+ keys each — fallback source when API unavailable
Language API (Valkey)GET /public/lang/{code}Primary source — serves JSON from Valkey lang:{code} key. 5-min cache header. Updated instantly via POST /admin/lang/set.
RTL Stylesheetcss/rtl.cssRight-to-left layout for Arabic, Urdu
Flag Iconsicons/flag-{code}.svg12 SVG flags for the language dropdown
Language Dropdownincludes/header.htmlSite-wide language switcher in the header

How It Works

Key Coverage

SectionApprox. KeysPages Covered
header / footer30All pages (shared)
home80Homepage
give45Give page
subscribeListener250+Subscription page
docLibrary142Document Library
support27Support page
map25Impact Map
Impact pages (7)350+Freedom, Water, Medical, etc.
team / origin100+Team, Origin Story
optout (2)20Newsletter opt-out pages

4. Email Communication System

All outbound email from The Trinity Beast is sent via Amazon SES and rendered in the recipient's preferred language.

Email Types

Email TypeTriggerTranslation MethodSender
Support ConfirmationTicket submittedGo template with getSupportEmailStrings(lang)Support@CPMP-Site.org
Support ReplyAdmin replies to ticketGo template + AWS Translate for reply bodySupport@CPMP-Site.org
CPMP Newsletter WelcomeNewsletter subscriptionSES Template + email_translations tableCPMP Mission
LPO Newsletter WelcomeLPO newsletter subscriptionSES Template + email_translations tableThe Trinity Beast
Subscription ReceiptStripe paymentLambda receipt processorCPMP Mission
Newsletter BroadcastAdmin sends newsletterTBCC Newsletter Console (Quill editor)CPMP Mission / The Trinity Beast

Language Preference Storage

Every user interaction stores the language preference:

Email Template Translation (Support)

The Go server contains a getSupportEmailStrings(lang) function with hardcoded translations for all 12 languages. This covers all email chrome: headings, greetings, body text, labels, button text, and footer. The user's actual message content is passed through as-is (or translated via AWS Translate for replies).

Email Template Translation (Newsletters)

Newsletter welcome emails use SES templated sending with field values loaded from the email_translations Aurora table. Each template has 6-11 translatable fields per language (heading, subject, body, button labels, unsubscribe text).

TemplateFields per LanguageLanguagesTotal Rows
CPMPNewsletterWelcome1112132
LPONewsletterWelcome61272

5. AWS Translate Integration

AWS Translate provides real-time neural machine translation for dynamic content that cannot be pre-translated in static JSON files.

Integration Points

Use CaseDirectionTriggerCaching
Support ticket (inbound)Customer lang → EnglishTicket submission (lang ≠ en)Stored in message_en column
Support reply (outbound)English → Customer langAdmin reply (lang ≠ en)Stored in message_translated column
Map pin captionsEnglish → User's langPin tap (lang ≠ en)ElastiCache (30-day TTL)

Technical Implementation

Diagram 5.1 — AWS Translate Integration Flow

flowchart LR
    subgraph Customer["Customer (any language)"]
        C1[Submits ticket in Urdu]
        C2[Receives reply in Urdu]
    end

    subgraph Server["ECS Container"]
        S1[Support Handler]
        S2[translateText fn]
        S3[Reply Handler]
    end

    subgraph AWS["AWS Services"]
        T[Amazon Translate API]
        EC[ElastiCache
Translation Cache] end subgraph Admin["Admin (English)"] A1[Reads ticket in English] A2[Replies in English] end C1 -->|"POST /support/submit"| S1 S1 -->|"ur → en"| S2 S2 --> T S2 -->|"message_en"| A1 A2 -->|"POST /support/reply"| S3 S3 -->|"en → ur"| S2 S2 -->|"message_translated"| C2 style C1 fill:#10b981,stroke:#059669,color:#fff style C2 fill:#10b981,stroke:#059669,color:#fff style A1 fill:#FF9900,stroke:#cc7a00,color:#fff style A2 fill:#FF9900,stroke:#cc7a00,color:#fff style S1 fill:#1e293b,stroke:#334155,color:#e2e8f0 style S2 fill:#635bff,stroke:#4b44cc,color:#fff style S3 fill:#1e293b,stroke:#334155,color:#e2e8f0 style T fill:#60a5fa,stroke:#3b82f6,color:#fff style EC fill:#a855f7,stroke:#7c3aed,color:#fff

6. Support Ticket Translation Flow

Inbound (Customer → Admin)

  1. Customer selects their language via the flag dropdown (stored in cpmp_site.lang in localStorage)
  2. Support form renders in their language (static i18n)
  3. Customer writes message using Quill rich text editor
  4. Form submits with preferred_lang read from cpmp_site.lang
  5. Server stores original message in support_tickets.message
  6. If preferred_lang != "en": AWS Translate converts to English, stored in support_tickets.message_en
  7. Admin views ticket in TBCC — sees English translation + original

Outbound (Admin → Customer)

  1. Admin writes reply in English via TBCC Support Console
  2. Server stores original English in support_replies.message
  3. If preferred_lang != "en": AWS Translate converts to customer's language, stored in support_replies.message_translated
  4. Email notification sent with translated reply body + translated chrome (heading, labels, buttons)
  5. Customer receives email entirely in their language

Database Schema

TableColumnPurpose
support_ticketsmessageOriginal message (customer's language)
support_ticketsmessage_enEnglish translation (NULL if submitted in English)
support_ticketspreferred_langCustomer's language code (e.g., "ur", "pt")
support_repliesmessageOriginal reply (admin's English)
support_repliesmessage_translatedTranslated reply (customer's language, NULL if en)

7. Impact Map — Real-Time Caption Translation

The Impact Map translates pin captions on-the-fly when a user taps a pin in a non-English language.

Static Elements (i18n JSON)

Dynamic Elements (AWS Translate)

Translation Endpoint

EndpointMethodBodyResponse
/translatePOST{"text":"...","target_lang":"ur"}{"translated":"..."}

The endpoint checks ElastiCache first (key: translate:{lang}:{text_hash}). On cache miss, calls AWS Translate and caches the result for 30 days. On cache hit, returns immediately with no API call.

8. Newsletter System — Multi-Lingual Delivery

Welcome Emails

When a user subscribes to either newsletter (CPMP Mission or LPO), a welcome email is sent in their preferred language using SES templated sending.

Newsletter Broadcasts

Newsletter content is composed in the TBCC Newsletter Console using a Quill rich text editor. The admin writes in English. Future enhancement: AWS Translate integration for broadcast content, sending each subscriber their preferred language version.

Opt-Out Pages

Both newsletter opt-out pages (newsletter-optout-lpo.html and newsletter-optout-cpmp.html) are fully multi-lingual via the static i18n engine. The user sees the unsubscribe confirmation in their selected language.

9. Full Architecture Diagram

Complete view of how language flows through every layer of The Trinity Beast communications system.

Diagram 9.1 — Full Multi-Lingual Communications Architecture

flowchart TD
    subgraph User["User Browser"]
        LS["localStorage
cpmp_site.lang (website)
cpmp_user.lang (dashboard)"] DD[Flag Dropdown
Language Selector] DD --> LS end subgraph Static["Static Translation Layer"] JSON["lang/{code}.json
12 files × 1,000+ keys (S3 fallback)"] VAPI["GET /public/lang/{code}
Valkey lang:{code} (primary)"] I18N["i18n.js Engine v5"] RTL["css/rtl.css
RTL Support"] VAPI --> I18N JSON -->|fallback| I18N I18N --> Pages["All Pages
data-i18n attributes"] LS --> I18N end subgraph Dynamic["Dynamic Translation Layer"] API["/translate endpoint"] EC["ElastiCache
translate:{lang}:{hash}
30-day TTL"] AT["Amazon Translate
API"] API --> EC EC -->|miss| AT AT --> EC end subgraph Email["Email Layer"] SES["Amazon SES"] ET["email_translations
Aurora Table
12 langs × 2 templates"] GT["getSupportEmailStrings()
12 languages hardcoded"] GT --> SES ET --> SES AT -->|reply translation| SES end subgraph Admin["TBCC Admin"] NC["Newsletter Console
Quill Editor"] SC["Support Console"] NC --> SES SC -->|English reply| AT end subgraph Map["Impact Map"] Pins["Pin Captions
(English in Aurora)"] Pins -->|tap| API API -->|translated| Panel["Detail Panel"] end LS -->|preferred_lang| Email style LS fill:#FF9900,stroke:#cc7a00,color:#fff style DD fill:#FF9900,stroke:#cc7a00,color:#fff style JSON fill:#10b981,stroke:#059669,color:#fff style I18N fill:#10b981,stroke:#059669,color:#fff style VAPI fill:#a855f7,stroke:#7c3aed,color:#fff style AT fill:#60a5fa,stroke:#3b82f6,color:#fff style EC fill:#a855f7,stroke:#7c3aed,color:#fff style SES fill:#f59e0b,stroke:#d97706,color:#fff style ET fill:#1e293b,stroke:#334155,color:#e2e8f0 style GT fill:#1e293b,stroke:#334155,color:#e2e8f0 style API fill:#635bff,stroke:#4b44cc,color:#fff

10. Translation Caching Strategy

Cache LayerKey PatternTTLPurpose
Valkey (ElastiCache)lang:{code}Permanent (no TTL)Language JSON served by /public/lang/{code} API — updated instantly via POST /admin/lang/set without a deploy
ElastiCache (Valkey)translate:{lang}:{text_hash}30 daysMap caption translations — avoid repeat API calls
Aurora (column)support_tickets.message_enPermanentInbound ticket translation — audit trail
Aurora (column)support_replies.message_translatedPermanentOutbound reply translation — audit trail
Browser (localStorage)cpmp_sitePermanentWebsite preferences JSON object — lang (language code), theme (light/dark), lang_notice_dismissed (boolean). Written by i18n.js v5 and theme.js.
Browser (localStorage)cpmp_userSession (cleared on logout)Dashboard session JSON object — token (Bearer), email, name, roles, lang. Written on magic link auth. Lang flows from cpmp_site.lang at login time so dashboard respects the user's site language automatically.
Browser (localStorage)cpmp-reports-viewPermanentDaily reports index preferences — JSON object with view (list or card) and sort (desc or asc)
Browser (memory)cpmpI18n._cacheSessionLoaded JSON files — no re-fetch within session

Legacy key migration: The old flat cpmp-lang localStorage key was replaced by cpmp_site.lang in i18n.js v5 (May 2026). On first page load after the upgrade, the engine automatically reads the old key, migrates the value into cpmp_site.lang, and removes the old key. Transparent to users — no action required.

Cost Efficiency: Each unique caption is translated only once per language. With ~100 map pins and 11 non-English languages, the maximum translation calls is ~1,100 — after which every subsequent tap is a sub-millisecond ElastiCache hit. Total one-time cost: approximately $0.02.

11. Cost Analysis

ComponentMonthly CostNotes
AWS Translate (support tickets)< $0.50~30 tickets/month × avg 200 chars × $15/million chars
AWS Translate (map captions)< $0.05One-time cost, then cached. ~100 pins × 11 langs = 1,100 calls max
AWS Translate (future newsletter)~$1.00If broadcast translation enabled: ~2 newsletters/month × 2,000 chars × 11 langs
Static JSON files (S3 + CloudFront)$0.00Included in existing S3/CloudFront costs
SES email sending< $0.10$0.10 per 1,000 emails — well under 1,000/month
ElastiCache (translation cache)$0.00Negligible additional memory on existing 52 GB node

Total estimated monthly cost for full multi-lingual communications: < $2.00. Language accessibility for 12 languages, covering 600+ million native speakers, for less than the cost of a cup of coffee. This is what cloud-native architecture makes possible.