The Russian site was fine for the local market. English came from a simple greed: international work, a portfolio in the language of the industry, and a wish to run localization on my own product, not on a training stand.
I kept Russian as the default. Next.js 15, an /en prefix, middleware looks at the path and, if there is no locale, sends you to /ru.
The thing that stood up next was not the routing. It was the header.
Five words
Russian navigation:
Я → Делаю → Проекты → Как → Надо
You can read it as a sentence and as five doors. In Russian it holds.
A literal translation sat down at once:
I → Do → Projects → How → Need
I Do Projects How Need. As if the phrase had been dragged through a dictionary and left on the porch.
A sense translation sat down too, only now like a thousand other sites:
About → Work → Projects → Process → Contact
It works. There is no stone in it. A person lands in a template and forgets whose house it was.
What the five words do
Я: who I am and what I can do.
Делаю: what I build and how I stand toward it.
Проекты: the actual cases.
Как: the way the work runs.
Надо: start, write, meet.
The English words have to walk the same corridor. They do not have to copy the letters.
I stopped here:
Me → Craft → Work → Way → Right
Me is about me. Craft is the trade, not "I do." Work is the portfolio. Way is the run of the work. Right is "we do it properly," without the poke of "I need a job."
Read in a row, Me Craft Work Way Right stands a little crooked. It sticks. The five doors stay in place.
«Надо» in Russian is ordinary bluntness. The same bluntness in English sounds like a notice on a stairwell. Right takes the poke off and leaves the sense.
I showed the options to friends whose English is native. Ten minutes of their grumbling closed a week of my love for the literal.
Dictionaries, not one string
In the code this is not "translate nav." It is two dictionaries with different names on the same keys.
// ru
nav: { me: "Я", make: "Делаю", projects: "Проекты", how: "Как", need: "Надо" }
// en
nav: { me: "Me", make: "Craft", projects: "Work", how: "Way", need: "Right" }The paths stay the same: /me, /make, /projects, /how, /need. The plates change, not the corridor. A component takes dict.nav.make and does not know which language the header is joking in.
Localization here is not a layer of words on a finished site. Until the five items sat down in English, it was a different navigation, only with a prefix.
The English version lives at potapov.me/en.