I'm torn where the best place for this question to go but when researching the React crossorigin purpose I found the answer on MDN:

Normal script elements pass minimal information to the window.onerror for scripts which do not pass the standard CORS checks. To allow error logging for sites which use a separate domain for static media, use this attribute. See CORS settings attributes for a more descriptive explanation of the valid arguments.


and in looking at using ReactDOM I've seen the script tags at the bottom of:

<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script>window.ReactDOM || document.write('<script crossorigin src="path/to/react-dom.development.js"><\/script>')</script>

In WordPress I am familiar with a basic enqueue:

function theme_js() {
    wp_enqueue_script( 'bootstrap_js', get_template_directory_uri() . '/js/bootstrap.min.js', array( 'jquery' ), '1.0', true );
add_action( 'wp_enqueue_scripts', 'theme_js' );

and with WordPress I've attached scripts to the footer with:

function inline_script() {
    <script type="text/javascript">
    // js code goes here
add_action( 'wp_footer', 'inline_script' );

When running a query through previous questions with the params of [wordpress] crossorigin I didn't see this question asked. Is there a proper way to code for ReactDOM in a WordPress theme besides calling it in the footer with something like:

function react_dom() {
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script>window.ReactDOM || document.write('<script crossorigin src=" <?php get_template_directory_uri() ?>/react-dom.development.js"><\/script>')</script>
add_action( 'wp_footer', 'react_dom' );

How should ReactDOM be wp_enqueue_scripts or should it be added to the footer?

For reference this was mentioned in chat: How to add defer=“defer” tag in plugin javascripts?

  • I'm voting to close this as "primarily opinion-based". As far as I know you can't simply add crossorigin to the <script> tag, so I'd just do it manually in the footer as you've shown in your last code example
    – kero
    Commented May 2, 2018 at 16:29

1 Answer 1


So I'm thinking you can use the script_loader_tag filter to replace HTML as the script is being loaded in. This will allow you to control where you're enqueueing the script as usual via wp_enqueue_scripts hook while still allowing you to add in any script attributes.

The Enqueue

 * Enqueue whatever script we may need
 * @return void
function wpse302526_enqueue_react() {

        'react',    // File handle/slug
        $file_url,      // URL to file
        array(),        // Dependencies
        false,          // Version
        true            // Add to Header ( false ) or Footer ( true )

add_action( 'wp_enqueue_scripts', 'wpse302526_enqueue_react' );

We'll target the script specifically by the handle/script slug.

The Find / Replace

 * Modify the enqueue script tag
 * @param String $html      - Generated script HTML
 * @param String $handle    - Script slug/handle
 * @return $html
function wpse302526_modify_script_tags( $html, $handle ) {

    /** Add script attribute **/
    if( 'react' === $handle ) {

        /* Add `crossorigin` attribute */
        $html = str_replace(
            '<script crossorigin',

        /* Initialize ReactDOM */
        $html = str_replace(


    return $html;

add_filter( 'script_loader_tag', 'wpse302526_modify_script_tags', 10, 2 );

I feel like if you can you should avoid doing this part outside your enqueue as it could be confusing to any developers who run across it. Keeping all your enqueues and script URLs in one place ( instead of torn between the two filters ) seems for the best. If you can't avoid it then feel free to add it in.

document.write('<script crossorigin src=" <?php get_template_directory_uri() ?>/react-dom.development.js"><\/script>')

If you absolutely need the above line, then I would go with the wp_footer approach to keep everything in one place.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.