Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở
#620 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
38/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
eslint, next.js, node.js, playwright, typescript

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
TypeScript
Star
19
Fork
4
Merge trung bình
22 giờ 10 phút
Pull request đã merge (30 ngày)
168

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của richshaw/OpenSignup

Tất cả issue của richshaw/OpenSignup

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.