From 0d1fdb5c2ebdbde03c8f6b5dcb4058dc715ffb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Fri, 28 Jun 2024 15:35:12 +0200 Subject: [PATCH] Add doctype to renderToMarkup when html tags are rendered (#30122) Stacked on top of #30121. This is the same thing we do for `renderToReadableStream` so that you don't have to manually inject it into the stream. The only reason we didn't for `renderToString` / `renderToStaticMarkup` was to preserve legacy behavior but since this is a new API we can change that. If you're rendering a partial it doesn't matter. This is likely what you'd do for RSS feeds. The question is if you can reliably rely on the doctype being used while rendering e-mails since many clients are so quirky. However, if you're careful it also doesn't hurt so it seems best to include it. --- packages/react-html/src/ReactFizzConfigHTML.js | 10 ++-------- .../src/__tests__/ReactHTMLClient-test.js | 11 +++++++++++ .../src/__tests__/ReactHTMLServer-test.js | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/react-html/src/ReactFizzConfigHTML.js b/packages/react-html/src/ReactFizzConfigHTML.js index 81528b0cdb81c..0be7abe8bb0ad 100644 --- a/packages/react-html/src/ReactFizzConfigHTML.js +++ b/packages/react-html/src/ReactFizzConfigHTML.js @@ -36,14 +36,7 @@ export const isPrimaryRenderer = false; // Disable Client Hooks export const supportsClientAPIs = false; -import { - stringToChunk, - stringToPrecomputedChunk, -} from 'react-server/src/ReactServerStreamConfig'; - -// this chunk is empty on purpose because we do not want to emit the DOCTYPE -// when markup is rendering HTML -export const doctypeChunk: PrecomputedChunk = stringToPrecomputedChunk(''); +import {stringToChunk} from 'react-server/src/ReactServerStreamConfig'; export type { RenderState, @@ -81,6 +74,7 @@ export { resetResumableState, completeResumableState, emitEarlyPreloads, + doctypeChunk, } from 'react-dom-bindings/src/server/ReactFizzConfigDOM'; import escapeTextForBrowser from 'react-dom-bindings/src/server/escapeTextForBrowser'; diff --git a/packages/react-html/src/__tests__/ReactHTMLClient-test.js b/packages/react-html/src/__tests__/ReactHTMLClient-test.js index 4f052288a8403..36a44ebc6d21a 100644 --- a/packages/react-html/src/__tests__/ReactHTMLClient-test.js +++ b/packages/react-html/src/__tests__/ReactHTMLClient-test.js @@ -28,6 +28,17 @@ describe('ReactHTML', () => { expect(html).toBe('
hello world
'); }); + it('should prefix html tags with a doctype', async () => { + const html = await ReactHTML.renderToMarkup( + + hello + , + ); + expect(html).toBe( + 'hello', + ); + }); + it('should error on useState', async () => { function Component() { const [state] = React.useState('hello'); diff --git a/packages/react-html/src/__tests__/ReactHTMLServer-test.js b/packages/react-html/src/__tests__/ReactHTMLServer-test.js index ecb33c1c040d3..1a9976aafbd49 100644 --- a/packages/react-html/src/__tests__/ReactHTMLServer-test.js +++ b/packages/react-html/src/__tests__/ReactHTMLServer-test.js @@ -38,6 +38,20 @@ describe('ReactHTML', () => { expect(html).toBe('
hello world
'); }); + it('should prefix html tags with a doctype', async () => { + const html = await ReactHTML.renderToMarkup( + // We can't use JSX because that's client-JSX in our tests. + React.createElement( + 'html', + null, + React.createElement('body', null, 'hello'), + ), + ); + expect(html).toBe( + 'hello', + ); + }); + it('should error on useState', async () => { function Component() { const [state] = React.useState('hello');