Communication is the foundation of every online community. But the moment people from different countries join the same space, one invisible problem shows up fast: language.
You might be comfortable chatting in English, while someone else prefers Hindi, Spanish, or Japanese. Most chat apps assume everyone will “figure it out” — but in reality, that often leads to confusion, hesitation, or people staying silent.
I wanted to fix that.
So I built FlowTalk, a real-time multilingual chat application where users can write in their own language and instantly read messages in theirs — without breaking the flow of conversation.
In this article, I’ll walk through how I built it, the unexpected translation problems I ran into, and how I used Lingo.dev to solve them in a clean, scalable way.
🚀 The Tech Stack
I kept the stack modern but practical:
- Frontend: Next.js 16 (App Router) + React 19
- Styling: Tailwind CSS v4
- Backend: Next.js API routes + MongoDB
- Real-time updates: Pusher / polling
- Translation layer: Lingo.dev
Nothing exotic — just tools that work well together.
🏗️ High-Level Architecture
The core challenge wasn’t how to translate text.
It was how to translate text without slowing down a real-time chat.
Here’s the flow I ended up with:
- A user sends a message (for example, “Hello everyone”)
- The server receives the message and detects the source language
- A Translation Engine checks if translations already exist (cache first)
- If not cached, it calls Lingo.dev to generate translations
- The message is broadcast to all connected clients
- Each client displays the message in the user’s preferred language
Only one message is sent — translation is treated as metadata, not a new chat message.
🧠 The Real Translation Problems (That No One Mentions)
This is where things got interesting.
Once real users started testing the app, I discovered problems that don’t show up in simple demos.
1. Script ≠ Language (Hinglish Is Real)
One of the most common messages I saw was something like:
muje aapki help chahiye
This is Hindi, but written using English letters (often called Hinglish).
Most systems either:
- Treat it as English (wrong), or
- Don’t translate it at all (also wrong)
So FlowTalk detects language intent, not just the alphabet used.
Correct result:
I need your help
2. Brand Names Should Not Be Translated
Auto-translation loves to translate everything — including things it absolutely shouldn’t.
Examples:
- ChatGPT
- Discord
- React
- Next.js
If these get translated, the message becomes confusing fast.
I needed a way to protect proper nouns and technical terms.
3. Broken Characters & Formatting Issues
Another subtle issue:
Some platforms and fonts don’t handle all scripts perfectly.
That can lead to:
- Broken characters
- Random symbols
- Numbers appearing where text should be
To avoid this, I normalized output and ensured Unicode-safe formatting across the pipeline.
💡 The Heart of FlowTalk: The Translation Engine
At the center of everything is a small but powerful service: TranslationEngine.
Instead of scattering translation logic everywhere, I wrapped it in a single layer that handles:
- Language detection
- Caching
- Glossary protection
- Error handling
Here’s a simplified version:
// src/services/TranslationEngine.ts
import { LingoDotDevEngine } from "lingo.dev/sdk";
export class TranslationEngine {
private lingoEngine: LingoDotDevEngine;
constructor(apiKey: string) {
this.lingoEngine = new LingoDotDevEngine({
apiKey,
});
}
async translateText(
content: string,
sourceLang: string,
targetLang: string
): Promise<string> {
if (sourceLang === targetLang) {
return content;
}
const result = await this.lingoEngine.localizeText(content, {
sourceLocale: sourceLang,
targetLocale: targetLang,
});
return result;
}
}
This is where Lingo.dev really shines.
Instead of simple word replacement, it provides context-aware translation, which makes conversations feel natural rather than robotic.
Chekout My Repo here: https://github.com/TejasRawool186/FlowTalk
special thanks to @sumitsaurabh927 @maxprilutskiy for the continious guidance

Top comments (0)