Back to Portfolio

2025 · Founder, Full-stack Engineer

IsraelVotes

In 2025, I launched IsraelVotes.ca, a Next.js application designed to help Canadian expats in Israel quickly register to vote in the federal election, utilizing a multi-step registration process and ensuring internationalization and a reliable backend submission pipeline, successfully mobilizing over 1,000 voters by election day.

Next.jsReactTypescript

IsraelVotes.ca — Voter registration drive for Canadian expats living in Israel (2025 federal election).

Overview

In late March 2025, the Canadian Prime Minister dissolved parliament and triggered a snap federal election. With extremely limited time, I launched IsraelVotes.ca to help Canadian expats in Israel complete voter registration quickly and correctly.

What I built (React + Next.js)

App structure (Next.js)

  • Implemented the site as a Next.js application with:

    • Route-based organization ( / , /register , /success , etc.)
    • Shared layout + metadata (SEO/Open Graph)
    • Componentized UI (form steps, validation, review step)
  • Used server-side rendering/static generation where appropriate (marketing pages) while keeping registration as a highly interactive client flow.

Multi-step registration UX (React)

  • Built a multi-step form as a state machine style flow (step-by-step progression, conditional branches, and a final review step).

  • Managed complex form state using established React patterns:

    • Single source of truth for form data
    • Step-level validation with a shared schema
    • Persistent progress (so refresh/back doesn’t wipe the session)
  • Implemented the “review & confirm” step by rendering the normalized form state back to the user before submission.

Internationalization (i18n)

  • Served English/French/Hebrew using a locale-aware routing pattern (e.g. /(en|fr|he)/... ) and a translation dictionary.
  • Ensured that dates, labels, and the hero CTA copy were locale-correct.

Input quality & friction reduction

  • Phone number input optimized for Canada (+1) and Israel (+972) using an intl phone input component, with client-side formatting + validation.
  • Date-of-birth entry with a date picker and an eligibility constraint (18+ on election day).
  • Address entry improvements via Google Places autocomplete, with explicit event dispatching to ensure downstream validation re-runs after selection.

Backend registration pipeline

The critical part of the project wasn’t just the UI — it was reliably turning partially-complete user sessions into a submission artifact and follow-up workflow.

API routes & submission contract

  • Implemented a POST /api/register endpoint (Next.js API Route) as the main ingestion point.
  • Validated payloads server-side (schema validation + strict normalization) to prevent bad data from entering downstream systems.

File uploads & storage

  • Supported document uploads (where required) using a pre-signed upload pattern:
    • POST /api/uploads/presign to mint short-lived upload URLs
    • Direct-to-object-storage upload from the browser
    • Submission payload stores only file keys/metadata

Idempotency, tracing, and follow-up

  • Generated a uuid per registration to:

    • De-duplicate retries
    • Correlate logs/events
    • Enable follow-up communication
  • Recorded language/locale as part of the submission record to keep outreach consistent with the registrant’s preference.

Operational workflow

  • Persisted submissions in a database (or durable store) with an explicit status lifecycle (received → validated → queued → processed).
  • Sent notifications / exports for organizers to follow up on edge cases (address verification, missing documents, etc.).

Outcomes