@samitouri / QOS-React-2 / commits / 0d1fdb5c2e

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.

Sebastian Markbåge committed Jun 28, 2024 at 15:35 UTC 0d1fdb5c2ebdbde03c8f6b5dcb4058dc715ffb0a
3 files changed +27 -8
packages/react-html/src/ReactFizzConfigHTML.js
+2 -8
@@ -36,14 +36,7 @@ export const isPrimaryRenderer = false;
36 // Disable Client Hooks
37 export const supportsClientAPIs = false;
38
39 -import {
40 - stringToChunk,
41 - stringToPrecomputedChunk,
42 -} from 'react-server/src/ReactServerStreamConfig';
43 -
44 -// this chunk is empty on purpose because we do not want to emit the DOCTYPE
45 -// when markup is rendering HTML
46 -export const doctypeChunk: PrecomputedChunk = stringToPrecomputedChunk('');
39 +import {stringToChunk} from 'react-server/src/ReactServerStreamConfig';
40
41 export type {
42 RenderState,
@@ -81,6 +74,7 @@ export {
74 resetResumableState,
75 completeResumableState,
76 emitEarlyPreloads,
77 + doctypeChunk,
78 } from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
79
80 import escapeTextForBrowser from 'react-dom-bindings/src/server/escapeTextForBrowser';
packages/react-html/src/__tests__/ReactHTMLClient-test.js
+11
@@ -28,6 +28,17 @@ describe('ReactHTML', () => {
28 expect(html).toBe('<div>hello world</div>');
29 });
30
31 + it('should prefix html tags with a doctype', async () => {
32 + const html = await ReactHTML.renderToMarkup(
33 + <html>
34 + <body>hello</body>
35 + </html>,
36 + );
37 + expect(html).toBe(
38 + '<!DOCTYPE html><html><head></head><body>hello</body></html>',
39 + );
40 + });
41 +
42 it('should error on useState', async () => {
43 function Component() {
44 const [state] = React.useState('hello');
packages/react-html/src/__tests__/ReactHTMLServer-test.js
+14
@@ -38,6 +38,20 @@ describe('ReactHTML', () => {
38 expect(html).toBe('<div>hello world</div>');
39 });
40
41 + it('should prefix html tags with a doctype', async () => {
42 + const html = await ReactHTML.renderToMarkup(
43 + // We can't use JSX because that's client-JSX in our tests.
44 + React.createElement(
45 + 'html',
46 + null,
47 + React.createElement('body', null, 'hello'),
48 + ),
49 + );
50 + expect(html).toBe(
51 + '<!DOCTYPE html><html><head></head><body>hello</body></html>',
52 + );
53 + });
54 +
55 it('should error on useState', async () => {
56 function Component() {
57 const [state] = React.useState('hello');