Skip to content

Conversation

@softmarshmallow
Copy link
Member

@softmarshmallow softmarshmallow commented Feb 7, 2026

  • prefer url building with canonical
  • missing i18n from embedded forms via campaign view

Summary by CodeRabbit

  • New Features

    • Invite links now resolve to tenant-aware site URLs (canonical domains and normalized route paths).
    • Centralized, context-driven translations for form views with language/translation props and localized button labels.
    • Email verification text strings made required for consistent localization.
  • Refactor

    • Improved locale propagation through the invitation/signup flow and form provider.
  • Tests

    • Added comprehensive tests for tenant URL construction and canonical resolution.

Replace hardcoded base URL construction with a new `buildTenantSiteBaseUrl` function to dynamically generate tenant site URLs based on the campaign's `www_name` and `www_route_path`. This change ensures the use of canonical domains when available and improves URL handling in both the invite and refresh routes. Additionally, add unit tests for the new URL building logic to ensure correctness across various scenarios.
@vercel
Copy link

vercel bot commented Feb 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Feb 7, 2026 0:11am
grida Ready Ready Preview, Comment Feb 7, 2026 0:11am
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
code Ignored Ignored Feb 7, 2026 0:11am
legacy Ignored Ignored Feb 7, 2026 0:11am
backgrounds Skipped Skipped Feb 7, 2026 0:11am
blog Skipped Skipped Feb 7, 2026 0:11am
viewer Skipped Skipped Feb 7, 2026 0:11am

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Feb 7, 2026

Walkthrough

Refactors tenant base-URL construction with canonical-domain resolution, replaces manual URL assembly in invite/refresh routes, adds buildTenantSiteBaseUrl and its tests, introduces a FormView translation context with lang propagation, tightens i18n Translation shape to require previously-optional keys, and threads locale through the invitation signup flow.

Changes

Cohort / File(s) Summary
API Route Handlers
editor/app/(api)/(public)/v1/west/t/invite/route.ts, editor/app/(api)/(public)/v1/west/t/refresh/route.ts
Replaced manual base URL composition with buildTenantSiteBaseUrl(...); assert presence of campaign.www_name (renamed to raw_www_name in refresh); use derived inviteUrl for sharable URLs.
Tenant URL Module & Tests
editor/lib/tenant-url.ts, editor/lib/tenant-url.test.ts
Added buildTenantSiteBaseUrl with canonical RPC lookup (getCanonicalHostnameForTenant), route-path normalization, hosted vs local logic; comprehensive unit tests covering canonical resolution, fallbacks, normalization, and RPC mocking.
FormView Translation & Context
editor/grida-forms-hosted/e/formview.tsx
Introduced build_form_view_translation, FormViewTranslationContext, useFormViewTranslation; added lang/translation props to roots, moved footer/buttons to consume context instead of per-prop translations (public signatures changed).
i18n Resources
editor/i18n/resources.ts
Made previously optional Translation fields required (verify, resend, retry, sending and all email_challenge subfields), tightening the Translation interface.
Invitation Template / Locale Wiring
editor/theme/templates/enterprise/west-referral/invitation/page.tsx
Propagated locale through InvitationPageTemplate → SignUpForm → FormViewProvider; FormView.Root now receives lang (uses lang or locale); simplified Drawer footer component usage.

Sequence Diagram

sequenceDiagram
    participant Client as Client/Server
    participant Builder as buildTenantSiteBaseUrl()
    participant RPC as Service-Role RPC
    participant DB as Database

    Client->>Builder: buildTenantSiteBaseUrl({www_name, www_route_path, hosted, prefer_canonical})
    alt hosted = false
        Builder->>Client: http://{www_name}.localhost:3000{route}
    else hosted = true
        Builder->>Builder: platformHost = platformSiteHostnameForTenant(www_name)
        alt prefer_canonical = true
            Builder->>RPC: www_get_canonical_hostname(www_name)
            RPC->>DB: query canonical hostname
            DB-->>RPC: canonical hostname or null
            RPC-->>Builder: canonical hostname or null
            alt canonical available
                Builder->>Client: https://{canonicalHost}{route}
            else fallback
                Builder->>Client: https://{platformHost}{route}
            end
        else prefer_canonical = false
            Builder->>Client: https://{platformHost}{route}
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

breaking

Suggested reviewers

  • kmk142789

