Skip to content

Fix untranslated SSR labels and #418 hydration errors - #1416

Merged
daveearley merged 1 commit into
developfrom
fix/module-scope-translations
Oct 18, 2026
Merged

daveearley merged 1 commit into
developfrom
fix/module-scope-translations

Conversation

@daveearley

@daveearley daveearley commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Production auth pages throw React error #418 (hydration text mismatch) on every load. The cause is the feature ticker in AuthShell: its labels were built with t at module scope.

A module-level t runs once, when its chunk first loads. On the SSR server that value is then reused for every later request, so the ticker rendered as raw message ids (production descriptors carry only the id) or in whichever locale loaded the chunk first. Reproduced against a production build:

German request first then English request
before D0tAMe (raw id) D0tAMe (raw id)
after Wiederkehrende Veranstaltungen Recurring events

The client then rendered the real text, React found the mismatch, and the page threw #418. It only shows in production builds, because dev descriptors keep the English source text.

Fix

lingui/t-call-in-function, which is already in .eslintrc but not run in CI, flags 81 more module-scope t calls with the same problem:

  • Report date-range options (ReportTable, OrganizerReportTable)
  • Recurrence weekdays, months, frequencies and week positions (RecurrenceScheduleDrawer)
  • Attendee and order status filters
  • Organizer social link names

On the client these also never followed a language switch. They're all now built in getter functions, matching getEventCategories. The rule reports 0 afterwards.

Tests

New @smoke spec e2e/tests/ssr/server-translations.spec.ts:

Also checked against a local production build: login, register and forgot-password hydrate with no console errors. tsc adds no new errors; the two in the report tables already exist on develop.

Independent of #1415 (build speed); no shared files.

Labels built with `t` at module scope were evaluated once, when their
chunk first loaded. On the SSR server that froze them for every later
request: depending on timing they rendered as raw message ids (e.g.
"D0tAMe") or in whichever locale loaded them first, and the client then
re-rendered them, throwing React #418 hydration errors on the auth
pages. On the client they never followed a language switch.

Build them in getter functions instead, matching getEventCategories,
and add a smoke spec that requests the login page in two locales.
@railway-app

railway-app Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the Hi.Events-pr-1416 environment in Hi.Events

Service Status Web Updated
Hi.Events Frontend 😴 Sleeping (View Logs) Web Oct 18, 2026 at 12:47 pm UTC
Hi.Events API ✅ Success (View Logs) Web Oct 18, 2026 at 12:33 pm UTC
3 services not affected by this PR
  • Maildev
  • Hi.Events Scheduler
  • Hi.Events Queue Worker

@railway-app
railway-app Bot temporarily deployed to Hi.Events / Hi.Events-pr-1416 October 18, 2026 12:32 Destroyed
@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ E2E full suite (pull request): Everything passed, but 4 tests only passed on retry.

Mode Result ✅ Passed ❌ Failed ⚠️ Flaky ⏭️ Skipped ⏱️ Duration
Self-hosted ⚠️ Passed (some flaky) 595 0 2 4 16m 11s
SaaS ⚠️ Passed (some flaky) 583 0 2 16 10m 30s

⚠️ Flaky tests: failed first, then passed on retry (4)

  • SaaS · widget/widget-editor.spec.ts:104 · widget editor › organizers embed their events list from the organizer area
  • SaaS · widget/widget-playground.spec.ts:29 · widget playground › the playground embeds an organizer events list as a custom element
  • Self-hosted · management/event-lifecycle.spec.ts:91 · event lifecycle › an organizer deletes a draft event from the danger zone
  • Self-hosted · widget/widget-editor.spec.ts:104 · widget editor › organizers embed their events list from the organizer area
⏭️ Why tests were skipped

Self-hosted

  • 3 × Runs only against a SaaS stack (E2E_SAAS_MODE=true).
  • 1 × Lifecycle emails only exist in SaaS mode.

SaaS

  • 15 × Runs only against a non-SaaS stack (E2E_SAAS_MODE=false).
  • 1 × The composer form is gated behind Stripe/manual account verification in SaaS mode.

Open the run

@daveearley
daveearley merged commit 439a48b into develop Oct 18, 2026
12 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 18, 2026

This branch was successfully deployed

No deployments
Hi.Events / Hi.Events-pr-1416 — 405a1ca2 Deployed Oct 18, 2026 by railway-app[bot]
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant