Building a Multilingual News Aggregator: What We Learned
Serving news in three scripts — Latin, Sinhala, and Tamil — sounds straightforward until you actually try it. Here's what we built and what surprised us along the way.
LakFeed Engineering
May 18, 2025 · 3 min read
When we started building LakFeed, we thought the hard part would be aggregating news from dozens of different outlets. It turns out that part is almost easy. The hard part is presenting three languages well — simultaneously, on the same interface, for users who might switch between them mid-session.
Here's a look at some of the problems we ran into, and how we solved them.
Typography Is Not One-Size-Fits-All
The first thing that breaks when you try to display Sinhala and Tamil alongside English is the typography.
Sinhala (සිංහල) and Tamil (தமிழ்) are complex scripts with tall characters, conjunct consonants, and a default line-height that looks cramped at English font settings. We spent a surprising amount of time getting the baseline grid right — Noto Sans Sinhala and Noto Sans Tamil both have a taller x-height than Plus Jakarta Sans, which is what we use for English.
Our solution: CSS lang attribute selectors. We detect which language the user is viewing and swap in the correct font stack and line-height values automatically. When you switch to Sinhala, the entire interface reflowed to accommodate the different character geometry. No JavaScript required.
:lang(si) {
font-family: 'Noto Sans Sinhala', system-ui, sans-serif;
line-height: 1.9;
font-size: 14px;
}
Article Length and Layout
News articles in Sinhala tend to be shorter than their English counterparts covering the same event. Tamil articles, particularly from the north, often include more context and historical reference. English articles sometimes lead with a headline that's optimised for search rather than information.
This meant we couldn't design a fixed-height card and assume it would work across all three languages. Our cards are entirely height-flexible — the text drives the layout, not the other way around.
Date Formats and Relative Times
"2 hours ago" translates trivially into English. In Sinhala, the grammar changes depending on whether the time reference is past or future, and there are specific constructions for durations less than an hour. Tamil has similar nuances.
Rather than attempt to translate relative time strings perfectly in every language, we made a deliberate product decision: all timestamps display in the locale's numeral system with a universal relative format. This is slightly less native-feeling but dramatically more reliable.
Search Across Scripts
Searching for "cricket" should return results that include the Sinhala word for cricket and the Tamil word, even if the user types in English. Full-text search across three scripts is not a solved problem out of the box.
We're currently using PostgreSQL's full-text search capabilities with language-specific configurations. It's not perfect — transliteration across scripts is still a manual tagging exercise — but it works well enough that users can find what they're looking for most of the time.
Search across multilingual content is an area we're actively improving.
What We'd Do Differently
If we were starting over, we'd define the typography system before writing a single line of component code. Getting the font loading, line-height, and font-size right for all three scripts from day one would have saved us weeks of refactoring.
We'd also separate the language detection from the locale routing earlier. Right now, the language you read in is tied to the URL path (/en/news, /si/news). That's correct for SEO but creates some interesting state-management questions when a user bookmarks a page and then switches languages.
Building a multilingual product for Sri Lanka has been genuinely challenging — and genuinely rewarding. There's not a lot of prior art for exactly this combination of languages and scripts. We're figuring it out as we go, and we're documenting what we learn here.
If you're building something similar, or if you have feedback on how we're handling any of the above, reach out at contact.