Skip to content

refactor(react-components): make it SSR friendly#241

Open
elboletaire wants to merge 4 commits intomainfrom
f/ssr-friendly
Open

refactor(react-components): make it SSR friendly#241
elboletaire wants to merge 4 commits intomainfrom
f/ssr-friendly

Conversation

@elboletaire
Copy link
Copy Markdown
Member

No description provided.

@elboletaire elboletaire requested a review from Copilot March 17, 2026 15:13
@elboletaire elboletaire force-pushed the f/ssr-friendly branch 2 times, most recently from 09459d6 to ca6cdf9 Compare March 17, 2026 15:19
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the react-components package to be SSR-friendly by removing direct browser API assumptions, supporting serialized SDK objects, and adding SSR-focused tests.

Changes:

  • Guard browser-only APIs (window/localStorage/workers) and centralize browser helpers.
  • Add “normalized” adapters so serialized election/organization data can be consumed safely.
  • Add SSR and serialized-data tests to validate server rendering and provider behavior.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
setup-tests.ts Guards window/URL mocks to avoid crashing in non-browser test environments.
packages/react-components/src/ssr.test.tsx Adds node-environment SSR tests for server rendering key components.
packages/react-components/src/providers/worker/webWorker.ts Makes web worker creation SSR-safe and uses globalThis instead of window.
packages/react-components/src/providers/worker/useWebWorker.ts Allows null worker instances to support SSR/unsupported environments.
packages/react-components/src/providers/organization/use-organization-provider.ts Accepts serialized org data and normalizes it for consistent usage.
packages/react-components/src/providers/organization/normalized.ts Introduces organization normalization utilities for serialized inputs.
packages/react-components/src/providers/organization/OrganizationProvider.test.tsx Adds coverage for serialized organization input.
packages/react-components/src/providers/election/use-election-reducer.ts Removes direct localStorage access and supports ElectionLike data.
packages/react-components/src/providers/election/use-election-provider.ts Normalizes election input, defers worker creation, and supports serialized elections.
packages/react-components/src/providers/election/normalized.ts Adds election normalization + field access helpers for serialized elections.
packages/react-components/src/providers/election/ElectionProvider.test.tsx Adds coverage for serialized election input.
packages/react-components/src/providers/client/use-client-provider.ts Uses a browser helper to avoid direct window.ethereum checks in SSR.
packages/react-components/src/providers/browser.ts Re-exports browser utilities under the providers namespace.
packages/react-components/src/components/Election/Title.tsx Uses normalized election helpers for SSR/serialized compatibility.
packages/react-components/src/components/Election/StatusBadge.tsx Uses normalized election helpers to avoid reliance on SDK classes.
packages/react-components/src/components/Election/SpreadsheetAccess.tsx Avoids direct window.location usage and uses browser helpers.
packages/react-components/src/components/Election/Schedule.tsx Uses normalized date/status accessors to support serialized elections.
packages/react-components/src/components/Election/ElectionTitle.test.tsx Updates title test to assert serialized-data rendering.
packages/react-components/src/components/Election/Election.tsx Uses normalized helpers for spreadsheet census detection.
packages/react-components/src/components/Election/Description.tsx Uses normalized description helper for SSR/serialized compatibility.
packages/react-components/src/browser.ts Adds SSR-safe wrappers for browser APIs and feature detection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread packages/react-components/src/browser.ts Outdated
Comment thread packages/react-components/src/providers/worker/webWorker.ts
Comment thread packages/react-components/src/providers/election/use-election-provider.ts Outdated
Comment thread packages/react-components/src/providers/election/use-election-provider.ts Outdated
Comment thread packages/react-components/src/ssr.test.tsx Outdated
Comment thread packages/react-components/src/ssr.test.tsx Outdated
@elboletaire elboletaire force-pushed the f/ssr-friendly branch 5 times, most recently from e0cc89c to 041a2ec Compare March 17, 2026 16:43
@elboletaire elboletaire requested a review from Copilot March 17, 2026 16:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors @vocdoni/react-components to be more SSR-friendly by removing direct window/localStorage access at module/render time, adding normalization helpers for serialized SDK entities, and introducing node-environment SSR coverage.

Changes:

  • Guard browser-only APIs (window, localStorage, hash, Web Workers) behind SSR-safe helpers/effects.
  • Accept and normalize serialized Election/Organization data so components/providers can run after JSON round-trips.
  • Add SSR + worker + browser helper tests; adjust tests to use path aliases and Vitest globals.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
