Qreacto
Run standalone React components in your Quarto project!
Getting started
Create your component
function MyComponent() {    
    const [text, setText] = React.useState(['Click me'])
    return (
      <div onClick={() => setText((previous) => [previous, ...[' and me']])}>
        <p>{text.map(value => <span>{value}</span>)} </p>
      </div>
    );
  }
export default MyComponentadd it to your markdown file with {{< react MyComponent >}}
and see the results:
Add styles
Create your component, with the styles imported
import './style.css';
function MyStyledComponent() {    
    const [text, setText] = React.useState([])
    return (
      <div onClick={() => setText((previous) => [...previous, ' and this one'])}>
        <div className='styled-component-container'>
          <span className='wrapper-for-other-component'>Click this one</span> 
          {text.map(value => <span className='wrapper-for-other-component'>{value}</span>)} 
        </div>
      </div>
    );
  }
export default MyStyledComponentadd it to your markdown file with {{< react MyStyledComponent >}}
and see the results:
Import local scripts
Create your component, with the scripts imported
import './style.css';
import getRandomEmoji from './emojiservice'; // we are importing a script here
function EmojiComponent() {    
    const [text, setText] = React.useState([getRandomEmoji()])
    return (
      <div onClick={() => setText((previous) => [...previous, getRandomEmoji()])}>
        <div className='styled-component-container'>          
          {text.map(value => <span className='wrapper-for-other-component'>{value}</span>)} 
        </div>
      </div>
    );
  }
export default EmojiComponentadd it to your markdown file with {{< react EmojiComponent >}}
and see the results:
Import thirdparty scripts
Create your component, with thirdparty scripts imported.
Any CDN that supports ESM packages can be used, like jsDelivr
import './style.css';
import * as randomWords from 'https://cdn.jsdelivr.net/npm/random-words/+esm'; // we are importing a thirdparty script here
function RandomWordsComponent() {
    const [text, setText] = React.useState([randomWords.generate({ maxLength: 8 })])
    return (
      <div onClick={() => setText((previous) => [...previous, randomWords.generate({ maxLength: 8 })])}>
        <div className='styled-component-container'>          
          {text.map(value => <span className='wrapper-for-other-component'>{value}</span>)} 
        </div>
      </div>
    );
  }
export default RandomWordsComponentadd it to your markdown file with {{< react RandomWordsComponent >}}
and see the results:
Nesting components
Create your component with the nested components imported and in the jsx
import RandomWordsComponent from "./RandomWordsComponent";
import EmojiComponent from "./EmojiComponent";
function MyNestedComponent() {
    return (
      <div>
        <RandomWordsComponent/>
        <EmojiComponent/>
      </div>
    );
  }
export default MyNestedComponentadd it to your markdown file with {{< react MyNestedComponent >}} and see the results:
Using environment variables
Add your environment variables as specified on the official documentation Qreacto will pick up environment variables that begin with QREACTO_ They can then be accessed with process.env....โโโ
The enviornment file:
QREACTO_FOO=bar
QREACTO_TEST=Very trueResults in:
 {
  env: { 
      QREACTO_FOO:"bar"
      QREACTO_TEST:"Very true"
  }
 }and can be accessed with:
 console.log(process.env.QREACTO_FOO)
 console.log(process.env.QREACTO_TEST)Note Qreacto only looks for _environment files, not iterations of this file (eg _environment-dev, _environment-prod) ## Configuring
You can (optionally) specify the location for your components and resources
    react:
        components: _components
        resources: _resourcesGotchas
- Dont import react in your file import React from 'react'
- components should be placed in the _components/folder
- styles and supporting scripts should be placed in the _components/folder
- Changes to your component will not refresh quarto, quarto previeworquarto renderwill need to be called.
- Typescript is supported but is limited to babels transpilation support of TS. As such, it may not have the latest features you would expect
- Named imports are not currently supported import { NamedButton } from './Button';will not work butimport Button from './Button'will.
- Deep imports are not currently supported. components should be placed in the _components/folder.
- Works with mdandqmdother extensions might work but have not been tested.