A React hook for easily loading external JavaScript files asynchronously and managing their loading state.
You can install the package using npm or yarn:
npm:
npm install @n0n3br/react-use-lazy-script-loaderyarn:
yarn add @n0n3br/react-use-lazy-script-loaderHere's how to import and use the useLazyScriptLoader hook in your React component:
import React from "react";
import useLazyScriptLoader from "@n0n3br/react-use-lazy-script-loader";
function MyComponent() {
// Replace with the actual script URL you want to load
const SCRIPT_URL =
"https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap";
const { isLoading, isLoaded, error } = useLazyScriptLoader(SCRIPT_URL);
if (isLoading) {
return <p>Loading script...</p>;
}
if (error) {
return <p>Error loading script: {error.message}</p>;
}
if (isLoaded) {
// Example: Check if a global object (e.g., 'google') is available
// This depends on what the loaded script exposes.
if (window.google && window.google.maps) {
// Initialize map or other script-dependent logic here
// For example, if your script defines a function like initMap on window:
// if (typeof window.initMap === 'function') {
// window.initMap();
// }
return (
<p>
Google Maps script loaded successfully! You can now use
`window.google.maps`.
</p>
);
} else {
return (
<p>
Script loaded, but the expected global object (e.g., `window.google`)
was not found. Please check the script URL and its behavior.
</p>
);
}
}
return null; // Or some default/fallback UI
}
export default MyComponent;Note on Callbacks (e.g., Google Maps callback=initMap):
This hook focuses on loading the script file itself. If the script requires a global callback function to be defined before it executes (common with APIs like Google Maps), you'll need to ensure that callback function is defined on the window object before the useLazyScriptLoader hook successfully loads the script. The hook doesn't manage the creation of such callback functions.
scriptUrl(string, required): The full URL of the external JavaScript file to load.- If an empty string or falsy value is passed, the hook will set
isLoadingtofalseanderrorto anErrorobject.
- If an empty string or falsy value is passed, the hook will set
An object containing the following properties:
isLoading(boolean):trueif the script is currently being fetched.falseotherwise (i.e., if the script has loaded, failed, or ifscriptUrlwas invalid).
isLoaded(boolean):trueif the script has successfully loaded.falseotherwise.
error(Error | null):- An
Errorobject if script loading failed (e.g., network error, 404). Theerror.messagewill provide more details. nullif the script loaded successfully or is still loading.
- An
- Asynchronous Loading: Loads scripts without blocking the main thread.
- Duplicate Prevention: The same script URL is only fetched and added to the DOM once, even if multiple components use the hook with the same URL. The loading state is shared.
- Error Handling: Provides an
errorstate to inform your component if the script fails to load. - Automatic Cleanup: Script tags are automatically removed from the DOM when all components using that specific script URL have unmounted.
- Server-Side Rendering (SSR) Compatibility: Gracefully handles being run in non-browser environments (though script loading will only occur client-side).
- Re-renders & URL Changes: Handles re-renders and changes to the
scriptUrlprop correctly, loading new scripts and cleaning up old ones as needed.
This repository includes an example application built with Vite, React, and Tailwind CSS to demonstrate the usage of the useLazyScriptLoader hook.
To run the example app:
-
Navigate to the example directory:
cd example -
Install dependencies: This will install dependencies for the example app itself and also link the local
@n0n3br/react-use-lazy-script-loaderpackage from the root of the repository.npm install
-
Run the development server:
npm run dev
-
Open your browser and navigate to the URL provided by Vite (usually
http://localhost:5173or a similar port). Once the app is running, click the "Load Chart.js & Display Charts" button to trigger the script loading and see the charts.
This project is licensed under the MIT License. See the LICENSE file for details.