setup-tests.ts Avoids referencing window in non-browser test environments; adjusts URL mocking.
packages/react-components/src/ssr.test.tsx Adds node-environment SSR smoke tests using renderToString.
packages/react-components/src/providers/worker/webWorker.ts Makes worker creation SSR-safe and revokes blob URL on termination.
packages/react-components/src/providers/worker/webWorker.test.ts Adds tests for null-return behavior and blob URL revocation.
packages/react-components/src/providers/worker/useWebWorker.ts Accepts `Worker
packages/react-components/src/providers/organization/use-organization-provider.ts Supports serialized organization input via normalization; normalizes query/mutation results.
packages/react-components/src/providers/organization/normalized.ts Adds organization normalization helper/types for serialized shapes.
packages/react-components/src/providers/organization/OrganizationProvider.test.tsx Adds coverage for serialized organization input.
packages/react-components/src/providers/election/use-election-reducer.ts Removes direct localStorage access; uses SSR-safe storage helpers and election normalization types.
packages/react-components/src/providers/election/use-election-provider.ts Normalizes election input/results; makes worker usage conditional; supports serialized elections.
packages/react-components/src/providers/election/normalized.ts Adds election normalization and safe field access helpers for serialized shapes.
packages/react-components/src/providers/election/ElectionProvider.test.tsx Adds coverage for serialized elections + worker creation fallback; updates mock import path.
packages/react-components/src/providers/client/use-client-provider.ts Replaces direct window.ethereum checks with SSR-safe helper.
packages/react-components/src/providers/browser.ts Re-exports browser helpers through the ~providers/* alias.
packages/react-components/src/confirm/ConfirmModal.test.tsx Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/context/helpers.test.ts Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/context/ComponentsProvider.test.tsx Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/Pagination/Pagination.test.tsx Updates mocks to use ~ aliases; removes redundant Vitest imports.
packages/react-components/src/components/Pagination/EllipsisButton.test.tsx Updates mocks to use ~ aliases; removes redundant Vitest imports.
packages/react-components/src/components/Pagination/Button.test.tsx Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/Organization/OrganizationName.test.tsx Updates provider mock import to ~providers; removes redundant Vitest imports.
packages/react-components/src/components/Election/VoteButton.test.tsx Updates provider mock import to ~providers; removes redundant Vitest imports.
packages/react-components/src/components/Election/Title.tsx Uses getElectionTitle to support serialized elections.
packages/react-components/src/components/Election/StatusBadge.tsx Uses normalized status helpers for serialized elections.
packages/react-components/src/components/Election/SpreadsheetAccess.tsx Removes direct hash access at render time; uses SSR-safe location helpers.
packages/react-components/src/components/Election/SpreadsheetAccess.test.tsx Updates mocks to ~ aliases; adds coverage for not reusing hash-derived key after logout.
packages/react-components/src/components/Election/Schedule.tsx Uses normalized date/status helpers to support serialized elections.
packages/react-components/src/components/Election/Results.test.tsx Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/Election/Questions.test.tsx Updates provider mock import to ~providers; removes redundant Vitest imports.
packages/react-components/src/components/Election/Questions.Validation.test.tsx Updates mocks to ~ aliases; removes redundant Vitest imports.
packages/react-components/src/components/Election/Questions.FormInteraction.test.tsx Updates mocks to ~ aliases; removes redundant Vitest imports.
packages/react-components/src/components/Election/Questions.Confirmation.test.tsx Updates i18n mock to ~i18n/localize; adjusts expectation string.
packages/react-components/src/components/Election/Questions.ChoiceProps.test.tsx Removes redundant Vitest imports (globals enabled).
packages/react-components/src/components/Election/ElectionTitle.test.tsx Updates provider mock import to ~providers; aligns test with serialized title behavior.
packages/react-components/src/components/Election/Election.tsx Uses normalized helpers for spreadsheet gating to support serialized elections.
packages/react-components/src/components/Election/Description.tsx Uses getElectionDescription to support serialized elections.
packages/react-components/src/components/Account/Balance.test.tsx Updates mocks to ~ aliases; reorders imports.
packages/react-components/src/browser.ts Introduces SSR-safe browser helpers (storage, hash, ethereum, workers).
packages/react-components/src/browser.test.ts Adds coverage for hash clearing and canUseWorkers behavior.
packages/react-components/package.json Bumps prerelease version; adds react-dom as devDependency for SSR tests.
packages/extended-sdk/package.json Removes the package test script.
package.json Adds vite devDependency at repo root.
Comments suppressed due to low confidence (2)

packages/react-components/src/providers/election/use-election-provider.ts:253

  • isAnonCircuitsFetching.current is set to true before calling fetchAnonCircuits(), but startProcessing() is a no-op until workerInstance exists. On the initial render workerInstance is still null (it is created in a separate effect), so this effect can mark fetching as in-progress and permanently block retries, leaving anonymous circuits never loaded.

Fix by gating this effect on workerInstance being non-null (and/or moving the isAnonCircuitsFetching.current = true assignment inside fetchAnonCircuits only after verifying a worker exists), so circuits fetching can run once the worker has been created.
packages/react-components/src/providers/election/use-election-reducer.ts:129

  • participation() / turnout() can return NaN/Infinity when current.census exists but census.size is missing/0 and maxCensusSize is also missing/0. The guard only checks that either census or maxCensusSize exists, not that the derived size is a finite positive number before dividing.

Compute size and return 0 unless Number.isFinite(size) and size > 0.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread packages/extended-sdk/package.json
Comment thread packages/react-components/src/components/Election/StatusBadge.tsx
@elboletaire elboletaire added the react-components Specific issues related to `@vocdoni/react-components` package. label Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

react-components Specific issues related to `@vocdoni/react-components` package.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants