TL;DR
I translated my personal site to English and ran into a problem: a literal navigation “Я → Делаю → Проекты → Как → Надо” doesn’t work. I had to rethink the structure entirely: Me → Craft → Work → Way → Right. This post is about the process, decisions, and cultural differences in UX.
Why Translate at All
The Russian site works well locally. But:
- International work — be available to English‑speaking clients and partners.
- Portfolio — much of the industry speaks English.
- Experience — try real‑world localization on my own product.
I added an English version, kept Russian as default. Next.js 15 + middleware for /en/... prefix routing.
First Problem: Navigation Doesn’t Translate
My Russian navigation:
Я → Делаю → Проекты → Как → Надо
It’s a wordplay: you can read it as a sentence — “I do projects the right way” — or as five sections. In English?
Attempt #1: Literal Translation
I → Do → Projects → How → Need
Reads like machine translation. “I Do Projects How Need” — nonsense.
Attempt #2: Meaningful but Generic
About → Work → Projects → Process → Contact
Works, but loses the identity. Becomes a template.
Solution: Rethink the Structure
What do I actually want to say?
- Я — who I am, my skills
- Делаю — what I create, how I build
- Проекты — case studies, portfolio
- Как — processes, methods
- Надо — contact, start working
English should deliver the same user journey, with natural words.
Final Version
Me → Craft → Work → Way → Right
Why it works:
- Me — about me (skills, experience, expertise)
- Craft — what I build, approach to the craft
- Work — portfolio and case studies
- Way — how I work: process and methodology
- Right — get in touch, start working (do it right)
You can read it as a sentence: “Me Craft Work Way Right.” Slightly poetic, but meaningful — and uniquely mine.
Cultural and Language Pitfalls I Hit
- Directness vs. implicature. Russian tolerates clever implicit slogans; English often prefers explicit clarity.
- Wordplay. Russian pun survives translation rarely. Better to keep rhythm and function than literal words.
- Section expectations. “About/Work/Contact” are defaults. Breaking expectations is fine if clarity survives.
- Tone. Humor/sarcasm translate poorly; keep the smile, trim the edge.
My Practical Rules for i18n in Product Copy
- Translate the intent, not words.
- Keep path consistency between languages; let names differ.
- Validate with native speakers; a 10‑minute review saves weeks.
- Test copy in UI — real pixels catch ambiguities.
- Technical i18n in Next.js 15 is straightforward — middleware + dictionaries + SSG does most.
Outcomes
Localization turned out more interesting than expected. I started with a technical task and finished with new navigation and structure.
If you’re translating your site — don’t be afraid to change the concept. What matters is a clear user path and why it matters now.
See it live: English version at potapov.me/en
Technical Details
For those who want to ship something similar:
Stack
- Next.js 15 (App Router)
- TypeScript
- Middleware for routing
- SSG for all pages
Key Files
middleware.ts # Language detection
src/shared/config/i18n.ts # Locale config
src/shared/config/locales/ # Translation dictionaries
src/shared/lib/i18n/ # i18n utilities
Handy Functions
Localization of paths:
export function localizePath(path: string, locale: Locale): string {
if (locale === defaultLocale) return path;
return `/${locale}${path}`;
}Dictionary loader:
export async function getDictionary(locale: Locale) {
return (await import(`@/shared/config/locales/${locale}`)).default;
}If you have questions or want to discuss localization approaches — ping me on Telegram or email.