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 MyComponent
add 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>
.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
{text</div>
</div>
;
)
}
export default MyStyledComponent
add 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'>
.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
{text</div>
</div>
;
)
}
export default EmojiComponent
add 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'>
.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
{text</div>
</div>
;
)
}
export default RandomWordsComponent
add 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 MyNestedComponent
add 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 true
Results 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: _resources
Gotchas
- 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 preview
orquarto render
will 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
md
andqmd
other extensions might work but have not been tested.