# JSX import LiveCodes from '../../src/components/LiveCodes.tsx'; import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx'; [JSX](https://react.dev/learn/writing-markup-with-jsx) is a syntax extension for JavaScript that allows writing HTML-like markup inside JavaScript. It has been popularized by [React](https://react.dev/), and then adopted by many other libraries/frameworks. By default, when running JSX in LiveCodes, [React](https://react.dev/) runtime is used. However, other libraries like [Preact](https://preactjs.com/), [nano JSX](https://nanojsx.io/) and others can be used as well (see [Custom JSX Runtimes](#custom-jsx-runtimes)). TSX is also supported in LiveCodes and is [documented here](./tsx.html.md). Please note that [React compiler](https://react.dev/learn/react-compiler) is also available in LiveCodes and is [documented here](./react.html.md). ## Usage The easiest way is to [auto-render](#auto-rendering) a component by exporting it as the [default export](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#using_the_default_export): export const basicJsxDemo = { jsx: `export default function App() {\n return

Hello World!

;\n}`, }; You may, however, be more explicit and render the component yourself using [React DOM](https://react.dev/reference/react-dom/client): export const reactDomDemo = { jsx: `import { createRoot } from "react-dom/client";\n\nfunction App() {\n return

Hello World!

;\n}\n\nconst root = createRoot(document.querySelector("#root"));\nroot.render();`, html: `
`, }; :::info note React's [new JSX transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) is utilized. So there is no need to import React. ```jsx // this is not needed: // import React from 'react'; export default function App() { return

Hello World!

; } ``` ::: ### Auto-rendering A component is rendered automatically as a React component (without having to manually use React Dom to render it) if the following conditions are met: - The component is exported as the default export. - No custom JSX runtime is used (see [Custom JSX Runtimes](#custom-jsx-runtimes)). - No [imports from `"./script"`](#exports) in markup editor. - Auto-rendering is not [disabled](#disabling-auto-rendering). #### Root Element To render the React components to a specific [root](https://react.dev/reference/react-dom/client/createRoot) DOM element use `"livecodes-app"` as the element `id`. Otherwise, if that element is not found, a new `div` element is added to `document.body` and is used as the root. Example: export const rootDemo = { html: `
Loading...
`, jsx: `export default function App() {\n return

Hello World!

;\n}`, }; #### Disabling Auto-rendering To disable auto-rendering, set the [custom settings](#custom-settings) `disableAutoRender` property to `true`. export const disableAutoRenderDemo = { markup: { language: 'html', content: `JSX auto-rendering is disabled. Set from Project menu → Custom Settings.`, }, script: { language: 'jsx', content: `export default function App() {\n return

Hello World!

;\n}`, }, customSettings: { jsx: { disableAutoRender: true } }, }; ### Importing Modules npm modules can be imported as described in the section about [module resolution](../features/module-resolution.html.md), including bare module imports and importing from different CDNs. Stylesheet imports are added as `` tags in the page `head`. Example: export const importsDemo = { jsx: `import { useState, useEffect } from "react";\nimport confetti from "canvas-confetti";\nimport "bootstrap/dist/css/bootstrap.css";\n\nexport default function App() {\n const [count, setCount] = useState(0);\n\n useEffect(() => {\n if (count > 0) {\n confetti();\n }\n }, [count]);\n\n return (\n
\n

You clicked {count} times.

\n \n
\n );\n}\n`, }; Module imports can be customized using import maps as described in [module resolution](../features/module-resolution.html.md)#custom-module-resolution) documentations. #### Types for Imported Modules Types for imported modules are loaded automatically (if available) to provide [Intellisense](../features/intellisense.html.md), auto-completion and type information. ![LiveCodes Intellisense](../../static/img/screenshots/intellisense-1.jpg) ![LiveCodes Intellisense](../../static/img/screenshots/intellisense-2.jpg) Moreover, you can provide custom type definitions for modules that do not have types available on npm. See [Custom Types](../features/intellisense.html.md)#custom-types) for details. ### Exports Values exported from script editor (default or named) can be imported in the markup editor by importing from `"./script"` (with no extension). This can be useful, for example, when using [MDX](./mdx.html.md) to import components exported form JSX. Demo: export const exportsDemo = { mdx: `import Greeting from "./script";\n\n\n`, jsx: `export default function(props) {\n return

Greeting from {props.name}!

;\n}\n`, }; :::info note When values are imported from `"./script"`, [auto-rendering](#auto-rendering) is disabled, because it is assumed that you want to take control over component rendering. ::: ### Styles CSS can be applied to the component using various ways: #### Style Editor Styles added in the style editor is applied globally to the [result page](../features/result.html.md). This can use different **languages/processors** supported in LiveCodes including CSS, SCSS, Less, Stylus, ..etc. See [style documentation](../features/css.html.md) for more details. And of course, styles and stylesheets added in markup editor are also applied globally. #### Importing Stylesheets Stylesheets imported in script editor are added as `` tags in the page `head`. The stylesheet URL can be an absolute URL or a path in the npm package. The URL has to end with `".css"`. example: export const stylesDemo = { jsx: `import "bootstrap/dist/css/bootstrap.css";\n\nexport default () =>

