I Built a Document Translator in 48 Hours. Here's What Lingo.dev Changed.
My uncle called me on a Tuesday night, panicking.
He'd received a letter - thick paper, official seal, dense paragraphs of English legal text. He's been in the country for six years. His English is conversational, enough for grocery runs and small talk. But this letter? It was from his landlord's attorney. Words like "breach of covenant", "notice to quit", and "unlawful detainer proceedings" stared back at him.
He didn't know if he was being evicted. He didn't know if he had 3 days or 30. He was scared.
I translated it for him over the phone, sentence by sentence. It took 45 minutes. He had 14 days and a fixable issue.
That call is why I built LinguaAid.
The Problem Isn't Just Translation
Here's what I realized while building this: the problem isn't that people can't find a translator. Google Translate exists. The problem is trust and context.
When you paste a legal eviction notice into Google Translate, you get words back. But do you know which deadline matters? Do you know what "unlawful detainer" means even after it's translated? Do you know what you're supposed to do?
LinguaAid doesn't just translate. It:
- Translates the full document into 50+ languages
- Rewrites it in plain language ("You have 14 days to pay $800 or leave")
- Extracts the 3-5 things you actually need to act on
- Highlights urgent deadlines separately
The translation is the foundation. Everything else is built on top of it. And that foundation needed to be accurate.
Why I Chose Lingo.dev (And Why It Mattered)
I've used translation APIs before. Most of them are fine for "Hello, how are you?" They fall apart on "The Tenant shall cure the breach within the statutory period pursuant to CCP §1161."
I needed something built for precision, not just speed.
Lingo.dev markets itself as "AI localization for teams that ship fast" - but what caught my attention was their emphasis on context awareness. Legal and medical documents aren't just text. They're structured, formal, and full of domain-specific terminology where a wrong word changes meaning entirely.
The integration was genuinely simple. Here's the actual code from app/api/translate/route.ts:
// Try Lingo.dev first — it's our primary engine for accuracy
if (process.env.LINGODOTDEV_API_KEY) {
try {
const response = await fetch("https://api.lingo.dev/v1/translate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.LINGODOTDEV_API_KEY}`,
},
body: JSON.stringify({
text,
sourceLocale: sourceLanguage, // e.g. "en"
targetLocale: targetLanguage, // e.g. "hi", "es", "ar"
}),
});
if (response.ok) {
const data = await response.json();
return NextResponse.json({
translatedText: data.translatedText ?? data.text ?? text,
provider: "lingo", // We track which engine ran
});
}
} catch (e) {
console.warn("Lingo.dev failed, falling back to OpenAI...", e);
}
}
That's it. No SDK gymnastics, no complex setup. The API is clean, the response is predictable, and it handles 50+ languages out of the box.
The fallback to OpenAI is there for edge cases, but in testing, Lingo.dev handled everything we threw at it - including a hospital discharge summary in medical shorthand and a Section 8 housing voucher with HUD-specific terminology.
The Stack (And What Actually Took Time)
What was fast:
- Next.js 15 App Router setup - 20 minutes
- Lingo.dev integration - honestly, about 30 minutes including testing
- Basic UI - a few hours
What took forever:
- Getting the "Simple Explanation" prompt right. LLMs love to be verbose. Getting GPT-4o-mini to write like a patient friend explaining something to a worried person - that took a lot of iteration.
- PDF parsing.
pdf-parseis fine until someone uploads a scanned document. We ended up with a graceful fallback that tells users to paste text instead. - The word-by-word TTS highlighting. I wanted it to feel like karaoke - words light up as they're spoken. The Web Speech API's
onboundaryevent is... inconsistent across browsers. But we got it working.
The Feature I'm Most Proud Of
It's not the translation. It's the Urgent Actions panel.
After translating and simplifying, we run a second LLM pass specifically to extract time-sensitive actions. The output looks like:
⚠️ URGENT ACTIONS
• Pay $847 in back rent by March 3rd
• Contact your local legal aid office (free service)
• Do NOT ignore this notice — respond in writing
For my uncle's situation, this would have taken his 45-minute panic call and turned it into a 2-minute clarity moment.
What I'd Tell Anyone Building Something Similar
Use Lingo.dev for the translation layer. Seriously. I spent maybe 30 minutes on integration and never had to think about it again. That's the dream for any API — it just works, so you can focus on the parts that actually differentiate your product.
Don't underestimate the "explain it simply" problem. Translation is solved. Comprehension is not. The gap between "translated" and "understood" is where your product lives.
Build for the scared user, not the curious one. My uncle wasn't exploring an app. He was terrified. Every design decision - the calm colors, the step-by-step flow, the plain-language rewrite - was made thinking about someone who needs help right now, not someone who wants to play with features.
Try It
The app is live. Drop in any legal, medical, or housing document. Pick your language. See what comes back.
If you've ever helped someone translate something important over the phone, you know why this matters.
GitHub: https://github.com/ChiragGadhvi/LinguaAid
Live Demo: https://linguaaid.chiraggadhvi.in/
Built with Next.js 15, Lingo.dev, OpenAI, and a lot of coffee during a hackathon.


Top comments (0)