Skip to content

fix: my apps link 404 in production - #2529

Open
finnar-bin wants to merge 1 commit into
stagefrom
fix/2524-missing-my-apps-link
Open

fix: my apps link 404 in production#2529
finnar-bin wants to merge 1 commit into
stagefrom
fix/2524-missing-my-apps-link

Conversation

@finnar-bin

@finnar-bin finnar-bin commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Resolves #2524

Summary

  • Replaced the fragile req.url exact-match (used to detect the virtual /marketplace/register/ and /marketplace/installed/ pages) with a check on the catch-all route's own query.slug, since req.url could be altered by the production reverse proxy/CDN in a way local dev never hit — this was the root cause of the 404 in production.
  • Rendered RegisterPage/InstalledPage client-only (next/dynamic, ssr: false) since both read getCookie('ZESTY_WORKING_INSTANCE') directly during render, which caused SSR/CSR hydration mismatches once the page stopped 404ing.
  • Switched the installed/register pages to read the working instance from the Zustand store (useZestyStore((state) => state.workingInstance)) instead of the cookie directly, so they update reactively when the instance switcher changes it, without requiring a manual page refresh.
  • Fixed a regression surfaced by the above in src/store/index.js: getInstanceZUID()'s fallback treated any URL's third path segment as an instance ZUID, which produced a bogus truthy value ("installed") on /marketplace/installed/ when no instance was actually selected. Scoped the fallback to /instances/{zuid}/... routes only.

Test plan

  • In production (or a build with a proxy in front), click Accounts UI > Marketplace > My Apps and confirm it loads instead of 404ing.
  • Load /marketplace/installed/ and /marketplace/register/ directly and confirm no hydration mismatch warnings in the console.
  • With an instance already selected, switch instances via the instance switcher while on /marketplace/installed/ and confirm the installed apps list updates without a manual refresh.
  • With no instance selected, load /marketplace/installed/ and confirm it shows "Please Select an Instance to Continue" rather than "No Data".

Screenshots

Recording.2026-07-28.134121.mp4

Replace the fragile req.url exact-match with the catch-all route's
query.slug to detect the /marketplace/register/ and /marketplace/installed/
virtual pages, since req.url could be altered by the production
reverse proxy/CDN in a way local dev never hit. Render these two pages
client-only (next/dynamic, ssr: false) since they read
getCookie('ZESTY_WORKING_INSTANCE') directly in render, which caused
SSR/CSR hydration mismatches once the page stopped 404ing.

Also switch installed/register pages to read the working instance from
the Zustand store instead of the cookie directly, so they update
reactively when the instance switcher changes it without a full page
reload (previously required a manual refresh).

Fix a regression this surfaced in store/index.js: getInstanceZUID()'s
fallback treated any URL's third path segment as an instance ZUID,
which produced a bogus truthy value ("installed") on
/marketplace/installed/ when no instance was actually selected. Scope
it to /instances/{zuid}/... routes only.

Fixes #2524

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@finnar-bin finnar-bin self-assigned this Jul 28, 2026
@finnar-bin finnar-bin changed the title Marketplace: Fix My Apps link 404 in production fix: my apps link 404 in production Jul 28, 2026
Comment thread src/store/index.js
Comment thread src/pages/marketplace/[...slug].js
@github-actions

Copy link
Copy Markdown

Review

Solid, well-scoped bug fix. The rationale in the PR description matches the code changes cleanly, and each of the four edits addresses a real issue rather than incidental cleanup.

Strengths

  • Root-cause fix: Switching from req.url === '/marketplace/register/' to query.slug from the catch-all params is the right call — query.slug comes from Next's route resolver and won't be affected by whatever the proxy is doing to req.url.
  • Hydration fix is well-reasoned: The next/dynamic + ssr: false guard is the correct fix for components that read getCookie() directly during render. The inline comment explaining why is helpful.
  • getInstanceZUID regression fix is a genuine correctness improvement: The previous pathname.split('/')[2] returned truthy garbage on unrelated routes (e.g. 'installed' on /marketplace/installed/, 'foo' on /docs/foo/bar). Scoping to /instances/{zuid} matches actual intent.
  • Cookie → Zustand swap for workingInstance in the two marketplace subpages is a small but real UX improvement (reactive to instance switcher).

Observations / follow-ups (non-blocking)

  1. getMarketplaceData(req.url) at line 173 still uses req.url. If the proxy mutation motivating this PR affects marketplace URLs more broadly than just the two virtual pages, this call would fail for legitimate marketplace URLs and they'd silently 404 (extended-pages bypass wouldn't apply). Worth checking whether the proxy behavior is scoped only to these two paths or broader.

  2. Test plan checkboxes are unchecked — worth confirming production behavior before merging, especially the hydration-mismatch console check, since that's the second-order fix that only surfaces once the 404 stops.

  3. Inline notes left on src/store/index.js and the slug-guard block for smaller specifics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 [Bug]: The My Apps link on the Marketplace is a broken link

1 participant