From 5efce2f9051598090c4c71b56d0dcf17c8bff0a4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 19 Sep 2026 07:05:45 +0000 Subject: [PATCH] fix: let the app's `htmlAttributes`/`bodyAttributes` take precedence over the ones set by Vike extensions For cumulative settings, `getHeadSetting()` returned the values in the order Vike provides them (most specific value first, values set by Vike extensions last) followed by the values set by `useConfig()`, and the tag attributes were merged in that order with the last value winning upon conflict. Consequently, upon conflict, a value set by a Vike extension would override the app's value, and a value set by `+config.js` would override the value set by `+htmlAttributes.js`. `getHeadSetting()` now returns the values of cumulative settings sorted by increasing precedence (values set by Vike extensions first, the app's most specific value last, then the values set by `useConfig()`), so that merging them in order yields the value with the highest precedence. Values set by `useConfig()` keep the highest precedence. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01MdJwhUKSfXPVuSvXyxBpr7 --- packages/vike-react/src/integration/getHeadSetting.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/vike-react/src/integration/getHeadSetting.tsx b/packages/vike-react/src/integration/getHeadSetting.tsx index d63a79c9..2a2eaaf0 100644 --- a/packages/vike-react/src/integration/getHeadSetting.tsx +++ b/packages/vike-react/src/integration/getHeadSetting.tsx @@ -23,9 +23,13 @@ function getHeadSetting( if (valFromHook !== undefined) return valFromHook as any return getCallable(valFromConfig) as any } else { + // Sorted by increasing precedence: the values set by Vike extensions come first, then the app's values (the most + // specific one last), then the values set by useConfig(). Merging the list in order (e.g. with Object.assign()) + // thus yields the value with the highest precedence. return [ - // - ...((valFromConfig as any) ?? []).map(getCallable), + // pageContext.config[configName] is sorted by decreasing precedence (the most specific value first, the values set + // by Vike extensions last) => we reverse it. (We copy the list first: pageContext.config is shared.) + ...[...((valFromConfig as any) ?? [])].reverse().map(getCallable), ...((valFromHook as any) ?? []), ] as any }