Skip to main content

Command Palette

Search for a command to run...

How I Built 80+ Psychological Tests in Next.js Architecture, i18n, and Lessons Learned

Updated
4 min read
How I Built 80+ Psychological Tests in Next.js  Architecture, i18n, and Lessons Learned
A
Full-stack developer. Building PrismaTest — a free multilingual platform with 80+ psychology tests in 20 languages. Passionate about psychometrics, i18n, and building tools that help people understand themselves.

Building a psychology testing platform sounds straightforward — until you try to support 20 languages, 7 different scoring systems, and 80+ assessments with zero page reloads. Here's how I did it with PrismaTest.

The Challenge

I wanted to create a platform where anyone in the world could take scientifically validated personality tests — in their native language, for free, with beautiful visual results. No registration, no paywalls, no clunky multi-page forms.

The requirements were ambitious:

  • 80+ tests covering personality (Big Five, MBTI, Enneagram), career (Holland RIASEC, DISC), IQ (Raven's matrices, spatial reasoning), relationships (attachment styles, love languages), and mental health (depression, anxiety, burnout)

  • 20 languages: English, Spanish, German, French, Portuguese, Russian, Japanese, Korean, Arabic, and 11 more

  • Instant results with charts, radar diagrams, and detailed interpretations

  • Single-page app feel — no reloads between questions

Architecture: One Test = One JSON File

The core insight that made everything manageable: each test is a single JSON file containing everything — all 20 translations, questions, answer options, scoring logic, and result descriptions.

{
  "slug": "mbti",
  "scoring": { "type": "dichotomy", ... },
  "display": { "type": "type", ... },
  "translations": {
    "en": { "title": "MBTI Personality Test", ... },
    "es": { "title": "Test de Personalidad MBTI", ... },
    "ja": { "title": "MBTI性格診断テスト", ... }
  },
  "questions": [ ... ]
}

Adding a new test = creating one file. No database migrations, no code changes, no deployment needed. The app automatically discovers and registers new tests from the content/tests/ directory.

7 Universal Scoring Types

Instead of writing custom scoring logic for each test, I built 7 universal scoring engines:

Type Used By How It Works
likert-scales Big Five, 16PF Sum answers per scale
likert-levels BDI, anxiety tests Total score → severity level
dichotomy MBTI, socionics Binary dimensions (E/I, T/F)
forced-choice Belbin, Love Languages Distribute points among options
color-sequence Lüscher test Analyze color ordering
formula EQ, IQ tests Custom formulas per scale
custom Special cases Fully custom scoring function

Every test JSON declares its scoring type, and the engine handles the rest. This means I can add a new Big Five variant in 10 minutes — just create the JSON with "scoring": { "type": "likert-scales" }.

i18n at Scale: 20 Languages Without Going Insane

The localization layer was the hardest part. Some lessons:

  1. RTL support for Arabic required special layout logic — not just CSS direction: rtl, but also mirroring charts and progress bars

  2. CJK languages (Japanese, Korean) need specialized fonts (Noto Sans JP/KR) loaded conditionally to avoid bloating the initial bundle

  3. Pluralization varies wildly between languages — Russian has 3 plural forms, Arabic has 6. I use ICU MessageFormat via next-intl

  4. Question length differs dramatically — a 5-word English question might be 15 words in German. The UI had to be flexible enough to handle this without breaking

All UI strings live in separate message files per locale. Test content lives in the JSON files. The two systems are independent, which keeps things clean.

The Result

PrismaTest now serves thousands of daily users. The most popular tests:

Tech Stack

  • Next.js 14 (App Router, server + client components)

  • TypeScript end-to-end

  • Tailwind CSS for responsive design

  • PostgreSQL for user data and statistics

  • Redis for caching test metadata

  • Docker + Traefik for production deployment

  • next-intl for internationalization

Key Takeaways

  1. Data-driven architecture wins. Keeping tests as JSON files instead of database records made everything simpler — version control, deployment, and adding new tests.

  2. Build universal engines, not custom code. 7 scoring types cover 80+ tests. The abstraction pays for itself after the 3rd test.

  3. i18n is a multiplier. Supporting 20 languages 10x'd the addressable audience with relatively little extra work per test.

  4. Speed matters for engagement. SPA-style navigation with no page reloads means users complete more tests per session.

If you're building something similar, I'm happy to chat about the architecture. And if you're curious about your personality, try any test on PrismaTest — it's all free. 🧠