From 8a5dfc93564a86d1474b1b72c85def4f40750b13 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:25:49 -0300 Subject: [PATCH 1/3] Hide slug field based on organization settings --- .../OrganizationProfile/ProfileForm.tsx | 35 ++++++++++++------- .../__tests__/ProfileSettingsPage.test.tsx | 25 +++++++++++++ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx index 225c6f9af40..9dc893610ae 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx @@ -1,6 +1,8 @@ import { useOrganization } from '@clerk/shared/react'; +import type { UpdateOrganizationParams } from '@clerk/types'; import React from 'react'; +import { useEnvironment } from '@/ui/contexts'; import { useCardState, withCardStateProvider } from '@/ui/elements/contexts'; import { Form } from '@/ui/elements/Form'; import { FormButtons } from '@/ui/elements/FormButtons'; @@ -20,6 +22,7 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => { const title = localizationKeys('organizationProfile.profilePage.title'); const card = useCardState(); const { organization } = useOrganization(); + const { organizationSettings } = useEnvironment(); const nameField = useFormControl('name', organization?.name || '', { type: 'text', @@ -39,14 +42,20 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => { const dataChanged = organization.name !== nameField.value || organization.slug !== slugField.value; const canSubmit = dataChanged && slugField.feedbackType !== 'error'; + const organizationSlugEnabled = !organizationSettings.slug.disabled; const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); - return (canSubmit ? organization.update({ name: nameField.value, slug: slugField.value }) : Promise.resolve()) - .then(onSuccess) - .catch(err => { - handleError(err, [nameField, slugField], card.setError); - }); + + const updateOrgParams: UpdateOrganizationParams = { name: nameField.value, slug: slugField.value }; + + if (organizationSlugEnabled) { + updateOrgParams.slug = slugField.value; + } + + return (canSubmit ? organization.update(updateOrgParams) : Promise.resolve()).then(onSuccess).catch(err => { + handleError(err, [nameField, slugField], card.setError); + }); }; const uploadAvatar = (file: File) => { @@ -92,13 +101,15 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => { ignorePasswordManager /> - - - + {organizationSlugEnabled && ( + + + + )} { it('updates organization slug on clicking continue', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withOrganizations(); + f.withOrganizationSlug(true); f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: [{ name: 'Org1', slug: '', role: 'admin' }], @@ -91,4 +92,28 @@ describe('OrganizationProfileScreen', () => { await userEvent.click(getByRole('button', { name: /save$/i })); expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1', slug: 'my-org' }); }); + + it("does not display slug field if it's disabled on environment", async () => { + const { wrapper, fixtures } = await createFixtures(f => { + f.withOrganizations(); + f.withOrganizationSlug(false); + f.withUser({ + email_addresses: ['test@clerk.com'], + organization_memberships: [{ name: 'Org1', slug: '', role: 'admin' }], + }); + }); + + fixtures.clerk.organization?.update.mockResolvedValue({} as OrganizationResource); + const { getByDisplayValue, queryByLabelText, userEvent, getByRole } = render( + , + { wrapper }, + ); + expect(getByDisplayValue('my-org')).toBeDefined(); + expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument(); + await userEvent.click(getByRole('button', { name: /save$/i })); + expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1', slug: 'my-org' }); + }); }); From a0c5272d3dafb0f8f956297224e88b6a655f0a0e Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:26:34 -0300 Subject: [PATCH 2/3] Add changeset --- .changeset/quick-trams-sink.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/quick-trams-sink.md diff --git a/.changeset/quick-trams-sink.md b/.changeset/quick-trams-sink.md new file mode 100644 index 00000000000..1ee8a927fe2 --- /dev/null +++ b/.changeset/quick-trams-sink.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Hide slug field on `OrganizationProfile` based on environment settings From 46146e39b7e85bb4f89374ac4e5fa5e49945f675 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Thu, 16 Oct 2025 10:54:06 -0300 Subject: [PATCH 3/3] Remove slug param from request payload --- .../ui/components/OrganizationProfile/ProfileForm.tsx | 2 +- .../__tests__/OrganizationGeneralPage.test.tsx | 1 + .../__tests__/ProfileSettingsPage.test.tsx | 9 ++++----- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx index 9dc893610ae..03f94ae7bf1 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/ProfileForm.tsx @@ -47,7 +47,7 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => { const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); - const updateOrgParams: UpdateOrganizationParams = { name: nameField.value, slug: slugField.value }; + const updateOrgParams: UpdateOrganizationParams = { name: nameField.value }; if (organizationSlugEnabled) { updateOrgParams.slug = slugField.value; diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationGeneralPage.test.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationGeneralPage.test.tsx index d435592a0c5..cd83d4b271b 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationGeneralPage.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationGeneralPage.test.tsx @@ -246,6 +246,7 @@ describe('OrganizationSettings', () => { it('open the profile section', async () => { const { wrapper } = await createFixtures(f => { f.withOrganizations(); + f.withOrganizationSlug(true); f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: [{ name: 'Org1', slug: 'Org1' }], diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/ProfileSettingsPage.test.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/ProfileSettingsPage.test.tsx index 354f1c4c697..62d1568fbe3 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/ProfileSettingsPage.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/ProfileSettingsPage.test.tsx @@ -66,7 +66,7 @@ describe('OrganizationProfileScreen', () => { await userEvent.type(getByLabelText(/^name/i), '234'); expect(getByDisplayValue('Org1234')).toBeDefined(); await userEvent.click(getByRole('button', { name: /save/i })); - expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1234', slug: '' }); + expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1234' }); }); it('updates organization slug on clicking continue', async () => { @@ -99,21 +99,20 @@ describe('OrganizationProfileScreen', () => { f.withOrganizationSlug(false); f.withUser({ email_addresses: ['test@clerk.com'], - organization_memberships: [{ name: 'Org1', slug: '', role: 'admin' }], + organization_memberships: [{ name: 'Org1', role: 'admin' }], }); }); fixtures.clerk.organization?.update.mockResolvedValue({} as OrganizationResource); - const { getByDisplayValue, queryByLabelText, userEvent, getByRole } = render( + const { queryByLabelText, userEvent, getByRole } = render( , { wrapper }, ); - expect(getByDisplayValue('my-org')).toBeDefined(); expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument(); await userEvent.click(getByRole('button', { name: /save$/i })); - expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1', slug: 'my-org' }); + expect(fixtures.clerk.organization?.update).toHaveBeenCalledWith({ name: 'Org1' }); }); });