diff --git a/src/components/MDX/InlineCode.tsx b/src/components/MDX/InlineCode.tsx index d206e98883c..0e8db0165b3 100644 --- a/src/components/MDX/InlineCode.tsx +++ b/src/components/MDX/InlineCode.tsx @@ -5,7 +5,8 @@ import cn from 'classnames'; interface InlineCodeProps { - isLink: boolean; + isLink?: boolean; + meta?: string; } function InlineCode({ isLink, diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index 74ab788bac1..e12acc733e6 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -19,6 +19,7 @@ import Link from './Link'; import {PackageImport} from './PackageImport'; import Recap from './Recap'; import Sandpack from './Sandpack'; +import SandpackWithHTMLOutput from './SandpackWithHTMLOutput'; import Diagram from './Diagram'; import DiagramGroup from './DiagramGroup'; import SimpleCallout from './SimpleCallout'; @@ -432,6 +433,7 @@ export const MDXComponents = { Recap, Recipes, Sandpack, + SandpackWithHTMLOutput, TeamMember, TerminalBlock, YouWillLearn, diff --git a/src/components/MDX/Sandpack/createFileMap.ts b/src/components/MDX/Sandpack/createFileMap.ts index 6fc160c469b..a85059174a1 100644 --- a/src/components/MDX/Sandpack/createFileMap.ts +++ b/src/components/MDX/Sandpack/createFileMap.ts @@ -7,7 +7,10 @@ import type {SandpackFile} from '@codesandbox/sandpack-react/unstyled'; export const createFileMap = (codeSnippets: any) => { return codeSnippets.reduce( (result: Record, codeSnippet: React.ReactElement) => { - if ((codeSnippet.type as any).mdxName !== 'pre') { + if ( + (codeSnippet.type as any).mdxName !== 'pre' && + codeSnippet.type !== 'pre' + ) { return result; } const {props} = codeSnippet.props.children; diff --git a/src/components/MDX/SandpackWithHTMLOutput.tsx b/src/components/MDX/SandpackWithHTMLOutput.tsx new file mode 100644 index 00000000000..134da65897c --- /dev/null +++ b/src/components/MDX/SandpackWithHTMLOutput.tsx @@ -0,0 +1,85 @@ +import {Children, memo} from 'react'; +import InlineCode from './InlineCode'; +import Sandpack from './Sandpack'; + +const ShowRenderedHTML = ` +import { renderToStaticMarkup } from 'react-dom/server'; +import formatHTML from './formatHTML.js'; + +export default function ShowRenderedHTML({children}) { + const markup = renderToStaticMarkup( + + + {children} + + ); + return ( + <> +

Rendered HTML:

+
+        {formatHTML(markup)}
+      
+ + ); +}`; + +const formatHTML = ` +import format from 'html-format'; + +export default function formatHTML(markup) { + // Cheap tricks to format the HTML readably -- haven't been able to + // find a package that runs in browser and prettifies the HTML if it + // lacks line-breaks. + return format(markup + .replace('', '\\n') + .replace('', '\\n') + .replaceAll(/<\\/script>/g, '<\\/script>\\n') + .replaceAll(/]*)\\/>/g, ' +``` + + + + + +--- + +## Reference {/*reference*/} + +### ` +``` + +[See more examples below.](#usage) + +#### Props {/*props*/} + +` + + … + + + ); +} + +export default function App() { + return ( + + + + ); +} +``` + + diff --git a/src/content/reference/react-dom/components/title.md b/src/content/reference/react-dom/components/title.md new file mode 100644 index 00000000000..9d6ed18ccf7 --- /dev/null +++ b/src/content/reference/react-dom/components/title.md @@ -0,0 +1,98 @@ +--- +title: "" +canary: true +--- + +<Canary> + +React's extensions to `<title>` are currently only available in React's canary and experimental channels. In stable releases of React `<title>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React's release channels here](/community/versioning-policy#all-release-channels). + +</Canary> + + +<Intro> + +The [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) lets you specify the title of the document. + +```js +<title>My Blog +``` + + + + + +--- + +## Reference {/*reference*/} + +### `` {/*title*/} + +To specify the title of the document, render the [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). You can render `<title>` from any component and React will always place the corresponding DOM element in the document head. + +```js +<title>My Blog +``` + +[See more examples below.](#usage) + +#### Props {/*props*/} + +`` supports all [common element props.](/reference/react-dom/components/common#props) + +* `children`: `<title>` accepts only text as a child. This text will become the title of the document. You can also pass your own components as long as they only render text. + +#### Special rendering behavior {/*special-rendering-behavior*/} + +React will always place the DOM element corresponding to the `<title>` component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<title>` to exist within the DOM, yet it’s convenient and keeps things composable if a component representing a specific page can render its `<title>` itself. + +There are two exception to this: +* If `<title>` is within an `<svg>` component, then there is no special behavior, because in this context it doesn’t represent the document’s title but rather is an [accessibility annotation for that SVG graphic](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title). +* If the `<title>` has an [`itemProp`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/itemprop) prop, there is no special behavior, because in this case it doesn’t represent the document’s title but rather metadata about a specific part of the page. + +<Pitfall> + +Only render a single `<title>` at a time. If more than one component renders a `<title>` tag at the same time, React will place all of those titles in the document head. When this happens, the behavior of browsers and search engines is undefined. + +</Pitfall> + +--- + +## Usage {/*usage*/} + +### Set the document title {/*set-the-document-title*/} + +Render the `<title>` component from any component with text as its children. React will put a `<title>` DOM node in the document `<head>`. + +<SandpackWithHTMLOutput> + +```js App.js active +import ShowRenderedHTML from './ShowRenderedHTML.js'; + +export default function ContactUsPage() { + return ( + <ShowRenderedHTML> + <title>My Site: Contact Us +

Contact Us

+

Email us at support@example.com

+ + ); +} +``` + + + +### Use variables in the title {/*use-variables-in-the-title*/} + +The children of the `` component must be a single string of text. (Or a single number or a single object with a `toString` method.) It might not be obvious, but using JSX curly braces like this: + +```js +<title>Results page {pageNumber} // 🔴 Problem: This is not a single string +``` + +... actually causes the `` component to get a two-element array as its children (the string `"Results page"` and the value of `pageNumber`). This will cause an error. Instead, use string interpolation to pass `<title>` a single string: + +```js +<title>{`Results page ${pageNumber}`} +``` + diff --git a/src/sidebarReference.json b/src/sidebarReference.json index 315ea3e0b2e..08e0132afe4 100644 --- a/src/sidebarReference.json +++ b/src/sidebarReference.json @@ -218,6 +218,31 @@ { "title": "