fix(frontend): enable /inbox and /code routes to embed Terragon via iframe#984
fix(frontend): enable /inbox and /code routes to embed Terragon via iframe#984vdimarco wants to merge 1 commit into
Conversation
…frame Previously, /inbox and /code had redirects that bypassed the iframe embedding page, sending users directly to the external Terragon URL. This broke the postMessage authentication flow. Changes: - Remove /inbox and /code redirects from redirects.ts - Update /code/page.tsx to re-export /inbox/page (same embedding) - Update /code/layout.tsx with InboxLayoutClient for full-height iframe - Add /code route to CSP frame-ancestors in next.config.ts Now both routes serve the embedded Terragon inbox with proper auth. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe Changes
Possibly related PRs
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Found 33 test failures on Blacksmith runners: Failures
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/app/code/layout.tsx (2)
2-2: Consider movingInboxLayoutClientto a shared location.Importing
InboxLayoutClientfrom a sibling route (../inbox/inbox-layout-client) creates an inter-route dependency. If the inbox route is restructured or removed, this import breaks. A shared path likesrc/components/layouts/InboxLayoutClient(orsrc/app/_shared/) would give this component a stable home for reuse across routes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/code/layout.tsx` at line 2, Move the InboxLayoutClient component out of the sibling route and into a stable shared location (e.g., src/components/layouts/InboxLayoutClient or src/app/_shared/InboxLayoutClient), then update imports that reference InboxLayoutClient in layout.tsx and any other files to the new path; ensure the component's export (named or default) is preserved in the new file so references to InboxLayoutClient still resolve.
10-10: Hardcoded site URL violates the environment-variable guideline.
url: 'https://gatewayz.ai/code'is baked in; staging/preview deployments will emit incorrect canonical OG URLs. Per coding guidelines, all configuration values should use environment variables prefixed withNEXT_PUBLIC_.♻️ Proposed fix
- url: 'https://gatewayz.ai/code', + url: `${process.env.NEXT_PUBLIC_SITE_URL ?? 'https://gatewayz.ai'}/code`,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/code/layout.tsx` at line 10, Replace the hardcoded url value with an env var: use process.env.NEXT_PUBLIC_SITE_URL (or a new NEXT_PUBLIC_SITE_URL) and append the path segment '/code' when building the URL so staging/preview picks up the correct domain; update the metadata creation in layout.tsx (the object containing url: 'https://gatewayz.ai/code') to compute url: `${process.env.NEXT_PUBLIC_SITE_URL}/code` (optionally provide a sensible fallback) so canonical/OG URLs are driven by NEXT_PUBLIC_ env vars.next.config.ts (1)
155-177: Extract the sharedframe-ancestorsCSP value into a named constant.The same
Content-Security-Policyvalue is now duplicated verbatim between the/inboxrule (line 162) and the new/coderule (line 174). A single origin list edit (e.g., adding a staging domain) must now be made in two places.♻️ Proposed refactor
+ // Trusted origins that may embed GatewayZ routes in an iframe + const trustedEmbedOrigins = + "frame-ancestors 'self' https://beta.gatewayz.ai https://gatewayz.ai https://www.gatewayz.ai https://inbox.gatewayz.ai"; { source: '/inbox', headers: [ ...commonSecurityHeaders, { key: 'Content-Security-Policy', - value: "frame-ancestors 'self' https://beta.gatewayz.ai https://gatewayz.ai https://www.gatewayz.ai https://inbox.gatewayz.ai", + value: trustedEmbedOrigins, }, ], }, { source: '/code', headers: [ ...commonSecurityHeaders, { key: 'Content-Security-Policy', - value: "frame-ancestors 'self' https://beta.gatewayz.ai https://gatewayz.ai https://www.gatewayz.ai https://inbox.gatewayz.ai", + value: trustedEmbedOrigins, }, ], },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@next.config.ts` around lines 155 - 177, The CSP frame-ancestors string is duplicated in the headers for the '/inbox' and '/code' route rules; extract that value into a single named constant (e.g., FRAME_ANCESTORS_CSP or INBOX_FRAME_ANCESTORS) and reference the constant in both header objects instead of embedding the literal, updating the header value assignments where key: 'Content-Security-Policy' is set and keeping the rest of the header arrays (including ...commonSecurityHeaders) unchanged so a future origin list edit only needs to change the constant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/code/layout.tsx`:
- Line 16: openGraph.images[0].url and twitter.images[0] currently point to the
beta URL 'https://beta.gatewayz.ai/og-inbox.jpg' which can break the /code
social card; update both references (openGraph.images[0].url and
twitter.images[0]) to use either the production URL (e.g.,
'https://gatewayz.ai/og-inbox.jpg' or a dedicated '/code' image) or read the
base image host from an environment variable (e.g.,
NEXT_PUBLIC_SOCIAL_IMAGE_BASE) and compose the final path (e.g.,
`${process.env.NEXT_PUBLIC_SOCIAL_IMAGE_BASE}/og-code.jpg`) so both places use
the same, non-beta source.
---
Nitpick comments:
In `@next.config.ts`:
- Around line 155-177: The CSP frame-ancestors string is duplicated in the
headers for the '/inbox' and '/code' route rules; extract that value into a
single named constant (e.g., FRAME_ANCESTORS_CSP or INBOX_FRAME_ANCESTORS) and
reference the constant in both header objects instead of embedding the literal,
updating the header value assignments where key: 'Content-Security-Policy' is
set and keeping the rest of the header arrays (including
...commonSecurityHeaders) unchanged so a future origin list edit only needs to
change the constant.
In `@src/app/code/layout.tsx`:
- Line 2: Move the InboxLayoutClient component out of the sibling route and into
a stable shared location (e.g., src/components/layouts/InboxLayoutClient or
src/app/_shared/InboxLayoutClient), then update imports that reference
InboxLayoutClient in layout.tsx and any other files to the new path; ensure the
component's export (named or default) is preserved in the new file so references
to InboxLayoutClient still resolve.
- Line 10: Replace the hardcoded url value with an env var: use
process.env.NEXT_PUBLIC_SITE_URL (or a new NEXT_PUBLIC_SITE_URL) and append the
path segment '/code' when building the URL so staging/preview picks up the
correct domain; update the metadata creation in layout.tsx (the object
containing url: 'https://gatewayz.ai/code') to compute url:
`${process.env.NEXT_PUBLIC_SITE_URL}/code` (optionally provide a sensible
fallback) so canonical/OG URLs are driven by NEXT_PUBLIC_ env vars.
| description: 'Delegate coding tasks to AI background agents. Run coding agents in parallel inside remote sandboxes with Claude Code, Codex, and more.', | ||
| images: [ | ||
| { | ||
| url: 'https://beta.gatewayz.ai/og-inbox.jpg', |
There was a problem hiding this comment.
OG/Twitter image hosted on beta.gatewayz.ai with an inbox-specific filename.
Both openGraph.images[0].url and twitter.images[0] point to https://beta.gatewayz.ai/og-inbox.jpg. If the beta subdomain is deprecated or the image is updated only for inbox, the /code social card silently breaks. Consider either:
- Using the production domain (
https://gatewayz.ai/og-inbox.jpg) and/or a/code-specific image, or - Storing the base image URL in a
NEXT_PUBLIC_environment variable consistent with the site URL.
Also applies to: 28-28
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/code/layout.tsx` at line 16, openGraph.images[0].url and
twitter.images[0] currently point to the beta URL
'https://beta.gatewayz.ai/og-inbox.jpg' which can break the /code social card;
update both references (openGraph.images[0].url and twitter.images[0]) to use
either the production URL (e.g., 'https://gatewayz.ai/og-inbox.jpg' or a
dedicated '/code' image) or read the base image host from an environment
variable (e.g., NEXT_PUBLIC_SOCIAL_IMAGE_BASE) and compose the final path (e.g.,
`${process.env.NEXT_PUBLIC_SOCIAL_IMAGE_BASE}/og-code.jpg`) so both places use
the same, non-beta source.
Summary
/inboxand/coderedirects fromredirects.tsthat were bypassing the iframe embedding/code/page.tsxto re-export/inbox/page(same Terragon embedding)/code/layout.tsxwithInboxLayoutClientfor full-height iframe rendering/coderoute to CSPframe-ancestorsheaders innext.config.tsProblem
The
/inboxand/coderoutes had redirects configured that immediately sent users to the external Terragon Railway URL (https://terragon-www-production.up.railway.app/dashboard). This bypassed the page components that embed Terragon via iframe with proper postMessage authentication.Solution
Removed the redirects so the page components are served instead. Now both
/inboxand/codeproperly embed Terragon with:?embed=true&awaitAuth=trueparametersTest plan
/inbox- should show embedded Terragon inbox (not redirect)/code- should show embedded Terragon inbox (not redirect)🤖 Generated with Claude Code
Summary by CodeRabbit
Greptile Summary
Removed redirects for
/inboxand/coderoutes to enable proper Terragon iframe embedding with postMessage authentication.Key Changes:
/inboxand/coderedirects fromredirects.tsthat were bypassing page components/code/page.tsxto re-export/inbox/pagefor consistent Terragon embedding/code/layout.tsxto useInboxLayoutClientfor full-height iframe rendering/coderoute to CSPframe-ancestorsheaders innext.config.tsto allow embedding from trusted GatewayZ originsTechnical Implementation:
Confidence Score: 5/5
/coderoute to reuse the/inboximplementation, and adds proper CSP headers for security. The implementation is consistent with the existing/inboxsetup and includes appropriate comments explaining the changes.Important Files Changed
/inboxand/coderedirects to allow page components to embed Terragon via iframe/inbox/pageinstead of/claude-code/pagefor Terragon embeddingInboxLayoutClientfor full-height iframe rendering and improved metadata/coderoute to CSPframe-ancestorsheaders to allow embedding from trusted originsLast reviewed commit: 35164a4