Technology Apr 17, 2026 · 2 min read

Building a Multi-Language Pokémon Fansite with Next.js 16 (en/ja/ko/zh)

I recently launched Pokopia Habitats — a complete game guide for Pokémon Pokopia. Sharing the build because the multi-language static-site setup had a few non-obvious wins worth documenting. Stack Next.js 16 with App Router Static HTML Export (output: "export") — full SSG, no server...

DE
DEV Community
by Alex Chen
Building a Multi-Language Pokémon Fansite with Next.js 16 (en/ja/ko/zh)

I recently launched Pokopia Habitats — a complete game guide for Pokémon Pokopia. Sharing the build because the multi-language static-site setup had a few non-obvious wins worth documenting.

Stack

  • Next.js 16 with App Router
  • Static HTML Export (output: "export") — full SSG, no server
  • Cloudflare Pages — free tier, auto-build on GitHub push
  • Tailwind 4 + TypeScript
  • 4 locales: en (default), ja, ko, zh

Scale

  • 212 habitats
  • 303 Pokémon
  • 282 materials
  • 105 crafting + 20 cooking recipes
  • 33 guides
  • ~11.6K URLs in sitemap

Multi-language without i18n routing complexity

Most Next.js i18n tutorials push you toward next-i18next or middleware-based locale detection. For a static export, both are overkill. What worked:

  1. Locale dicts in src/dictionaries/{en,ja,ko,zh}.json
  2. Route each locale as a separate [locale] segment
  3. generateStaticParams emits all (habitat × locale) combos at build time
  4. HtmlLangUpdater client component sets on the fly

Every page gets statically rendered per locale, which Cloudflare CDNs love. Build time: ~4 min for ~11K pages.

Asset trick: external → own CDN

The Pokémon company assets (serebii.net area images, pokemon.com background images) were hot-linked initially. Ran into browser cache issues + the obvious "please don't hot-link" etiquette. Solution: a small Cloudflare R2 worker that fetches on first request, caches, and serves from our own CDN.

What's the site for?

Pokemon Pokopia has a ton of hidden data — habitat unlock conditions, material drop rates, cross-language item names — scattered across 7+ fan sites. Pokopia Habitats consolidates it and is the only site covering all four languages (en/ja/ko/zh) with cross-referenced item names.

If you're playing on the Japanese or Korean version, the Pokédex at pokopiahabitats.com/pokemon shows names in every language — useful when a Japanese wiki is your only reference.

What I'd do differently

  • Pre-build a subset of pages first, lazy-generate the long tail via ISR-at-build-time
  • Use next/image unoptimized mode earlier — SSG + remote images is a classic footgun
  • Dict keys should be typed (currently Record) — typed-i18n next time

Happy to answer questions about the build if anyone is doing similar fansite work.

DE
Source

This article was originally published by DEV Community and written by Alex Chen.

Read original article on DEV Community
Back to Discover

Reading List