Skip to content

Migrate frontend to Nuxt 4 and Vue 3 - #381

Merged
fellnerse merged 24 commits into
devfrom
modernization/nuxt4-migration
Sep 4, 2026
Merged

Migrate frontend to Nuxt 4 and Vue 3#381
fellnerse merged 24 commits into
devfrom
modernization/nuxt4-migration

Conversation

@fellnerse

@fellnerse fellnerse commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

  • migrate the frontend from Nuxt 2 / Vue 2 / Vuetify 2 to Nuxt 4 / Vue 3 / Vuetify 3
  • replace Nuxt 2-only integrations for Content, i18n, PWA, Sentry, Firebase, analytics, Chart.js, and web workers
  • preserve the static localized site output and modernize the generated-site verification
  • extend Playwright smoke coverage for browser errors, migrated Markdown content, SEO, and chat privacy

Notable migration details

  • keeps the existing project layout through srcDir: "." to avoid mixing a framework migration with a directory restructure
  • explicitly prerenders all localized routes and emits the static site to dist
  • replaces the Firebase Nuxt module with a modular Firebase client plugin while preserving the existing $firebase caller interface
  • uses Nuxt Scripts for analytics and Vite-native workers
  • updates Nix and package metadata to the Node 22 runtime established by the preceding modernization PR

Validation

  • nix develop --command pnpm install --frozen-lockfile
  • NUXT_TELEMETRY_DISABLED=1 nix develop --command pnpm run build (58 prerendered routes)
  • nix develop --command pnpm run test
  • nix develop --command pnpm run format:check
  • nix develop --command pnpm run lint
  • nix develop --command pnpm run test:generated
  • pnpm test:e2e (10 passed, Chromium desktop/mobile; local regression suite)/
  • git diff --check

Review note

This is intentionally a draft because it is the framework boundary of the modernization sequence and touches most frontend integrations. The migration baseline is kept in a separate commit so the functional migration diff remains reviewable.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 9e06cf5):

https://whatsanalyze-80665--pr381-modernization-nuxt4-cyg61rvl.web.app

(expires Fri, 11 Sep 2026 18:10:07 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 5796a863d3a1b99df3fcb31feec7a39514d97aa4

@fellnerse
fellnerse marked this pull request as ready for review September 2, 2026 11:31
Sebastian Fellner 💯 added 15 commits September 2, 2026 15:11
- helloworld now also returns the created subscriptionId (additive)
- opt-in Playwright suite (pnpm test:e2e:sandbox) boots the Functions
  emulator + dev server and exercises the real PayPal sandbox; buyer
  approval stays manual by design
- optional GitHub workflow runs it only when PAYPAL_PASSWORD_DEV secret
  is configured; emulator reads it from gitignored functions/.secret.local
- pin TMPDIR=/tmp for the emulator: macOS truncates unix-socket paths at
  ~104 chars, colliding worker sockets and routing requests to the wrong
  function
- raise CI test timeout to 120s and assertion timeout to 15s (nuxt dev
  cold-compiles pages; small runners exceeded Playwright's defaults)
The old sandbox plan had total_cycles=1 (PayPal's default when omitted),
so every subscription became EXPIRED one second after the first payment.
Point the dev config at the new plan P-0KW41015GP654580PNKMT6EY and set
total_cycles: 0 explicitly in createPlan.

Also documented: the sandbox webhook registration was missing
PAYMENT.SALE.COMPLETED (prod subscribes to *); it is now aligned to *.
- pin explicit pwa.workbox.globPatterns: @vite-pwa/nuxt replaces the
  workbox default when payload extraction is active, which left / out of
  the precache manifest and crashed every navigation with
  non-precached-url from createHandlerBoundToURL
- restructure the download dialog: a single activator button binds the
  activator props, pricing cards render outside the overlay. multi-root
  activator slots dropped the props, so the buttons' own @click handlers
  never fired
- markRaw the pdf worker instance so Vue reactivity cannot wrap it
- objectToDictionary converts Date instances to ISO strings; proxied
  dates cannot be structured-cloned and stalled the worker silently
- guard attachment image decoding:InvalidStateError on some WhatsApp
  jpegs now degrades to text rendering instead of killing the pdf run
- guard empty FileReader results and parse errors in zipLoadEndHandler;
  previously they surfaced as an unhandled jszip rejection ("Can't read
  the data of 'the loaded zip file'") with no UI feedback
- document the findings in docs/modernization-runbook.md
@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@mowolf

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse

This comment has been minimized.

@fellnerse
fellnerse merged commit 5ceb14c into dev Sep 4, 2026
6 checks passed
@fellnerse
fellnerse deleted the modernization/nuxt4-migration branch September 4, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants