Skip to content

Repository files navigation

react-render-props-script-loader

CircleCICoverage StatusCommitizen friendlynpm version

an easier to use dynamic script loader with a render prop and now a React custom hook.

This is useful if you want to wait to load the Google Maps API until the user navigates to a view that uses it. When you mount a <ScriptLoader> component, it will create the script tag you've requested.

<ScriptLoader> doesn't load a given script URL more than once, even if there is a pre-existing <script> tag for that URL that it didn't create. If src prop changes, it will load that new URL.

Version notes

  • if building for legacy browsers with a bundler like Webpack that supports the module field of package.json, you will probably need to add a rule to transpile this package.

Installation

npm install --save react-render-props-script-loader

Example

import*asReactfrom'react'importScriptLoaderfrom'react-render-props-script-loader'importMapViewfrom'./MapView'exportconstMapViewContainer=(props)=>(<ScriptLoadertype="text/javascript"src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"onLoad={()=>console.log('loaded google maps!')}onError={(error)=>console.error('failed to load google maps:',error.stack)}>{({ loading, error })=>{if(loading)return<h3>Loading Google Maps API...</h3>if(error)return<h3>Failed to load Google Maps API: {error.message}</h3>return<MapView{...props}/>}}</ScriptLoader>)

API

useScript(props: Props)

import{useScript}from'react-render-props-script-loader'

props.src (requiredstring)

The script URL.

props.onLoad (?() => any)

A callback that ScriptLoader will call once the script has been loaded

props.onError (?(error: Error) => any)

A callback that ScriptLoader will call if there was an error loading the script

Returns

A state object of the following type:

typeState={loading: booleanloaded: booleanerror: ?Errorpromise: ?Promise<any>}

ScriptLoader

importScriptLoaderfrom'react-render-props-script-loader'

src (requiredstring)

The script URL.

onLoad (?() => any)

A callback that ScriptLoader will call once the script has been loaded

onError (?(error: Error) => any)

A callback that ScriptLoader will call if there was an error loading the script

children (?(state: State) => ?React.Node)

The render function. It will be called with an object having the following props, and may return your desired content to display:

{loading: boolean,loaded: boolean,error: ?Error,promise: ?Promise<any>,}

Server-Side Rendering

import{ScriptsRegistry,ScriptsRegistryContext,}from'react-render-props-script-loader'

On the server, create an instance of ScriptsRegistry and put it on the app's context:

constregistry=newScriptsRegistry()constbody=ReactDOM.renderToString(<ScriptsRegistryContext.Providervalue={registry}><App/></ScriptsRegistryContext.Provider>)

Then render registry.scriptTags() in your head element:

consthtml=(<htmlclassName="default"><head>
...
{registry.scriptTags()}</head>
...
</html>)

Content Security Policy

Make sure your header includes this meta tag:

<metaproperty="csp-nonce"content={nonce}/>

And in SSR, pass the nonce to registry.scriptTags({ nonce }).

About

an easier to use React dynamic script loader with a render prop and SSR

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages