EasyToolbox is a multilingual Next.js tools platform of calculators, checkers and browser games that I built and run alone. It serves people in seven European markets, giving every tool its own localized, indexable page in English, German, Spanish, French, Italian, Dutch and Polish, with each language applying its own country's rules. It runs on Next.js 16, React 19 and next-intl, entirely in the browser.
The problem
A lot of calculator sites are written for one country and translated for the rest. The labels change language but the maths does not, so a German visitor can read German words wrapped around a British tax calculation, and the result still looks credible. Net pay in Germany depends on Lohnsteuer, in Spain on IRPF, in the UK on PAYE. Each language has to follow its own country's rules.
The second problem was reach and privacy. People search for a salary or loan tool in their own language, so each translation has to be a real page search engines can index for that market, not a switch that swaps text on one URL. And the inputs are personal: income, loan amounts, household numbers. I did not want any of that reaching a server I run.
My role
I built EasyToolbox on my own and still run it. Over 428 commits that has meant choosing which tools to build for which market, reading official guidance to get each country's figures right, and writing the calculation logic, its tests, the localization and SEO setup, the interface and the Vercel deployment.
Architecture and tech stack
A tool registry behind a single route
Every tool is an entry in a registry holding its config, calculation logic and content. One route reads that registry and renders whichever tool the URL asks for, so a new tool needs those three things and no new page tree. For one person maintaining a growing catalogue in seven languages, that was the structure most likely to stay consistent.
next-intl with a static page per language
Each language version of a tool has its own URL and is generated ahead of time, so the HTML already holds the localized content when a visitor or a crawler arrives. hreflang tags tie the seven versions of each tool together and canonicals stop them competing with each other. Multiplied across the catalogue, that is how the site reaches 340+ indexable localized pages. The server-first approach is the same one I used for the subject and topic pages of NSCT Prep, my exam practice platform.
Official worked examples as Vitest cases
Tax authorities publish worked examples, the closest thing to an answer key a calculator can get. I turned the ones from HMRC, the German finance ministry (BMF), Poland's ZUS and others into automated tests, so a change that breaks a published example fails before it ships. The suite stands at about 4,700 tests.
Calculation on the visitor's device
There is no calculation API. Every result is computed in the browser, and the site tells visitors so: what you enter is never sent. Shareable results follow the same rule. The inputs live in the URL, so a link rebuilds the calculation for whoever opens it without anything being stored anywhere.
Key features
- Tools across eight areas: finance, tax and salary, automotive, home, cooking, family, business and word games.
- Country-specific logic for 7 markets, including UK PAYE, German Lohnsteuer and Spanish IRPF, with figures taken from official sources.
- Sources on the page: tools show where their figures come from and when they were last checked.
- Shareable results through URL state, with nothing saved on a server.
- Full international SEO: hreflang, canonicals, a generated sitemap, JSON-LD and answer blocks written to be quoted by AI search.
- Dark and light themes, with layouts that hold down to a 320px screen.
Challenges and how I solved them
Getting seven countries' tax rules right
- Problem
- A wrong number in a salary tool is not a cosmetic bug. Seven markets means seven sets of rates, thresholds and deductions, all revised over time, and reading the rules once was not enough.
- Solution
- Published worked examples became tests the calculation code has to pass, and each tool names its sources and the date its figures were last checked, so a visitor can verify a result rather than trust it.
Shipping only the tool on the page
- Problem
- Rendering every tool from one route keeps the code tidy, but it also makes it easy for a page to carry JavaScript for tools it is not showing. Before I split it, page JavaScript stood at 263 KB gzipped.
- Solution
- I split the code per tool, so each page loads only the calculator it displays. That brought page JavaScript down to about 160 KB gzipped.
Seven languages in a 320px layout
- Problem
- A form designed around English labels breaks when the same label is translated into a longer German or Polish phrase, and it breaks first on the narrowest phones.
- Solution
- I designed the layouts against every locale rather than English alone, and held them down to 320px wide, so the longest translation sets the limit. The groundwork for metadata and structured data is close to what I set up on the PulseRep gym management dashboard, here repeated across seven locales.
Results
The multilingual Next.js tools platform is live at easytoolbox.org. A visitor in Madrid gets the Spanish page with Spanish rules, a visitor in Warsaw gets the Polish one, and both can see where the figures came from. Nothing they type leaves the browser.
- 7 languages
- each with its own country rules
- 340+
- indexable localized pages
- ~4,700
- automated tests
- 263 to ~160 KB
- page JavaScript (gzipped) after per-tool splitting
What's next
The site already lists conversion, health and fitness, and maths tools as in preparation, and those are the next categories to fill, through the same registry and, where a country rule applies, the same check against official examples.
