Skip to content
Switch branches/tags


Failed to load latest commit information.
Latest commit message
Commit time

React Async Script Loader

Build Status npm version npm downloads

*NOTE - These are the docs for the upcoming 1.0.0 release - for v0.11.1 documention go to tag here: 0.11.1

A React HOC for loading 3rd party scripts asynchronously. This HOC allows you to wrap a component that needs 3rd party resources, like reCAPTCHA or Google Maps, and have them load the script asynchronously.


Async Script HOC api

makeAsyncScriptLoader(getScriptUrl, options)(Component)

  • Component: The Component to wrap.
  • getScriptUrl: string or function that returns the full URL of the script tag.
  • options (optional):
    • attributes: object : If the script needs attributes (such as data- attributes), then provide them as key/value pairs of strings and they will be added to the generated script tag.
    • callbackName: string : If the script needs to call a global function when finished loading (for example: recaptcha/api.js?onload=callbackName). Please provide the callback name here and it will be autoregistered on window for you.
    • globalName: string : Can provide the name of the global that the script attaches to window. Async-script will pass this as a prop to the wrapped component. (props[globalName] = window[globalName])
    • removeOnUnmount: boolean default=false : If set to true removes the script tag when component unmounts.
    • scriptId: string : If set, it adds the following id on the script tag.

HOC Component props

const AsyncScriptComponent = makeAsyncScriptLoader(URL)(Component);
// ---
<AsyncScriptComponent asyncScriptOnLoad={callAfterScriptLoads} />
  • asyncScriptOnLoad: function : called after script finishes loading. using script.onload

Ref and forwardRef

react-async-script uses react's forwardRef method to pass along the ref applied to the wrapped component.

If you pass a ref prop you'll have access to your wrapped components instance. See the tests for detailed example.

Simple Example:

const AsyncHoc = makeAsyncScriptLoader(URL)(ComponentNeedsScript);

class DisplayComponent extends React.Component {
  constructor(props) {
    this._internalRef = React.createRef();
  componentDidMount() {
    console.log("ComponentNeedsScript's Instance -", this._internalRef.current);
  render() { return (<AsyncHoc ref={this._internalRef} />)}
Notes on Requirements

At least React@16.4.1 is required due to forwardRef usage internally.



// recaptcha.js
export class ReCAPTCHA extends React.Component {
  componentDidUpdate(prevProps) {
    // recaptcha has loaded via async script
    if (!prevProps.grecaptcha && this.props.grecaptcha) {
  render() { return (
    <div ref={(r) => this._container = r} />)

// recaptcha-wrapper.js
import makeAsyncScriptLoader from "react-async-script";
import { ReCAPTCHA } from "./recaptcha";

const callbackName = "onloadcallback";
const URL = `${callbackName}&render=explicit`;
// the name of the global that recaptcha/api.js sets on window ie: window.grecaptcha
const globalName = "grecaptcha";

export default makeAsyncScriptLoader(URL, {
  callbackName: callbackName,
  globalName: globalName,

// main.js
import ReCAPTCHAWrapper from "./recaptcha-wrapper.js"

const onLoad = () => console.log("script loaded")

  <ReCAPTCHAWrapper asyncScriptOnLoad={onLoad} />,

Migration to 1.0

  • Component is now passed as a second function call
  • removeOnMount is now removeOnUnmount (typo fixed!)
  • exposeFuncs is no longer needed as it's done automatically!
-export default makeAsyncScriptLoader(ReCAPTCHA, getURL, {
+export default makeAsyncScriptLoader(getURL, {
-  removeOnMount: initialOptions.removeOnMount || false,
+  removeOnUnmount: initialOptions.removeOnUnmount || false,
-  exposeFuncs: ["getValue", "getWidgetId", "reset", "execute"],


Pre 1.0.0 and - React < React@16.4.1 support details in 0.11.1.