jsx というのは javascript の構文に xml っぽい構文を取り入れたjsにトランスパイル必須の言語です。
例えばこういうコードがあった場合
jsx
1<div></div>;
2<h1>hi</h1>;
3<Component/>;
4<Component {...props} />;
5<Component {...props} prop="a"/>;
6<Component prop="a" key="b" />;
7
8const profile = (
9 <>
10 <img src="avatar.png" className="profile" />
11 <h3>{[user.firstName, user.lastName].join(" ")}</h3>
12 </>
13);
こういうコードになるので
js
1import { jsxs as _jsxs } from "react/jsx-runtime";
2import { Fragment as _Fragment } from "react/jsx-runtime";
3import { jsx as _jsx } from "react/jsx-runtime";
4
5// change the code here!!
6// runtime "automatic" adds imports, will be default in Babel 8
7// importSource defaults to "react"
8
9/*#__PURE__*/
10_jsx("div", {});
11
12/*#__PURE__*/
13_jsx("h1", {
14 children: "hi"
15});
16
17/*#__PURE__*/
18_jsx(Component, {});
19
20/*#__PURE__*/
21_jsx(Component, { ...props
22});
23
24/*#__PURE__*/
25_jsx(Component, { ...props,
26 prop: "a"
27});
28
29/*#__PURE__*/
30_jsx(Component, {
31 prop: "a"
32}, "b");
33
34const profile = /*#__PURE__*/_jsxs(_Fragment, {
35 children: [/*#__PURE__*/_jsx("img", {
36 src: "avatar.png",
37 className: "profile"
38 }), /*#__PURE__*/_jsx("h3", {
39 children: [user.firstName, user.lastName].join(" ")
40 })]
41});
最終結果には 全くxml構文は出てきません。 javascript からの DOM操作です。
その為DOM操作のできる html であれば XHTML でも HTML でも 問題無いかと思われます。
参考:
New JSX Transform Playground
https://new-jsx-transform.netlify.app/
追伸1
jsx は XML like な記法 なので 最終結果としては DOMを生成して 既にある document にマウントするものでしかないので 挿入先の document が SGML ベースとか XML ベースとかは DOMが使えるか使えないかでしかないので関係無いと思われます。( html でも xhtml でも DOM は使える為)
追伸2
https://ja.react.dev/reference/react-dom/server/renderToReadableStream#rendering-a-react-tree-as-html-to-a-readable-web-stream
reactの仕様書に<!DOCTYPE html>を見つけたので、doctypeはこれで合ってる...?JSXとマークアップルールについては見つけられませんでした。
とありますが、その参照しているのは
React は doctype とあなたが指定した ブートストラップ <script> タグ
を結果の HTML ストリームに注入します。
html
1<!DOCTYPE html>
2<html>
3 <!-- ... HTML from your components ... -->
4</html>
5<script src="/main.js" async=""></script>
と jsx ではなく html です。それはマウント先の html の話です。