From e4a6d2dfc808c68149b5b68e113e875dadb02071 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 1 Mar 2026 13:50:42 +0000 Subject: [PATCH] Fix renderStrComponent with same eager-eval pattern as renderComponentDOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The string renderer's component call had the same deferred-evaluation bug — and this is the path actually used for blog card rendering via renderToString. Apply the same _isRenderExpr check to route render-only forms through renderStr while data expressions go through sxEval. Co-Authored-By: Claude Opus 4.6 --- shared/static/scripts/sx.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/shared/static/scripts/sx.js b/shared/static/scripts/sx.js index 83fa866..43e27c4 100644 --- a/shared/static/scripts/sx.js +++ b/shared/static/scripts/sx.js @@ -1110,10 +1110,18 @@ var i = 0; while (i < args.length) { if (isKw(args[i]) && i + 1 < args.length) { + // Evaluate kwarg values eagerly in the caller's env so expressions + // like (get t "src") resolve while lambda params are still bound. + // Render-only forms (HTML tags, <>, ~comp) go through renderStr. var v = args[i + 1]; - kwargs[args[i].name] = (typeof v === "string" || typeof v === "number" || - typeof v === "boolean" || isNil(v) || isKw(v)) - ? v : (isSym(v) ? sxEval(v, env) : v); + if (typeof v === "string" || typeof v === "number" || + typeof v === "boolean" || isNil(v)) { + kwargs[args[i].name] = v; + } else if (_isRenderExpr(v)) { + kwargs[args[i].name] = new RawHTML(renderStr(v, env)); + } else { + kwargs[args[i].name] = sxEval(v, env); + } i += 2; } else { children.push(args[i]); i++; } }