Last 12 weeks · 0 commits
3 of 6 standards met
Problem During SSR, a nullish child is interpolated into the tag as the literal string : If has not resolved when the shell flushes, the emitted HTML is: early-returns for non-string values, so gives back , which the template literal then stringifies. The unescaped branch already guarded against this with ; the escaped branch (used by ) did not. Fix Guard once at the call so both branches behave the same: rather than so that and still render, which the previous unescaped branch dropped. Verification (15 passed), and all clean. Also verified end to end in a SolidStart 2.0 app, on a route whose `createAsyncundefinedundefineddeferStreamcreateAsyncgenerate: 'dom'renderTags` has no SSR coverage to extend, and the most recent change to this function (3cbd12c) was likewise source-only. Happy to add an SSR test config if you would like one. Fixes #73.
Summary During SSR, a nullish child passed to a closing meta element is serialized as literal text. In particular, produces instead of an empty title. This is the current, framework-independent core of solidjs/solid-start#1881. The reproduction does not use SolidStart, routing, prerendering, or asynchronous data. Reproduction https://github.com/birkskyum/repro-solid-meta-nullish-ssr Minimal component: Actual Expected Cause passes the nullish value through and then interpolates the result into a template literal. returns , which template interpolation converts to the string . Normalizing the result of with before choosing the escaped or unescaped branch avoids stringifying both and , while preserving valid falsy values such as and . Scope This issue is specifically about serialization of a nullish value. If a title depends on asynchronous route data, the render must still wait for that data (for example with ). The correct output for data that is still unresolved when the shell flushes is an empty title, not the literal word . Versions Related older falsy-title report: #26 Downstream report: https://github.com/solidjs/solid-start/issues/1881 Proposed fix: #71
Summary Dynamic JSX children in can shift hydration IDs between SSR and the client when a hydratable sibling follows it. The server-rendered sibling is then left unclaimed. Reproduction Using , , and : The server emits the paragraph under hydration ID , but the corresponding client computation runs under . Hydration reports: The async title is outside , so it correctly holds the initial stream. The warning remains even when all serialized query and fragment records are settled before hydration. Root cause leaves body evaluation inside the deferred descriptor getter: For , the JSX compiler places a memo for the dynamic child inside the getter. On the client, the effect evaluates that getter during component rendering, before the sibling boundary. On the server, the getter is deferred until head flush, after the sibling boundary has already received its ID. Proposed fix Create one memo for body content when runs, then read it from the deferred descriptor: This preserves deferred head flushing while allocating the reactive owner at the same position on the server and client. I verified that the boundary ID aligns, the production build succeeds, the root async title still holds the stream, and hydration completes without unclaimed nodes.
Repository: solidjs/solid-meta. Description: Write meta tags to the document head Stars: 158, Forks: 23. Primary language: TypeScript. Languages: TypeScript (96.2%), JavaScript (3.8%). Open PRs: 5, open issues: 26. Last activity: 1w ago. Community health: 62%. Top contributors: ryansolid, nksaraf, davedbase, github-actions[bot], ArnabXD, birkskyum, GoodbyeNJN, JakkuSakura, dennev, indeyets and others.