Enable multizone embedding via prefixed asset URLs#96
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Beta preview has been cleaned up because this PR was closed. |
The chat is being embedded on policyengine.org/uk/chat as a multizone child (see policyengine-app-v2 PR #1036). Vercel rewrites are the mechanism; cross-origin iframes blank out for Next.js apps per CLAUDE.md. For the rewrites to work end-to-end, the chat's static asset URLs need to live under a prefixed path so the website can proxy them back through policyengine.org. Matches the household-api-docs zone pattern (which uses the same /_zones/<name> convention). Two coordinated files: - frontend/next.config.js: assetPrefix '/_zones/uk-chat' in production builds. Dev server stays unprefixed for local development. - frontend/vercel.json: rewrite /_zones/uk-chat/_next/:path* back to /_next/:path* so the chat host serves the prefixed URLs that the generated HTML references, without needing basePath (which would break the standalone preview URL). Pages still live at "/" on the chat host, so direct previews (policyengine-uk-chat.vercel.app) keep working unchanged.
1432dfc to
41a5ed5
Compare
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Review
The mechanism is correct and nicely minimal. The phase-function config form is valid, the vercel.json rewrite is a catch-all on /_zones/uk-chat/_next/:path* so it covers _next/static, _next/image, and _next/data (query strings pass through), and the self-rewrite on the chat host is what keeps the standalone preview working with the prefix applied — that's the clever part. No existing vercel.json to conflict with.
One real gap: public/ assets referenced by absolute path aren't covered. assetPrefix only rewrites Next's _next/* build output; it does not touch files in public/ referenced by literal /... paths. And the website's multizone rewrites only proxy /uk/chat and /_zones/uk-chat/_next/* to the chat host — bare public paths resolve against policyengine.org. Two of these are on the embedded main chat page:
frontend/src/app/ChatPage.tsx:1451— the header logo usesurl(/favicon.svg)as a CSS mask. In the embed this requestspolicyengine.org/favicon.svg, which isn't rewritten → mask fails to load and the logo span renders as a solid colored box.frontend/src/app/layout.tsx:8—icons: { icon: "/favicon.svg" }, same unprefixed-path issue for the favicon.
(/policyengine-logo.svg in s/[token]/page.tsx is only on the share route, which isn't reached through the /uk/chat zone, so it's fine in practice.)
So the standalone preview will look correct, but policyengine.org/uk/chat will likely show a broken header logo. Options: add the specific public asset paths to the website's rewrite list, or move/serve those assets under the prefixed path and reference them prefix-aware. Worth resolving before the "no console asset 404s" checkbox can pass.
Minor: confirm the Vercel project's root directory is frontend/ so this vercel.json is actually picked up (the Next app and output: standalone suggest it is, but the rewrite silently does nothing if the root is the repo root).
Config-only change; did not run a build.
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Approving — this is clean, minimal, and correct, and it's the rare PR in the current queue that's untouched by the #116 backend repackaging (frontend-only).
Why it's right:
assetPrefix: '/_zones/uk-chat'in prod /undefinedin dev (via the phase function) is the standard Next.js multizone pattern, and disabling it for the dev server keeps local dev simple.- The new
vercel.jsonrewrite (/_zones/uk-chat/_next/:path*→/_next/:path*) lives on the chat host itself, which is the key detail: the standalone preview URL stays self-consistent (its HTML requests the prefixed asset URLs and the same host rewrites them back to what Next actually serves). The:path*subtree also covers/_next/image, sonext/imageis fine. - Safe to land before the counterpart. app-v2 #1036 is still open, but merging this first is the correct ordering, not a risk: in isolation it only adds a prefix string + a self-canceling rewrite, so nothing changes behaviour until the website side also adds its rewrites. It unblocks #1036 rather than waiting on it.
Two things to verify before relying on the embed (neither affects the standalone URL, so neither blocks merge):
- Runtime API calls use absolute URLs (Modal), so the
/uk/chatmount won't break API traffic —assetPrefixonly touches/_nextstatic assets, notfetch(). Worth a glance for any relative/api-style calls. - The chat is effectively single-route — the PR deliberately skips
basePath(which would break the standalone URL), so any internal navigation assuming root/would break when embedded. Non-issue for a one-page chat SPA; just confirm there's no client-side routing to sibling paths.
The one thing I'd actually do before clicking merge is tick the test-plan box: load the Vercel preview and confirm DevTools shows assets requested at /_zones/uk-chat/_next/static/* returning 200.
@anth-volk — could you give this a review? It touches the deploy/embedding boundary, which is your area. I'm happy to merge it once you approve.
What
Makes the chat embeddable as a multizone child on `policyengine.org/uk/chat` (see policyengine-app-v2 PR #1036). Matches the household-api-docs zone pattern.
How
Two files:
End-to-end flow once both this and PR #1036 merge
The website (policyengine.org) rewrites:
```
/uk/chat → chat-host/
/_zones/uk-chat/_next/:path* → chat-host/_zones/uk-chat/_next/:path*
```
What stays the same
Test plan