Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

OpenSignup has no message catalogs or translator, so none of its text can be translated

オープン
#620 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
38/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
eslint, next.js, node.js, playwright, typescript

調査の方向性

Start with next.config.mjs, eslint.config.mjs, budgets.json, and the worker test at src/email/templates/worker-render.test.ts; inspect the existing package, test, and lint setup before adding the translator plumbing. The issue lists the required catalog and i18n entry points, plus checks to run: lint, typecheck, knip, tests, build, and budgets. Done means translation works in server, test, and worker contexts, client imports are rejected by lint, and first-load JavaScript budgets pass.

索引モデルが issue の本文から書いたものです。

説明

enhancement pipeline:proposed

Needs your OK: this adds next-intl and the translation plumbing the rest of #619 builds on. Nothing anyone sees changes. Swap pipeline:proposed for pipeline:ready to have it built.

What happens

Every string a person sees is typed inline, in English, in components, emails and helpers. There's no catalog to translate and no function to look a message up. Text is rendered in three places with different limits:

  • Server components, the bulk of the app.
  • 'use client' bundles, whose size budgets.json caps.
  • The pg-boss worker (pnpm worker, plain Node under tsx, no Next runtime), which renders the reminder and time-changed emails.

Fix, in outline

  • Packages. Add next-intl and use-intl at the same exact version. pnpm's isolated node_modules won't resolve use-intl/core as a transitive dependency, and knip flags unlisted imports. Wrap next.config.mjs with createNextIntlPlugin, keeping output: 'standalone', serverExternalPackages and headers() as they are.
  • Catalog. src/messages/en.json, under src/ because the runner image copies only src/ and the worker runs from it (a root messages/ folder would crash the first reminder job in production). Top-level namespaces by audience: participant, email, organizer, auth, site, common. Types come from next-intl's AppConfig augmentation over en.json, so a missing key or a wrong argument fails typecheck.
  • src/i18n/config.ts, pure (no next/*, no env.ts): CATALOG_LOCALES (just en for now) and SHIPPED = { participant: ['en'], organizer: ['en'], site: ['en'] }, the languages complete and reviewed for each audience.
  • src/i18n/translator.ts: getTranslator(locale, namespace, { onError }), synchronous, built on use-intl/core's createTranslator over the catalogs imported as modules. English is merged under the requested language per namespace, so a gap shows English, not a key path like participant.signUp. No logging import, because Playwright specs import app copy modules. It returns the same function type useTranslations does, so a helper written against it also works in a client component.
  • src/i18n/server.ts: passes an onError that logs one pino line per missing key. The worker will import it, so nothing from next/* goes in it.
  • src/i18n/request.ts: the request config the plugin requires. For now it returns en and timeZone: 'UTC'.
  • A lint rule keyed on the 'use client' directive, in a small local ESLint plugin in eslint.config.mjs: a client file may not import the translator, server.ts or a catalog, since each carries every language. Client files live outside any fixed directory list, so read the file's leading directive rather than matching paths.
  • Tests: an English test translator whose onError throws, so a missing key fails a test.
  • knip: entries for the request config and the catalogs, with a comment saying why.

Watch for

  • Don't use next-intl's server hooks (getTranslations, or useTranslations in server components). 18 jsdom test files render server components synchronously with render(), and async components would break them. Server code takes a translator from getTranslator.
  • server-only can't guard the translator: it throws under tsx and vitest. The lint rule and pnpm budgets (a client chunk with every catalog in it blows the 108 KB * budget) are the guards.
  • Move no copy yet beyond what the tests need. Extraction comes in later steps of #619.
  • Pieces with no caller yet wait for the step that first uses them (resolveLocale, defaultFor, language names, the client provider wrapper), or knip fails.

Choices this makes

  • next-intl, over Lingui, Paraglide, react-intl and i18next. Default: next-intl. Measured client runtimes (esbuild, minified, gzip, React excluded): use-intl 11.6 KB, or 2.8 KB with its precompile option (a later step); Lingui 3.4 KB, but its macros need an SWC plugin tied to Next's exact swc_core and can't run under tsx; Paraglide 2 is built for Vite and fetches plugins from a CDN at build time; react-intl 14.9 KB; i18next 17.2 KB.
  • ICU MessageFormat in JSON. Default: yes. Translation tools such as Weblate read it.
  • One synchronous translator for server code, emails, the worker and tests, with next-intl's React provider only around client components that need text. Default: yes.

Done when

  • getTranslator('en', …) works in a server component, in a unit test, and under the worker toolchain (the src/email/templates/worker-render.test.ts pattern).
  • A client file that imports the translator fails lint.
  • No page's first-load JS changes (pnpm build && pnpm budgets).
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test pass.

Planned with the owner in https://claude.ai/code/session_01EFKmj716ZY3b3SwR8TV8Y2 and checked against the code on main at 35288fa. The full plan is private to the owner's account: https://claude.ai/artifact/VgQH6U2s2EVx3LX991fJi8 (a Claude session on that account can open it with the Artifact tool's read action). This is step 0.1 there.

主要言語
TypeScript
スター
19
フォーク
4
平均マージ
21時間 3分
マージ済み PR(30日)
176

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

richshaw/OpenSignup のほかの issue

richshaw/OpenSignup の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。