Repository navigation
feat(leptos): SSR of the initial document + render-mode-neutral adapter - #9
Merged
Merged
Conversation
Closes the last deferred v0.6 candidate from the roadmap: the Leptos adapter can now be used in SSR/hydrate apps, and the initial document is real HTML in the server response. - taino-edit-leptos no longer force-enables leptos/csr (feature unification made downstream SSR apps impossible); the app now picks exactly one render mode, like any Leptos component library. Browser tests keep csr via a wasm32-scoped dev-dependency. - New taino_edit_dom::doc_view_html (re-exported by the adapter): a host-safe, web-sys-free serializer emitting exactly the markup EditorView::mount builds — trailing <br> caret anchors in empty textblocks, <span> for to_dom-less nodes, browser-style void elements. TRAILING_BREAK_ATTR and is_textblock moved to view_html and shared with view.rs so the two can never drift. - <TainoEditor> now renders the initial doc as a one-shot (deliberately non-reactive) inner_html snapshot: the SSR payload and the CSR first paint. The pre-hydration document is not contenteditable on purpose — edits typed before the editor boots would be lost to the mount swap. - Contract pinned by tests: 6 host unit tests (incl. byte-parity with Node::to_html for plain content), a headless-Chromium parse-equality test (serializer output vs mounted DOM), and a first-paint component test (doc visible pre-effect, read-only, no duplication after mount). - examples/ssr-leptos: axum + cargo-leptos SSR/hydration demo in its own cargo workspace (leptos csr and ssr/hydrate cannot share a feature graph), with a host test asserting the server HTML embeds the serialized initial document byte-for-byte. New ssr-example CI job gates fmt + clippy(ssr) + clippy(hydrate, wasm32) + the SSR test. - Docs: README SSR section (+ stale v0.5.2 status fixed), CHANGELOG Unreleased entry, ROADMAP SSR item closed and stale v0.1.0 "Up next" replaced with the v0.6.0 hand-off. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ships the roadmap's deferred "Server-side rendering of the initial document (Leptos SSR)" item — the recommended v0.6 candidate. Two halves:
taino-edit-leptosis now render-mode neutral. It used to hard-enableleptos/csr, which cargo's feature unification propagated into every downstream app — making SSR apps impossible to build against the adapter. The library now enables no mode; the app picks exactly one ofcsr/hydrate/ssr(as with every Leptos component library). The browser test-suite keepscsrvia a wasm32-scoped dev-dependency.<TainoEditor>server-renders the initial document. The component's view now carries a one-shotinner_htmlsnapshot of the initial doc, produced by the new host-safetaino_edit_dom::doc_view_html. Under SSR that snapshot is the server payload (content visible + indexable before any wasm); under CSR it improves first paint. The pre-hydration document is deliberately notcontenteditable— edits typed before the editor boots would be lost to the mount swap. It is also deliberately non-reactive: after mount,EditorViewowns that subtree.doc_view_htmlemits exactly the markupEditorView::mountbuilds, including the trailing<br>caret anchor in empty textblocks (no visual jump on hydration),<span>forto_dom-less nodes, and browser-style void-element emission.TRAILING_BREAK_ATTR/is_textblockmoved into the new module and are shared withview.rs, so serializer and renderer cannot drift.New example:
examples/ssr-leptosFull axum +
cargo leptosSSR/hydration demo, in its own cargo workspace (Leptos'scsrandssr/hydratemodes cannot share one feature graph; the root workspace's demos arecsr).curl http://127.0.0.1:3000shows the document in the response HTML.CI
New
ssr-examplejob: fmt,clippy --features ssr,clippy --lib --target wasm32-unknown-unknown --features hydrate, and the SSR render test.Tests
doc_view_html, incl. byte-parity withNode::to_htmlfor plain content (pins escaping/attr order to core).innerHTMLboth sides) for a fixture covering heading attrs, nested marks, escaped text, a void<img>atom, an empty textblock, and a transparent node.doc_view_html(initial_doc)byte-for-byte and contains nocontenteditable.-D warnings) and the full wasm-bindgen browser matrix fortaino-edit-dom+taino-edit-leptos.Docs
README (SSR section, render-mode note, example listed, stale "v0.5.2 released" fixed), CHANGELOG
[Unreleased], ROADMAP (SSR item closed with date; stale "Up next: Release v0.1.0" replaced with the v0.6.0 hand-off + post-v0.6 candidates).🤖 Generated with Claude Code