Fix stepper SSR/hydration flash: server reads cookie, cache bypass
Three changes to eliminate the stepper flash: 1. home-stepper.sx: server path reads cookie via (get-cookie) for step-idx initial value. Client path reads document.cookie via def-store. Both default to 0 when no cookie exists. 2. sx_server.ml: bypass response cache when sx-home-stepper cookie is present. Render on main thread (not worker) so get-cookie sees the parsed request cookies. 3. site-full.spec.js: flash detection test sets cookie=7 via Playwright context, checks SSR HTML matches hydrated state. Test: "No flash: SSR=7 hydrated=7 (cookie=7)" — passes. Tested on fresh stack=site server subprocess. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3040,8 +3040,10 @@ let http_mode port =
|
||||
in
|
||||
write_response fd response; true
|
||||
end else if is_sx then begin
|
||||
let has_state_cookie = Hashtbl.mem _request_cookies "sx-home-stepper" in
|
||||
let cache_key = if is_ajax then "ajax:" ^ path else path in
|
||||
match Hashtbl.find_opt response_cache cache_key with
|
||||
match (if has_state_cookie then None
|
||||
else Hashtbl.find_opt response_cache cache_key) with
|
||||
| Some cached -> write_response fd cached; true
|
||||
| None ->
|
||||
if is_ajax then begin
|
||||
@@ -3062,6 +3064,18 @@ let http_mode port =
|
||||
(escape_sx_string (Printexc.to_string e)))
|
||||
in
|
||||
write_response fd response; true
|
||||
end else if has_state_cookie then begin
|
||||
(* State cookie present — render on main thread so get-cookie works.
|
||||
Don't cache: response varies by cookie value. *)
|
||||
let response =
|
||||
try match http_render_page env path [] with
|
||||
| Some body -> http_response body
|
||||
| None -> http_response ~status:404 "<h1>Not Found</h1>"
|
||||
with e ->
|
||||
Printf.eprintf "[render] Cookie render error for %s: %s\n%!" path (Printexc.to_string e);
|
||||
http_response ~status:500 "<h1>Error</h1>"
|
||||
in
|
||||
write_response fd response; true
|
||||
end else begin
|
||||
(* Full page: queue to render worker *)
|
||||
Mutex.lock render_mutex;
|
||||
|
||||
Reference in New Issue
Block a user