Poem

🐰 I hopped through routes and fixed the trail,
Canonicals found where local names fail,
Context carried words from root to submit,
Tests humbly check each normalized bit,
A tiny rabbit cheers: "URLs prevail!"

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Enterprise 260207-001' is vague and does not clearly describe the main changes in the pull request. Consider using a more descriptive title that summarizes the primary changes, such as 'Add canonical domain support and i18n fixes for embedded forms' or 'Refactor URL building with canonical domains and improve form translations'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch enterprise

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Refactor the form view to utilize shared i18n resources for dynamic translation based on the selected language. Introduce a context provider for translations, allowing components to access localized strings. Update the form components to use the new translation context, ensuring that the UI is properly localized. Additionally, modify the invitation page template to pass the locale to the form view provider.
@vercel vercel bot temporarily deployed to Preview – backgrounds February 7, 2026 11:51 Inactive
@vercel vercel bot temporarily deployed to Preview – viewer February 7, 2026 11:51 Inactive
@vercel vercel bot temporarily deployed to Preview – blog February 7, 2026 11:51 Inactive
@softmarshmallow softmarshmallow changed the title Enterprise 260207 Enterprise 260207-001 Feb 7, 2026
@softmarshmallow softmarshmallow marked this pull request as ready for review February 7, 2026 11:51
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@editor/lib/tenant-url.ts`:
- Around line 43-48: normalizeRoutePath currently preserves trailing slashes
(e.g., "/west/") which violates the "no trailing /" invariant; update the
function (normalizeRoutePath) to trim whitespace, then remove any trailing
slashes before further processing, and ensure the returned path has at most one
leading slash and no trailing slash (treat "/" or empty input as returning "").
Implement this by rtrim-ing trailing "/" characters from the intermediate raw
value (or using a regex) and then returning raw.startsWith("/") ? raw :
`/${raw}` after the trailing-slash removal.
- Around line 50-56: The JSDoc block above the tenant URL builder contains raw
escape artifacts like "\n+" that should be removed; edit the doc comment in
editor/lib/tenant-url.ts (the comment describing "Builds the **tenant site base
URL**...") to eliminate the "\n+" sequences and reformat the example list into
plain JSDoc lines (e.g., each example as " - `https://acme.example.com/west`")
while keeping the intended content and note about no trailing slash and usage;
ensure the comment is valid JSDoc without raw escape characters so hover
tooltips and generated docs render cleanly.
🧹 Nitpick comments (4)
editor/app/(api)/(public)/v1/west/t/invite/route.ts (1)

8-8: IS_HOSTED is duplicated across route files; consider importing from editor/env.ts.

Both invite/route.ts and refresh/route.ts define const IS_HOSTED = process.env.VERCEL === "1" locally, while editor/env.ts already exports the same constant. Using the shared export avoids drift if the check ever changes.

editor/lib/tenant-url.test.ts (2)

34-45: Duplicate test — identical to the test on lines 20–32 minus the RPC assertion.

This test uses the exact same inputs and expected output as the one above. Consider removing it or differentiating the scenario (e.g., test with prefer_canonical: false in local dev).


113-144: Consider adding a test case for a trailing-slash route path (e.g. "/west/").

This would document the expected behavior and guard the "no trailing slash" invariant. Currently normalizeRoutePath doesn't strip trailing slashes, so adding this test would either confirm the gap or serve as a regression guard once fixed.

editor/theme/templates/enterprise/west-referral/invitation/page.tsx (1)

410-414: Missing dependency in useEffect cleanup.

clearSessionStorage is referenced inside the effect but omitted from the dependency array. With React 19's strict mode this effect fires twice in dev, which is fine for cleanup, but the stale closure is still a concern if clearSessionStorage identity ever changes. This appears to be pre-existing, but worth noting since you're touching adjacent code.

   useEffect(() => {
     return () => {
       clearSessionStorage();
     };
-  }, []);
+  }, [clearSessionStorage]);

@vercel vercel bot temporarily deployed to Preview – blog February 7, 2026 12:09 Inactive
@vercel vercel bot temporarily deployed to Preview – viewer February 7, 2026 12:09 Inactive
@vercel vercel bot temporarily deployed to Preview – backgrounds February 7, 2026 12:09 Inactive
@softmarshmallow softmarshmallow merged commit b7d035b into main Feb 7, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant