Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#620 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
38/100
Tipo de issue
Nueva funcionalidad
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
eslint, next.js, node.js, playwright, typescript

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.

Lenguaje dominante
TypeScript
Estrellas
19
Forks
4
Merge medio
19 h 34 min
PR fusionados (30 d)
165

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de richshaw/OpenSignup

Todos los issues de richshaw/OpenSignup

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.