Hello World!

;\n`, }; #### CSS Modules CSS modules are supported and are [documented separately](./cssmodules.html.md). Make sure to enable CSS modules (from style editor menu or in [`processors`](../configuration/configuration-object.html.md)#processors) property of [configuration object](../configuration/configuration-object.html.md)). Demo: export const cssModulesDemo = { activeEditor: 'script', style: { language: 'css', content: `.title {\n color: green;\n font-family: sans-serif;\n}\n` }, script: { language: 'jsx', content: `import classes from './style.module.css';\n\nexport default function() {\n return

Hello, CSS Modules!

;\n}\n`, }, processors: ['cssmodules'], }; #### CSS Frameworks [CSS Frameworks](../features/css.html.md)#css-processors) supported in LiveCodes (e.g. [Tailwind CSS](./tailwindcss.html.md), [UnoCSS](./unocss.html.md), [WindiCSS](./windicss.html.md)) can detect class names added in JSX. Make sure that the required utility is enabled (from style editor menu or in [`processors`](../configuration/configuration-object.html.md)#processors) property of [configuration object](../configuration/configuration-object.html.md)) and that required [directives](https://tailwindcss.com/docs/functions-and-directives#tailwind) are added to the style editor. Demo: export const tailwindcssDemo = { activeEditor: 'script', style: { language: 'css', content: `@tailwind base;\n@tailwind components;\n@tailwind utilities;\n`, }, script: { language: 'jsx', content: `export default function() {\n return

Hello, Tailwind CSS!

;\n}\n`, }, processors: ['tailwindcss'], }; #### CSS-in-JS CSS-in-JS libraries can be imported and used as usual. Demo: export const styledComponentsDemo = { jsx: `import styled from 'styled-components';\n\nconst Title = styled.h1\`\n text-align: center;\n font-family: sans-serif;\n color: palevioletred;\n\`;\n\nexport default function () {\n return Hello, styled-components!;\n}\n`, }; ### Custom JSX Runtimes LiveCodes allows using other libraries (like [Preact](https://preactjs.com/) and [nano JSX](https://nanojsx.io/)) as the JSX runtime. JSX is compiled to JavaScript using the TypeScript compiler, which allows multiple configuration options for JSX, including [`jsx`](https://www.typescriptlang.org/tsconfig#jsx), [`jsxFactory`](https://www.typescriptlang.org/tsconfig#jsxFactory), [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory) and [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource). These can be configured using in-code pragmas or in [custom settings](#custom-settings). Example for using Preact: export const preactDemo = { jsx: `/** @jsx h */\nimport { h, render } from 'preact';\n\nconst App = (props) =>

Hello, {props.name}

;\n\nrender(, document.body);\n`, }; :::info note [Auto-rendering](#auto-rendering) is disabled for custom JSX runtimes. ::: ## Language Info ### Name `jsx` ### Extension `.jsx` ### Editor `script` ## Compiler [TypeScript compiler](./typescript.html.md) ## Code Formatting Using [Prettier](https://prettier.io/). ## Custom Settings [Custom settings](../advanced/custom-settings.html.md) added to the property `jsx` are passed to the TypeScript compiler as [compiler options](https://www.typescriptlang.org/tsconfig#compilerOptions) while compiling JSX. In addition, the option `disableAutoRender` can be set to `true` to disable [auto-rendering](#auto-rendering). Please note that custom settings should be valid JSON (i.e. functions are not allowed). **Example:** ```json title="Custom Settings" { "jsx": { "disableAutoRender": true, "jsxFactory": "h", "jsxFragmentFactory": "Fragment" } } ``` ## Links - [React](https://react.dev/) - [JSX](https://react.dev/learn/writing-markup-with-jsx)