diff --git a/.changeset/rude-humans-marry.md b/.changeset/rude-humans-marry.md new file mode 100644 index 000000000..f36db03bf --- /dev/null +++ b/.changeset/rude-humans-marry.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix text not rendered on ssr diff --git a/packages/slate-react/src/components/string.tsx b/packages/slate-react/src/components/string.tsx index b77b14672..7bd09c988 100644 --- a/packages/slate-react/src/components/string.tsx +++ b/packages/slate-react/src/components/string.tsx @@ -61,6 +61,10 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { const ref = useRef(null) + const getTextContent = () => { + return `${text ?? ''}${isTrailing ? '\n' : ''}` + } + // This is the actual text rendering boundary where we interface with the DOM // The text is not rendered as part of the virtual DOM, as since we handle basic character insertions natively, // updating the DOM is not a one way dataflow anymore. What we need here is not reconciliation and diffing @@ -72,7 +76,7 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { // useLayoutEffect: updating our span before browser paint useIsomorphicLayoutEffect(() => { // null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime - const textWithTrailing = `${text ?? ''}${isTrailing ? '\n' : ''}` + const textWithTrailing = getTextContent() if (ref.current && ref.current.textContent !== textWithTrailing) { ref.current.textContent = textWithTrailing @@ -82,6 +86,16 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { // as this effectively replaces "specifying the text in the virtual DOM under the below" on each render }) + // Render text content immediately if it's the first-time render + // Ensure that text content is rendered on server-side rendering + if (!ref.current) { + return ( + + {getTextContent()} + + ) + } + // the span is intentionally same on every render in virtual DOM, actual rendering happens in the layout effect above return }