Skip to Content
Content ToolkitMulti-Language Content Generation

Multi-Language Content Generation

[To Build] · All writer agents · language field on Activity

Adds a language field to content activities so all writer agents can produce output in the tenant’s chosen language. Supports 7 languages in v1, with language-aware readability scoring and right-to-left layout support for Arabic.

Related: Blog Writer · Social Post Writer · Email Writer · Content Optimizer · Content Toolkit Overview


Overview

FunctionGenerate content in 7 languages across all writer agents
TypePlatform Enhancement — All Writer Agents
StatusTo Build
PriorityP3 — Growth
LanguagesEnglish · Spanish · French · German · Arabic · Hindi · Portuguese
CreditsNo credit change — same cost per deliverable regardless of language
PlanStarter: English only · Professional: all 7 languages

Why This Is Needed

Most Leadmetrics tenants operate in non-English markets — particularly the Middle East (AED region) and India (INR region). A content platform that only produces English content has limited value for these tenants. Adding multi-language support directly expands the addressable market for the Professional plan without requiring new agent infrastructure.


Supported Languages — v1

LanguageCodeRegion most relevantRTL
EnglishenAllNo
SpanishesLatin America, SpainNo
FrenchfrFrance, Canada, AfricaNo
GermandeDACHNo
ArabicarMiddle East (AED region)Yes
HindihiIndia (INR region)No
PortugueseptBrazil, PortugalNo

Agents Affected

AgentChange Required
blog-writerAccept language in input; append language instruction to system prompt
social-post-writerAccept language; platform-specific emoji and hashtag norms vary per language
email-writerAccept language; subject line character limits are the same across languages
gbp-post-writerAccept language
keyword-researcherAccept language + locale; seed keywords may be non-English; output cluster in same language
content-brief-writerAccept language; brief headings and rationale in chosen language
topic-researcherAccept language; topic titles in chosen language
research-note-writerAccept language; notes in chosen language, sources may be in that language too

Agents not affected in v1: strategy-writer, deliverable-planner, activity-planner, report-writer — these are internal operational documents that remain in English.


How Language Is Applied

Prompt Injection Pattern

No separate system prompts per language. Instead, a language instruction block is appended to the existing system prompt at runtime:

// In the worker, after loading the system prompt from DB: if (input.language && input.language !== 'en') { const languageBlock = buildLanguageInstruction(input.language); systemPrompt = `${agentConfig.systemPrompt}\n\n${languageBlock}`; }
function buildLanguageInstruction(language: SupportedLanguage): string { const languageNames: Record<SupportedLanguage, string> = { es: 'Spanish', fr: 'French', de: 'German', ar: 'Arabic', hi: 'Hindi', pt: 'Portuguese (Brazilian)', }; return [ `## Language Requirement`, ``, `Write ALL output in ${languageNames[language]}.`, `- Headings, body text, meta description, and slug must all be in ${languageNames[language]}`, `- Do not mix languages within the output`, `- Use vocabulary and phrasing natural to a native ${languageNames[language]} speaker`, `- Maintain the same structure and quality standards specified above`, ].join('\n'); }

Keyword Research in Non-English

The keyword-researcher agent accepts seed keywords in any language. When language !== 'en':

  1. The agent is instructed to output the full keyword cluster in the specified language
  2. Volume and difficulty estimates are noted as approximate (most keyword data skews toward English)
  3. The agent supplements with localized variants — e.g. a Hindi seed keyword will return Hindi LSI terms

Note: SEMrush and DataForSEO both support non-English keyword data for most markets. If the tool integration layer supports locale-specific queries, volume/difficulty data will be accurate. Otherwise, the agent returns qualitative estimates flagged with "volume": null, "difficultyNote": "estimated".


Language-Aware Readability Scoring

The Flesch-Kincaid formula is calibrated for English. Different target thresholds apply per language group in the Content Optimizer:

LanguageReadability targetNotes
EnglishGrade 8–10 (Flesch 60–70)Standard
SpanishGrade 9–11Spanish sentence structure allows longer sentences naturally
FrenchGrade 9–11Similar to Spanish
GermanGrade 8–10German compound words inflate word-per-sentence counts; parser must handle compounds
ArabicSyllable-based scoring not reliableSwitch to paragraph length + sentence count only; skip Flesch
HindiSkip Flesch; use sentence length + paragraph density onlyDevanagari character count ≠ English word count
PortugueseGrade 8–10Closest to English calibration

Arabic RTL Support

Arabic is the only RTL language in v1 scope. Required UI changes:

  • Blog editor: dir="rtl" on the content editable area when language is Arabic
  • Score panel sidebar: layout flips to left side in RTL mode
  • Brief export public view: RTL layout for Arabic briefs
  • Social post preview cards: RTL text alignment
  • Dashboard list views: text direction adapts per post’s language field

Activity Model Change

Add to Activity input metadata (already a Json field on the model — no migration needed for the field itself, but the type definition in packages/queue/src/types.ts updates):

// In ActivityJobData or equivalent language?: SupportedLanguage; type SupportedLanguage = 'en' | 'es' | 'fr' | 'de' | 'ar' | 'hi' | 'pt';

The language field is inherited by child activities (social posts, emails) spawned from a blog activity, unless overridden.


Plan Gating

LanguagePlan required
English (en)Starter+
All other languagesProfessional+

The API validates the tenant’s plan before processing a non-English activity. If a Starter tenant submits a job with language: 'es', the API returns 403 with { error: "Multi-language generation requires the Professional plan" }.


Key Design Decisions

DecisionChoiceRationale
Language instruction appended, not separate promptSingle system prompt with runtime language blockAvoids maintaining 7 versions of every system prompt; language is an output constraint, not a domain change
English-only for operational agentsstrategy-writer, report-writer etc. stay EnglishThese are internal documents used by DMs, not client-facing content
Approximate keyword data in non-EnglishFlag with difficultyNote rather than blockBetter to surface approximate data than refuse; DM can verify manually
Inherit language from parent activityChild activities (social, email) inherit parent languageRepurposed social posts should match the language of the source blog

Implementation Phases

Phase 1 — Blog + Social (English-adjacent languages)

  1. Add SupportedLanguage type to packages/common/src/types.ts
  2. Add language field to all writer agent input types
  3. Implement buildLanguageInstruction() utility in packages/agents/src/utils/
  4. Update blog-writer.worker.ts to append language block when language !== 'en'
  5. Update social-post-writer.worker.ts similarly
  6. Language selector in blog + social activity creation forms (Starter hides non-English options)
  7. Test with Spanish + French (closest to English in prompt terms)

Phase 2 — Remaining Agents + Languages

  1. Update keyword-researcher, content-brief-writer, email-writer, gbp-post-writer
  2. Add Arabic + Hindi support; implement language-aware readability thresholds in Content Optimizer
  3. RTL UI changes for Arabic in blog editor and brief export

Phase 3 — Plan Gating

  1. Language plan validation in API middleware
  2. Dashboard language selector: non-English options locked with upgrade prompt for Starter tenants

© 2026 Leadmetrics — Internal use only