-
Notifications
You must be signed in to change notification settings - Fork 377
chore(clerk-js): Update notice when cancelling a trial #6582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(clerk-js): Update notice when cancelling a trial #6582
Conversation
🦋 Changeset detectedLatest commit: ba2f317 The changes in this PR will be included in the next version bump. This PR includes changesets to release 22 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/elements
@clerk/clerk-expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/clerk-react
@clerk/react-router
@clerk/remix
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/themes
@clerk/types
@clerk/upgrade
@clerk/vue
commit: |
📝 WalkthroughWalkthroughRenames localization key commerce.cancelFreeTrialDescription → commerce.cancelFreeTrialAccessUntil (newly accepts a date) across en-US and many locale files (old key removed only in en-US). Updates types to replace cancelFreeTrialDescription with cancelFreeTrialAccessUntil and broaden its allowed params to include 'date'. Refactors SubscriptionDetails to introduce internal SubscriptionCard and DetailRow, and passes selectedSubscription.periodEnd (cast to Date) to the new localization key. Updates a unit test string to expect the date-based cancellation message. Adds two changeset metadata files for version bumps and the Billing Beta API rename. Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)
282-285
: Avoid hard-coded “upcoming ” in localized textInjecting the English string “upcoming ” into the plan parameter makes the title partially unlocalizable and violates the “no hard-coded values” guideline. Pass only the plan name and handle “upcoming” via localization.
Apply this diff:
- : localizationKeys('commerce.cancelSubscriptionTitle', { - plan: `${selectedSubscription.status === 'upcoming' ? 'upcoming ' : ''}${selectedSubscription.plan.name}`, - }) + : localizationKeys('commerce.cancelSubscriptionTitle', { + plan: selectedSubscription.plan.name, + })If you need an “upcoming” variant, prefer a dedicated key (e.g.,
cancelUpcomingSubscriptionTitle
) or introduce a boolean param (e.g.,upcoming: true
) and adjust types/localizations accordingly in a follow-up.
🧹 Nitpick comments (7)
.changeset/thick-frogs-hope.md (1)
5-5
: Make the patch note a bit more explicit about the UX changeClarify that the notice now mentions access remains until the trial end date (and no charges apply). This helps consumers scanning release notes understand what changed.
Apply this diff:
-Update notice when cancelling a trial. +Update trial cancellation notice to clarify access remains until the trial end date and no charges apply..changeset/afraid-waves-bow.md (1)
7-7
: Great: capture the public API rename. Add a brief migration hint.A short migration note reduces friction for adopters of Billing Beta.
Apply this diff to append a migration line:
[Billing Beta] Rename `cancelFreeTrialDescription` to `cancelFreeTrialAccessUntil`. + +Migration: +- Replace `commerce.cancelFreeTrialDescription` with `commerce.cancelFreeTrialAccessUntil` and pass `{ plan, date }`.packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (2)
1215-1219
: Make the assertion resilient to localization tweaksHard-coding the full sentence is brittle. Assert the critical tokens (plan name + formatted date + “no charges will apply”) instead, or use a regex.
Apply this diff:
- expect( - getByText( - 'Your Pro Plan trial will remain active until February 1, 2021. After that, you will no longer have access and no charges will apply.', - ), - ).toBeVisible(); + // Less brittle assertion: match core tokens via regex + expect( + getByText(/pro plan trial will remain active until February 1, 2021.*no longer have access.*no charges will apply/i), + ).toBeVisible();Optionally, also assert the date token separately to decouple copy from formatting around it:
expect(getByText('February 1, 2021')).toBeVisible();
614-716
: Consider adding a test for canceling an upcoming subscriptionYou already cover active monthly and free trial cancellations. Add a test asserting the “no charge” copy path for upcoming subscriptions to cover
commerce.cancelSubscriptionNoCharge
.I can draft a focused test case that sets
status: 'upcoming'
and asserts:
- title uses “Cancel … Subscription?”
- description uses
cancelSubscriptionNoCharge
- destructive action label matches
commerce.cancelSubscription
Would you like me to push that test?packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2)
291-303
: Null-safe date for free trial cancellation description
selectedSubscription.periodEnd
is cast toDate
but may be nullable in the type. Passingundefined
to localization date formatting will throw at runtime. Use a safe fallback (e.g.,periodStart
orcreatedAt
) or guard.Minimal safe change within this block:
- ? localizationKeys('commerce.cancelFreeTrialAccessUntil', { - plan: selectedSubscription.plan.name, - date: selectedSubscription.periodEnd as Date, - }) + ? localizationKeys('commerce.cancelFreeTrialAccessUntil', { + plan: selectedSubscription.plan.name, + date: (selectedSubscription.periodEnd ?? + selectedSubscription.periodStart ?? + selectedSubscription.createdAt) as Date, + })Alternatively, guard before rendering the confirmation to avoid showing the dialog without a known end date, and log appropriately.
To validate assumptions, add a unit test where a free trial item has a missing
periodEnd
and ensure the UI doesn’t crash.
404-453
: Tighten action list typing to avoidnull
entries
filter(a => a !== null)
still leaves a union in many TS configs. Narrow the type soThreeDotsMenu
receives a properly typed action array.Example refactor:
- const actions = React.useMemo(() => { + type Action = React.ComponentProps<typeof ThreeDotsMenu>['actions'][number]; + const actions: Action[] = React.useMemo(() => { if (!canManageBilling) { return []; } - return [ + return ([ isSwitchable ? { /* ... */ } : null, isCancellable ? { /* ... */ } : null, isReSubscribable ? { /* ... */ } : null, - ].filter(a => a !== null); + ] as const).filter((a): a is Action => Boolean(a)); }, [/* deps */]);packages/localizations/src/en-US.ts (1)
69-70
: Optional: align tone with nearby cancellation copy (single-sentence + follow-up)If you want to mirror the phrasing style of cancelSubscriptionAccessUntil, consider this minor tweak:
- "Your {{plan}} trial will remain active until {{ date | longDate('en-US') }}. After that, you will no longer have access and no charges will apply.", + "Your {{plan}} trial will remain active until {{ date | longDate('en-US') }}, after which you will no longer have access. No charges will apply.",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
.changeset/afraid-waves-bow.md
(1 hunks).changeset/thick-frogs-hope.md
(1 hunks)packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
(1 hunks)packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
(1 hunks)packages/localizations/src/en-US.ts
(1 hunks)packages/types/src/localization.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
packages/clerk-js/src/ui/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/clerk-js-ui.mdc)
packages/clerk-js/src/ui/**/*.{ts,tsx}
: Element descriptors should always be camelCase
Use element descriptors in UI components to enable consistent theming and styling via appearance.elements
Element descriptors should generate unique, stable CSS classes for theming
Element descriptors should handle state classes (e.g., cl-loading, cl-active, cl-error, cl-open) automatically based on component state
Do not render hard-coded values; all user-facing strings must be localized using provided localization methods
Use the useLocalizations hook and localizationKeys utility for all text and error messages
Use the styled system (sx prop, theme tokens, responsive values) for custom component styling
Use useCardState for card-level state, useFormState for form-level state, and useLoadingStatus for loading states
Always use handleError utility for API errors and use translateError for localized error messages
Use useFormControl for form field state, implement proper validation, and handle loading and error states in forms
Use localization keys for all form labels and placeholders
Use element descriptors for consistent styling and follow the theme token system
Use the Card and FormContainer patterns for consistent UI structure
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.{jsx,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{jsx,tsx}
: Use error boundaries in React components
Minimize re-renders in React components
**/*.{jsx,tsx}
: Always use functional components with hooks instead of class components
Follow PascalCase naming for components:UserProfile
,NavigationMenu
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Use useState for simple state management
Use useReducer for complex state logic
Implement proper state initialization
Use proper state updates with callbacks
Implement proper state cleanup
Use Context API for theme/authentication
Implement proper state selectors
Use proper state normalization
Implement proper state persistence
Use React.memo for expensive components
Implement proper useCallback for handlers
Use proper useMemo for expensive computations
Implement proper virtualization for lists
Use proper code splitting with React.lazy
Implement proper cleanup in useEffect
Use proper refs for DOM access
Implement proper event listener cleanup
Use proper abort controllers for fetch
Implement proper subscription cleanup
Use proper HTML elements
Implement proper ARIA attributes
Use proper heading hierarchy
Implement proper form labels
Use proper button types
Implement proper focus management
Use proper keyboard shortcuts
Implement proper tab order
Use proper skip links
Implement proper focus traps
Implement proper error boundaries
Use proper error logging
Implement proper error recovery
Use proper error messages
Implement proper error fallbacks
Use proper form validation
Implement proper error states
Use proper error messages
Implement proper form submission
Use proper form reset
Use proper component naming
Implement proper file naming
Use proper prop naming
Implement proper...
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
packages/**/*.{test,spec}.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Unit tests should use Jest or Vitest as the test runner.
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/{clerk-js,elements,themes}/**/*.{test,spec}.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Visual regression testing should be performed for UI components.
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)
**/*.tsx
: Use proper type definitions for props and state
Leverage TypeScript's type inference where possible
Use proper event types for handlers
Implement proper generic types for reusable components
Use proper type guards for conditional rendering
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
**/*.test.{jsx,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)
**/*.test.{jsx,tsx}
: Use React Testing Library
Test component behavior, not implementation
Use proper test queries
Implement proper test isolation
Use proper test coverage
Test component interactions
Use proper test data
Implement proper test setup
Use proper test cleanup
Implement proper test assertions
Use proper test structure
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/typescript.mdc)
**/__tests__/**/*.{ts,tsx}
: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
packages/localizations/src/en-US.ts
packages/types/src/localization.ts
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
.changeset/**
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Automated releases must use Changesets.
Files:
.changeset/thick-frogs-hope.md
.changeset/afraid-waves-bow.md
packages/localizations/**/*
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Localization files must be placed in 'packages/localizations/'.
Files:
packages/localizations/src/en-US.ts
**/localizations/**/*.ts
⚙️ CodeRabbit Configuration File
**/localizations/**/*.ts
: Review the changes to localization files with the following guidelines:
- Ensure that no existing translations are accidentally removed unless they are being replaced or fixed. If a string is removed, verify that it is intentional and justified.
- Check that all translations are friendly, formal, or semi-formal. Explicit, offensive, or inappropriate language is not allowed. If you find any potentially offensive language or are unsure, tag the @clerk/sdk-infra team in a separate comment. If you do not intend to tag the team, refer to it as "Clerk SDK Infra team" instead.
- Use the most up-to-date base localization file (https://github.com/clerk/javascript/blob/main/packages/localizations/src/en-US.ts) to validate changes, ensuring consistency and completeness.
- Confirm that new translations are accurate, contextually appropriate, and match the intent of the original English strings.
- Check for formatting issues, such as missing placeholders, incorrect variable usage, or syntax errors.
- Ensure that all keys are unique and that there are no duplicate or conflicting entries.
- If you notice missing translations for new keys, flag them for completion.
Files:
packages/localizations/src/en-US.ts
🔇 Additional comments (3)
packages/types/src/localization.ts (1)
190-193
: All references tocancelFreeTrialDescription
removed and new key usage verified
- No occurrences of the old key
cancelFreeTrialDescription
remain in the codebase.- The new key
cancelFreeTrialAccessUntil
is defined in
- packages/types/src/localization.ts
- packages/localizations/src/en-US.ts (with both
plan
anddate
placeholders)- Usage in
- packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
correctly passes bothplan
anddate
parameters.packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)
160-167
: LGTM: SubscriptionCard extraction improves readabilityThe split into per-subscription cards and a DetailRow helper is a solid internal refactor and makes the component easier to follow and test.
packages/localizations/src/en-US.ts (1)
69-70
: Copy update is clear; placeholders and filters look correct
- Key name aligns with existing pattern (…AccessUntil).
- Placeholders use expected names: plan, date.
- Date filter matches house style: longDate('en-US').
Looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 14
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/localizations/src/ro-RO.ts (1)
186-186
: Template syntax error: extra closing brace in dates.numericThere’s an extra
}
that will likely break interpolation/parsing.Apply this diff:
- numeric: "{{ date | numeric('en-US') }}}", + numeric: "{{ date | numeric('en-US') }}",packages/localizations/src/mn-MN.ts (1)
71-117
: MissingcancelFreeTrialAccessUntil
in core localization modulesOur verification shows the new key was added to individual locale files but is absent from the central modules that drive exports, type-generation, and default strings:
• packages/localizations/src/index.ts
• packages/localizations/src/utils/enUS_v4.ts
• packages/localizations/src/utils/generate.ts
• packages/localizations/src/utils/utils.tsNo occurrences of the removed
cancelFreeTrialDescription
remain, which is correct. However, our placeholder check found no locale strings that include both{{plan}}
and{{date}}
forcancelFreeTrialAccessUntil
. Please:
- Add
cancelFreeTrialAccessUntil
to the above core files so it’s recognized in builds and typings.- Ensure each locale’s value for
cancelFreeTrialAccessUntil
includes the{{plan}}
and{{date}}
placeholders in its translated string.
♻️ Duplicate comments (9)
packages/localizations/src/fi-FI.ts (1)
115-116
: Key path for keepFreeTrial — verify alignment with en-US schemaConfirm
commerce.keepFreeTrial
(sibling tokeepSubscription
) matches en-US. Some locales previously placed similar CTAs under different sub-objects; keep it consistent with the base.Use the script in the earlier comment to grep en-US for keepFreeTrial and verify placement.
packages/localizations/src/ms-MY.ts (2)
78-81
: Introduce date-based free-trial cancellation keys — track translation completenessKeys added correctly. Please ensure:
cancelFreeTrialAccessUntil
includes adate
placeholder when localized.- All references to the legacy
cancelFreeTrialDescription
are removed.Refer to the verification script in the fi-FI comment to check en-US and call sites.
115-116
: Confirm keepFreeTrial placement vs en-USValidate that
commerce.keepFreeTrial
aligns with base en-US structure.packages/localizations/src/ar-SA.ts (2)
78-81
: Free-trial cancelation keys added — ensure date param for AccessUntilSet for translation later is fine. Ensure
cancelFreeTrialAccessUntil
uses adate
placeholder when localized and UI has switched away from the deprecated key.Use the script in fi-FI to confirm base/callers.
115-116
: Placement of keepFreeTrialConfirm
commerce.keepFreeTrial
matches en-US; keep parallel tokeepSubscription
.packages/localizations/src/de-DE.ts (2)
78-81
: Added free-trial cancellation keys — align with types and en-USLooks correct. Plan to add translations; ensure
cancelFreeTrialAccessUntil
includes adate
placeholder.Use the fi-FI script to verify base and callers switched off the legacy key.
118-118
: keepFreeTrial key — verify placement vs base localeConfirm
commerce.keepFreeTrial
mirrors en-US (sibling tokeepSubscription
).packages/localizations/src/es-ES.ts (2)
78-81
: Free-trial cancelation keys added — ensure date-based messageAll good. When translating:
- Include the
date
placeholder incancelFreeTrialAccessUntil
.- Remove/avoid use of legacy
cancelFreeTrialDescription
.See fi-FI script to confirm base/callers.
115-116
: Confirm keepFreeTrial key path against en-USKeep consistent placement (
commerce.keepFreeTrial
) with the base locale.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…n-to-mention-that-user-will-stay-on-trial' into elef/bill-1180-trial-cancellation-to-mention-that-user-will-stay-on-trial
8dab159
to
6982655
Compare
There was a problem hiding this 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
♻️ Duplicate comments (1)
packages/localizations/src/ru-RU.ts (1)
160-161
: Using label-only strings for trial start/end looks correctPlain labels here align with the common pattern (UI injects the formatted date separately). No issues.
🧹 Nitpick comments (6)
packages/localizations/src/hu-HU.ts (2)
115-115
: Fill missing translation for keepFreeTrial to avoid fallbackProvide a Hungarian string for the CTA to keep consistency with nearby keys.
Apply this diff:
- keepFreeTrial: undefined, + keepFreeTrial: 'Próbaverzió megtartása',
152-161
: Add Hungarian translations for new subscriptionDetails keysThe following keys in packages/localizations/src/hu-HU.ts are currently undefined and should be translated into Hungarian. These are static labels (no placeholders needed):
• firstPaymentAmount
• firstPaymentOn
• trialEndsOn
• trialStartedOnApply this diff:
--- a/packages/localizations/src/hu-HU.ts +++ b/packages/localizations/src/hu-HU.ts @@ -152,7 +152,9 @@ - firstPaymentAmount: undefined, - firstPaymentOn: undefined, + firstPaymentAmount: 'Első fizetés összege', + firstPaymentOn: 'Első fizetés dátuma', nextPaymentAmount: undefined, nextPaymentOn: undefined, @@ -160,7 +162,9 @@ - trialEndsOn: undefined, - trialStartedOn: undefined, + trialEndsOn: 'Próbaverzió vége', + trialStartedOn: 'Próbaverzió kezdete', },Let me know if you need any further assistance!
packages/localizations/src/bg-BG.ts (2)
78-82
: Free-trial cancellation strings look correct; align longDate quote style for consistencyThe new keys and placeholders match en-US intent (date and plan). Minor nit: elsewhere in this file filters use single quotes for locales. Consider switching "bg-BG" to 'bg-BG' inside the longDate filter to match the prevailing style.
- 'Вашият пробен период ще продължи до {{ date | longDate("bg-BG") }}. След това ще загубите достъп до пробните функции. Няма да бъдете таксувани.', + 'Вашият пробен период ще продължи до {{ date | longDate(\'bg-BG\') }}. След това ще загубите достъп до пробните функции. Няма да бъдете таксувани.',
161-163
: Translate trial start/end labels; mirror en-US date placeholderThese new keys are still undefined. Suggest adding BG strings and using the date placeholder consistent with en-US.
Proposed translations:
- trialEndsOn: undefined, - trialStartedOn: undefined, + trialEndsOn: 'Пробният период приключва на {{ date | longDate(\'bg-BG\') }}', + trialStartedOn: 'Пробният период започна на {{ date | longDate(\'bg-BG\') }}',You can use the verification script from the previous comment to confirm the expected placeholder name (date) in en-US.
packages/localizations/src/ru-RU.ts (2)
115-116
: Fill in new “keep” actions to avoid falling back to EnglishThese were introduced alongside the trial notice changes. Providing RU strings prevents fallback and aligns tone with nearby labels.
Apply:
- keepFreeTrial: undefined, - keepSubscription: undefined, + keepFreeTrial: 'Сохранить пробный период', + keepSubscription: 'Сохранить подписку',
152-153
: Translate first-payment labels in ru-RU.tsIn en-US these two keys are simple labels (no interpolation). Mirror them in ru-RU:
• File: packages/localizations/src/ru-RU.ts (lines 152–153)
- firstPaymentAmount: undefined, - firstPaymentOn: undefined, + firstPaymentAmount: 'Сумма первого платежа', + firstPaymentOn: 'Дата первого платежа',
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (9)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
(1 hunks)packages/localizations/src/bg-BG.ts
(3 hunks)packages/localizations/src/bn-IN.ts
(3 hunks)packages/localizations/src/ca-ES.ts
(3 hunks)packages/localizations/src/es-MX.ts
(3 hunks)packages/localizations/src/hr-HR.ts
(3 hunks)packages/localizations/src/hu-HU.ts
(3 hunks)packages/localizations/src/ru-RU.ts
(3 hunks)packages/localizations/src/th-TH.ts
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/localizations/src/bn-IN.ts
- packages/localizations/src/hr-HR.ts
- packages/localizations/src/es-MX.ts
- packages/clerk-js/src/ui/components/SubscriptionDetails/tests/SubscriptionDetails.test.tsx
- packages/localizations/src/ca-ES.ts
- packages/localizations/src/th-TH.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
packages/localizations/**/*
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Localization files must be placed in 'packages/localizations/'.
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
**/localizations/**/*.ts
⚙️ CodeRabbit Configuration File
**/localizations/**/*.ts
: Review the changes to localization files with the following guidelines:
- Ensure that no existing translations are accidentally removed unless they are being replaced or fixed. If a string is removed, verify that it is intentional and justified.
- Check that all translations are friendly, formal, or semi-formal. Explicit, offensive, or inappropriate language is not allowed. If you find any potentially offensive language or are unsure, tag the @clerk/sdk-infra team in a separate comment. If you do not intend to tag the team, refer to it as "Clerk SDK Infra team" instead.
- Use the most up-to-date base localization file (https://github.com/clerk/javascript/blob/main/packages/localizations/src/en-US.ts) to validate changes, ensuring consistency and completeness.
- Confirm that new translations are accurate, contextually appropriate, and match the intent of the original English strings.
- Check for formatting issues, such as missing placeholders, incorrect variable usage, or syntax errors.
- Ensure that all keys are unique and that there are no duplicate or conflicting entries.
- If you notice missing translations for new keys, flag them for completion.
Files:
packages/localizations/src/bg-BG.ts
packages/localizations/src/hu-HU.ts
packages/localizations/src/ru-RU.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (22)
- GitHub Check: Integration Tests (nextjs, chrome, 15)
- GitHub Check: Integration Tests (nextjs, chrome, 14)
- GitHub Check: Integration Tests (tanstack-react-router, chrome)
- GitHub Check: Integration Tests (billing, chrome)
- GitHub Check: Integration Tests (react-router, chrome)
- GitHub Check: Integration Tests (express, chrome)
- GitHub Check: Integration Tests (machine, chrome)
- GitHub Check: Integration Tests (astro, chrome)
- GitHub Check: Integration Tests (nuxt, chrome)
- GitHub Check: Integration Tests (expo-web, chrome)
- GitHub Check: Integration Tests (sessions, chrome)
- GitHub Check: Integration Tests (vue, chrome)
- GitHub Check: Integration Tests (quickstart, chrome)
- GitHub Check: Integration Tests (tanstack-react-start, chrome)
- GitHub Check: Integration Tests (localhost, chrome)
- GitHub Check: Integration Tests (generic, chrome)
- GitHub Check: Integration Tests (ap-flows, chrome)
- GitHub Check: Integration Tests (elements, chrome)
- GitHub Check: Unit Tests (22, **)
- GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
- GitHub Check: Static analysis
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
packages/localizations/src/hu-HU.ts (1)
78-80
: Trial-cancellation translations LGTM; placeholders are correct
cancelFreeTrialAccessUntil
correctly includes{{date}}
.cancelFreeTrialTitle
correctly includes{{plan}}
.
Tone and style match the rest of hu-HU.packages/localizations/src/bg-BG.ts (1)
116-116
: keepFreeTrial translation LGTMClear and aligned with the new flow.
firstPaymentAmount: undefined, | ||
firstPaymentOn: undefined, | ||
nextPaymentAmount: undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Fill in subscriptionDetails “first payment” translations and confirm placeholder names
These are newly introduced keys and currently undefined. Propose adding friendly BG strings and mirroring en-US placeholders. Please verify the exact placeholder names (likely amount and date) against en-US before merging.
Proposed translations:
- firstPaymentAmount: undefined,
- firstPaymentOn: undefined,
+ firstPaymentAmount: 'Сума на първото плащане: {{ amount }}',
+ firstPaymentOn: 'Първо плащане на {{ date | longDate(\'bg-BG\') }}',
Run this to confirm the base en-US placeholders for these keys and ensure we’re using the same param names:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
en="$(fd -a 'en-US.ts' | head -n 1 || true)"
bg="$(fd -a 'bg-BG.ts' | head -n 1 || true)"
if [[ -z "${en}" || -z "${bg}" ]]; then
echo "en-US.ts or bg-BG.ts not found. Ensure packages/localizations/src/en-US.ts and bg-BG.ts exist."
exit 0
fi
echo "Base (en-US) — relevant keys:"
rg -nC1 -e 'firstPayment(Amount|On)\b' "$en" || true
echo -e "\nBulgarian (bg-BG) — relevant keys:"
rg -nC1 -e 'firstPayment(Amount|On)\b' "$bg" || true
Length of output: 1007
Fill in Bulgarian translations for new subscriptionDetails keys
The en-US entries for firstPaymentAmount
and firstPaymentOn
are static labels (no placeholders), so the BG values should mirror them directly. In packages/localizations/src/bg-BG.ts (lines 153–155), update as follows:
- firstPaymentAmount: undefined,
- firstPaymentOn: undefined,
+ firstPaymentAmount: 'Сума на първото плащане',
+ firstPaymentOn: 'Първото плащане на',
- nextPaymentAmount: undefined,
+ nextPaymentAmount: 'Сума на следващото плащане',
If these strings are actually rendered with dynamic values in code, switch to template syntax (e.g. {{ amount }}
or date filters) to match the implementation.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
firstPaymentAmount: undefined, | |
firstPaymentOn: undefined, | |
nextPaymentAmount: undefined, | |
firstPaymentAmount: 'Сума на първото плащане', | |
firstPaymentOn: 'Първото плащане на', | |
nextPaymentAmount: 'Сума на следващото плащане', |
🤖 Prompt for AI Agents
In packages/localizations/src/bg-BG.ts around lines 153 to 155, the Bulgarian
translations for subscriptionDetails are empty; set firstPaymentAmount and
firstPaymentOn to the same static Bulgarian strings used in en-US (translate the
English labels into Bulgarian), and provide an appropriate Bulgarian translation
for nextPaymentAmount as well; if these keys are actually rendered with dynamic
values in code, replace the static text with template placeholders (e.g.,
{{amount}} or {{date}}) to match the implementation.
cancelFreeTrial: 'Отменить пробный период', | ||
cancelFreeTrialAccessUntil: "Вы сохраните доступ к пробной версии до {{ date | numeric('ru-RU') }}.", | ||
cancelFreeTrialTitle: 'Отменить пробный период', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Good addition; minor wording/consistency nit for Russian and verify base placeholders
The new key uses the date placeholder correctly. Two small improvements:
- Use “пробный период” consistently across RU strings (it’s already used at Lines 80, 160, 161).
- Prefer a noun phrase for the title (many titles in this file are nouns), keeping the button as an action.
Apply this diff if you agree:
- cancelFreeTrial: 'Отменить пробный период',
- cancelFreeTrialAccessUntil: "Вы сохраните доступ к пробной версии до {{ date | numeric('ru-RU') }}.",
- cancelFreeTrialTitle: 'Отменить пробный период',
+ cancelFreeTrial: 'Отменить пробный период',
+ cancelFreeTrialAccessUntil: "Доступ в рамках пробного периода сохранится до {{ date | numeric('ru-RU') }}.",
+ cancelFreeTrialTitle: 'Отмена пробного периода',
To double-check the correct placeholder shape (and confirm the old key is gone), run:
🏁 Script executed:
#!/bin/bash
set -e
# 0) Ensure the removed key isn't used anywhere
rg -nP -C2 '\bcancelFreeTrialDescription\b' || echo 'OK: cancelFreeTrialDescription not found'
# 1) Inspect the en-US base translations for reference
EN_US_FILE="$(fd -a 'en-US.ts' packages/localizations | head -n1)"
echo "Base file: $EN_US_FILE"
rg -n -C2 -e 'cancelFreeTrial(AccessUntil|Description)' -e 'keepFreeTrial' -e 'keepSubscription' -e 'firstPayment(On|Amount)' -e 'trial(Started|Ends)On' "$EN_US_FILE"
# 2) Show all current uses across the repo for the new key (to confirm param names)
rg -nP -C2 'cancelFreeTrialAccessUntil'
Length of output: 22742
Minor RU wording improvements & add missing plan placeholder
Two fixes in packages/localizations/src/ru-RU.ts
(around lines 79–80):
• Rephrase the “access until” string to use “пробный период” consistently
• Change the dialog title to a noun phrase and include the {{ plan }}
placeholder
Apply this diff:
--- a/packages/localizations/src/ru-RU.ts
+++ b/packages/localizations/src/ru-RU.ts
@@ -78,3 +78,4 @@
cancelFreeTrial: 'Отменить пробный период',
- cancelFreeTrialAccessUntil: "Вы сохраните доступ к пробной версии до {{ date | numeric('ru-RU') }}.",
- cancelFreeTrialTitle: 'Отменить пробный период',
+ cancelFreeTrialAccessUntil: "Доступ в рамках пробного периода сохранится до {{ date | numeric('ru-RU') }}.",
+ cancelFreeTrialTitle: 'Отмена пробного периода для плана {{ plan }}?',
To verify placeholders and wording:
#!/bin/bash
set -e
EN_US_FILE="$(fd -a 'en-US.ts' packages/localizations | head -n1)"
echo "❯ RU strings:"
rg -n -C1 'cancelFreeTrial(AccessUntil|Title)' packages/localizations/src/ru-RU.ts
echo "❯ Base en-US placeholders:"
rg -n -C1 'cancelFreeTrial(AccessUntil|Title)' "$EN_US_FILE"
🤖 Prompt for AI Agents
In packages/localizations/src/ru-RU.ts around lines 78 to 80, update two
strings: change cancelFreeTrialAccessUntil to consistently reference "пробный
период" (e.g., use wording like "Доступ к пробному периоду сохранён до {{ date |
numeric('ru-RU') }}.") and modify cancelFreeTrialTitle to a noun phrase that
includes the {{ plan }} placeholder (e.g., a short title like "Отмена пробного
периода {{ plan }}"); ensure placeholders and punctuation match the en-US
equivalents and keep the {{ date | numeric('ru-RU') }} and {{ plan }} tokens
intact.
Description
Checklist
pnpm test
runs as expected.pnpm build
runs as expected.Type of change
Summary by CodeRabbit