Skip to content

Commit df6fefd

Browse files
authored
fix(clerk-js): Call setActive after closing checkout drawer (#5916)
1 parent 041ac68 commit df6fefd

File tree

9 files changed

+63
-29
lines changed

9 files changed

+63
-29
lines changed

.changeset/full-bushes-heal.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/types': minor
3+
---
4+
5+
Add `onClose` to `__internal_CheckoutProps`.

.changeset/long-bananas-agree.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
Bug fix: Call `setActive` after closing Checkout to ensure RSCs re-render with the new auth context.
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
import { PricingTable } from '@clerk/nextjs';
1+
import { PricingTable, Protect } from '@clerk/nextjs';
22

33
export default async function PricingTablePage({
44
searchParams,
55
}: {
66
searchParams: Promise<{ newSubscriptionRedirectUrl: string }>;
77
}) {
88
const newSubscriptionRedirectUrl = (await searchParams).newSubscriptionRedirectUrl;
9-
return <PricingTable newSubscriptionRedirectUrl={newSubscriptionRedirectUrl} />;
9+
return (
10+
<>
11+
<Protect plan='free_user'>
12+
<p>user in free</p>
13+
</Protect>
14+
<Protect plan='pro'>
15+
<p>user in pro</p>
16+
</Protect>
17+
<Protect plan='plus'>
18+
<p>user in plus</p>
19+
</Protect>
20+
<PricingTable newSubscriptionRedirectUrl={newSubscriptionRedirectUrl} />
21+
</>
22+
);
1023
}

integration/tests/pricing-table.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl
6262
await u.po.checkout.fillTestCard();
6363
await u.po.checkout.clickPayOrSubscribe();
6464
await expect(u.po.page.getByText('Payment was successful!')).toBeVisible();
65+
await u.po.checkout.confirmAndContinue();
66+
67+
// eslint-disable-next-line playwright/no-conditional-in-test
68+
if (app.name.includes('next')) {
69+
// Correctly updates RSCs with the new `pla` claim.
70+
await expect(u.po.page.getByText('user in plus')).toBeVisible({
71+
timeout: 5_000,
72+
});
73+
}
6574
});
6675

