Skip to content

Commit bb520d6

Browse files
authored
fix: changing the language of the admin panel does not work for "radio" and "select" fields. (#14569)
Plugin-defined label functions (e.g., `label: ({ t }) => t('plugin-redirects:internalLink')`) don't update when switching languages. ## Root Cause The global Payload config was being **mutated**. When `createClientField` copied the `options` array by reference, it would evaluate label functions and replace them with strings in the global config. Subsequent requests would find strings instead of functions and couldn't re-evaluate. ## Why PR #11725 Wasn't Enough [PR #11725](#11725) fixed the client config cache to store separate configs per language, but didn't prevent the source config from being mutated. ## Solution **File**: `packages/payload/src/fields/config/client.ts` - Skip copying `options` in the default case - Create a fresh array in the radio/select handler instead of reusing the reference - This prevents mutating the global config while still evaluating labels correctly per language ## Testing The testing is located at #14569, which depends on this PR. You can see that the new tests there pass because they already contain this commit. I originally created it into a different PR because CI was failing and I wasn't sure if it was due to this change. Now I've left them separate for traceability and clarity. The other pull request is a feature, this one is a fix.
1 parent 6789939 commit bb520d6

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

packages/payload/src/fields/config/client.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ export const createClientField = ({
226226
// Skip - we handle sub-fields in the switch below
227227
break
228228

229+
case 'options':
230+
// Skip - we handle options in the radio/select switch below to avoid mutating the global config
231+
break
232+
229233
case 'label':
230234
//@ts-expect-error - would need to type narrow
231235
if (typeof incomingField.label === 'function') {
@@ -342,18 +346,23 @@ export const createClientField = ({
342346
const field = clientField as RadioFieldClient | SelectFieldClient
343347

344348
if (incomingField.options?.length) {
349+
field.options = [] // Create new array to avoid mutating global config
350+
345351
for (let i = 0; i < incomingField.options.length; i++) {
346352
const option = incomingField.options[i]
347353

348354
if (typeof option === 'object' && typeof option.label === 'function') {
349-
if (!field.options) {
350-
field.options = []
351-
}
352-
353355
field.options[i] = {
354356
label: option.label({ i18n, t: i18n.t as TFunction }),
355357
value: option.value,
356358
}
359+
} else if (typeof option === 'object') {
360+
field.options[i] = {
361+
label: option.label,
362+
value: option.value,
363+
}
364+
} else if (typeof option === 'string') {
365+
field.options[i] = option
357366
}
358367
}
359368
}

0 commit comments

Comments
 (0)