Anki Forums

Can I use React in card templates?

I tried to test if JavaScript library “React” could be used in card templates. Here is my test code:

<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<div id="root"></div>

<script type="text/babel">
    ReactDOM.render(
      <h1>Hello, world!</h1>,
      document.getElementById('root')
    );
</script>

I expected the result to be “Hello, world!”, but the code produced an empty result. Can React be used in card templates? If yes, how?
My Anki version is ⁨2.1.38 (355e4cd5)⁩
Thanks.

I just tried using React in a card template, and it seems to work, but a few workarounds seems to be required to get it to work properly. Firstly, loading React files with <script src=""></script> seems not to work, so I think maybe dynamic loading of external js files is required. For example, see Linking to external javascript . In addition, maybe type="text/babel" doesn’t work, so you might need to run JSX Preprocessor from command line. The following is a script, which I modified to work on a card template on Anki, from the example source code in Add React to a Website page.

Template:

<div id="like_button_container"></div>
<!-- Load React component from "collection.media" folder. -->
<script src="_like_button.js"></script>
collection.media/_like_button.js
'use strict';

// This script is slightly modified from 
// https://gist.github.com/gaearon/6668a1f6986742109c00a581ce704605

var injectScript = (src) => {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.async = true;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
    });
};

(async () => {
    if (typeof React === 'undefined') {
        await Promise.all([
            injectScript('https://unpkg.com/react@17/umd/react.development.js'),
            injectScript('https://unpkg.com/react-dom@17/umd/react-dom.development.js')
        ])
    }
    const e = React.createElement;

    class LikeButton extends React.Component {
        constructor(props) {
            super(props);
            this.state = { liked: false };
        }

        render() {
            if (this.state.liked) {
                return 'You liked this.';
            }

            return e(
                'button',
                { onClick: () => this.setState({ liked: true }) },
                'Like'
            );
        }
    }

    const domContainer = document.querySelector('#like_button_container');
    ReactDOM.render(e(LikeButton), domContainer);
})();

Screenshot:

(Disclaimer: I have never used React before.)

4 Likes

Thanks!