6776
test('can upgrade to a new plan with saved card', async ({ page, context }) => {

packages/clerk-js/bundlewatch.config.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"files": [
33
{ "path": "./dist/clerk.js", "maxSize": "595.5kB" },
4-
{ "path": "./dist/clerk.browser.js", "maxSize": "68.5KB" },
4+
{ "path": "./dist/clerk.browser.js", "maxSize": "68.4KB" },
55
{ "path": "./dist/clerk.legacy.browser.js", "maxSize": "110KB" },
66
{ "path": "./dist/clerk.headless*.js", "maxSize": "52KB" },
7-
{ "path": "./dist/ui-common*.js", "maxSize": "105KB" },
7+
{ "path": "./dist/ui-common*.js", "maxSize": "104.7KB" },
88
{ "path": "./dist/vendors*.js", "maxSize": "39.5KB" },
99
{ "path": "./dist/coinbase*.js", "maxSize": "38KB" },
1010
{ "path": "./dist/createorganization*.js", "maxSize": "5KB" },
@@ -13,7 +13,7 @@
1313
{ "path": "./dist/organizationswitcher*.js", "maxSize": "5KB" },
1414
{ "path": "./dist/organizationlist*.js", "maxSize": "5.5KB" },
1515
{ "path": "./dist/signin*.js", "maxSize": "14KB" },
16-
{ "path": "./dist/signup*.js", "maxSize": "7.5KB" },
16+
{ "path": "./dist/signup*.js", "maxSize": "7.4KB" },
1717
{ "path": "./dist/userbutton*.js", "maxSize": "5KB" },
1818
{ "path": "./dist/userprofile*.js", "maxSize": "16.5KB" },
1919
{ "path": "./dist/userverification*.js", "maxSize": "5KB" },

packages/clerk-js/src/ui/Components.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,18 @@ const Components = (props: ComponentsProps) => {
372372
};
373373

374374
componentsControls.closeDrawer = name => {
375-
setState(s => ({
376-
...s,
377-
[`${name}Drawer`]: {
378-
...s[`${name}Drawer`],
379-
open: false,
380-
},
381-
}));
375+
setState(s => {
376+
const currentItem = s[`${name}Drawer`];
377+
// @ts-expect-error `__internal_PlanDetailsProps` does not accept `onClose`
378+
currentItem?.props?.onClose?.();
379+
return {
380+
...s,
381+
[`${name}Drawer`]: {
382+
...s[`${name}Drawer`],
383+
open: false,
384+
},
385+
};
386+
});
382387
};
383388

384389
componentsControls.prefetch = component => {

packages/clerk-js/src/ui/components/Checkout/useCheckout.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ClerkAPIResponseError } from '@clerk/shared/error';
22
import { useClerk, useOrganization, useUser } from '@clerk/shared/react';
33
import type { __internal_CheckoutProps, CommerceCheckoutResource } from '@clerk/types';
4-
import { useCallback, useEffect, useState } from 'react';
4+
import { useEffect, useState } from 'react';
55

66
import { useFetch } from '../../hooks/useFetch';
77

@@ -10,7 +10,6 @@ export const useCheckout = (props: __internal_CheckoutProps) => {
1010
const clerk = useClerk();
1111
const { organization } = useOrganization();
1212
const [currentCheckout, setCurrentCheckout] = useState<CommerceCheckoutResource | null>(null);
13-
1413
const { user } = useUser();
1514
const {
1615
data: initialCheckout,
@@ -31,10 +30,6 @@ export const useCheckout = (props: __internal_CheckoutProps) => {
3130

3231
const error = _error as ClerkAPIResponseError | undefined;
3332

34-
const updateCheckout = useCallback((newCheckout: CommerceCheckoutResource) => {
35-
setCurrentCheckout(newCheckout);
36-
}, []);
37-
3833
useEffect(() => {
3934
if (initialCheckout && !currentCheckout) {
4035
setCurrentCheckout(initialCheckout);
@@ -43,7 +38,7 @@ export const useCheckout = (props: __internal_CheckoutProps) => {
4338

4439
return {
4540
checkout: currentCheckout || initialCheckout,
46-
updateCheckout,
41+
updateCheckout: setCurrentCheckout,
4742
isLoading,
4843
invalidate,
4944
revalidate,

packages/clerk-js/src/ui/contexts/components/Plans.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useClerk, useOrganization, useUser } from '@clerk/shared/react';
1+
import { useClerk, useOrganization, useSession, useUser } from '@clerk/shared/react';
22
import type {
33
Appearance,
44
CommercePlanResource,
@@ -142,6 +142,7 @@ type HandleSelectPlanProps = {
142142

143143
export const usePlansContext = () => {
144144
const clerk = useClerk();
145+
const { session } = useSession();
145146
const subscriberType = useSubscriberTypeContext();
146147
const context = useContext(PlansContext);
147148

@@ -344,27 +345,27 @@ export const usePlansContext = () => {
344345
portalRoot,
345346
});
346347
} else {
347-
// if the plan doesn't support annual, use monthly
348-
let _planPeriod = planPeriod;
349-
if (planPeriod === 'annual' && plan.annualMonthlyAmount === 0) {
350-
_planPeriod = 'month';
351-
}
352-
353348
clerk.__internal_openCheckout({
354349
planId: plan.id,
355-
planPeriod: _planPeriod,
356-
subscriberType: subscriberType,
350+
// if the plan doesn't support annual, use monthly
351+
planPeriod: planPeriod === 'annual' && plan.annualMonthlyAmount === 0 ? 'month' : planPeriod,
352+
subscriberType,
357353
onSubscriptionComplete: () => {
358354
ctx.revalidate();
359355
onSubscriptionChange?.();
360356
},
357+
onClose: () => {
358+
if (session?.id) {
359+
void clerk.setActive({ session: session.id });
360+
}
361+
},
361362
appearance,
362363
portalRoot,
363364
newSubscriptionRedirectUrl,
364365
});
365366
}
366367
},
367-
[clerk, ctx, activeOrUpcomingSubscription, subscriberType],
368+
[clerk, ctx, activeOrUpcomingSubscription, subscriberType, session?.id],
368369
);
369370

370371
const defaultFreePlan = useMemo(() => {

packages/types/src/clerk.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,7 @@ export type __internal_CheckoutProps = {
16211621
* @default undefined
16221622
*/
16231623
newSubscriptionRedirectUrl?: string;
1624+
onClose?: () => void;
16241625
};
16251626

16261627
export type __internal_PlanDetailsProps = {

0 commit comments

Comments
 (0)