React useScript Hook
React useScript hook for dynamic script loading. Load third-party libraries with status tracking, caching, and error handling using TypeScript for Next.js.
Struggling with dynamic script loading?
Join our Discord community for help from other developers.
Ever tried to load external scripts in React and ended up with document.createElement chaos, duplicate script loading nightmares, or broken loading state management? You know the drill—manually creating script tags, forgetting to check if scripts already exist, dealing with loading state tracking, handling cleanup on unmount. This free open source React useScript custom hook handles all that dynamic script loading complexity so you can focus on building features instead of debugging third-party integration edge cases in your React applications.
useScript showcase
Smart script loading with automatic caching and status tracking:
This free open source React hook simplifies external script integration with TypeScript support for modern JavaScript applications. Whether you're loading analytics SDKs, payment gateways, or social widgets in your Next.js projects, this React hook keeps your script loading reliable and performant.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/use-script.json
npx shadcn@latest add https://www.shadcn.io/registry/use-script.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-script.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-script.json
Why most script loading implementations suck
Look, you could keep manually creating script elements and managing loading states. But then you hit the script loading complexity—duplicate script tags cluttering the DOM, missed loading events, race conditions with multiple components, broken cleanup causing memory leaks in React applications.
Most developers manually create script tags with document.createElement() without proper deduplication, leading to the same script being loaded multiple times in TypeScript components. Or they forget to track loading states properly, causing race conditions when multiple components need the same script. Some skip cleanup entirely and wonder why their third-party scripts accumulate memory leaks when components unmount in Next.js projects.
This React hook uses optimized script management under the hood, with automatic caching to prevent duplicate loads and shared status across components in JavaScript applications. The browser handles all the script loading, plus you get comprehensive error handling and cleanup options in one call.
Plus it handles all the edge cases—SSR compatibility with proper hydration, script deduplication across components, automatic status sharing, proper event listener cleanup in React development. No more scattered script tags or broken third-party integrations.
This free open source React hook manages script state while you focus on building features. Whether you're creating React applications, Next.js dashboards, or TypeScript components, reliable script loading keeps your JavaScript development smooth.
Features
- Dynamic script loading with automatic status tracking and comprehensive error handling in React applications
- Script caching preventing duplicate loads and sharing status across components in TypeScript components
- Loading state management providing idle, loading, ready, and error states in Next.js projects
- Cleanup options with configurable script removal on component unmount in JavaScript development
- SSR compatibility with proper server-side rendering support and hydration safety for React frameworks
- TypeScript support with comprehensive type definitions and status enums in modern applications
- Free open source designed for modern React development workflows
When you'll actually use this
Real talk—this isn't for every external resource in React applications. Static assets in your build process handle most script needs perfectly. But when you need dynamic third-party integration with conditional loading or runtime script management, this React hook delivers in Next.js projects.
Perfect for:
- Analytics and tracking - Load Google Analytics, Mixpanel, or custom tracking conditionally built with TypeScript
- Payment processing - Load Stripe, PayPal, or payment gateway SDKs when needed using React patterns
- Social integrations - Load Twitter embeds, Facebook widgets, or social sharing on demand in JavaScript applications
- CDN libraries - Load utility libraries, polyfills, or fallback scripts dynamically in React components
- A/B testing tools - Load experiment scripts based on user segments or conditions in Next.js applications
- Chat widgets - Load customer support, Intercom, or help desk scripts conditionally using TypeScript safety
API Reference
useScript
useScript(
src: string | null,
options?: UseScriptOptions
): UseScriptStatus
Parameter | Type | Description |
---|---|---|
src | string | null | Script source URL (null prevents loading) |
options | UseScriptOptions | Configuration options for script loading |
UseScriptOptions
Property | Type | Default | Description |
---|---|---|---|
id | string | undefined | Script element ID for identification and deduplication |
removeOnUnmount | boolean | false | Remove script from DOM when component unmounts |
shouldPreventLoad | boolean | false | Prevent script loading regardless of src value |
UseScriptStatus
Status | Description | Use Case |
---|---|---|
'idle' | Script not loaded, waiting to start or prevented | Show initial state or loading trigger |
'loading' | Script is currently being downloaded | Show loading spinner or skeleton |
'ready' | Script loaded successfully and is available | Enable script-dependent features |
'error' | Script failed to load due to network or other error | Show error message or fallback |
Common gotchas
Script caching is global: All components using the same URL share the same loading status in React applications. The first component to load a script determines the state for all others. This prevents duplicate requests but means error states are also shared.
Third-party scripts can affect performance: The React hook itself is lightweight, but the scripts you load can significantly impact your app in TypeScript components. Use conditional loading to delay non-essential scripts and monitor third-party performance.
Security is your responsibility: Dynamically loaded scripts have full page access just like static scripts in Next.js projects. Only load from trusted domains and implement proper Content Security Policy headers.
SSR returns 'idle' initially: Scripts only load after client hydration, so handle the case where global objects from scripts aren't available yet during SSR in JavaScript applications.
Script load timing varies: External scripts may load at different speeds based on network conditions in React frameworks. Always handle loading states gracefully to avoid broken functionality.
Global namespace pollution: Third-party scripts may modify global objects in TypeScript projects. Consider defensive programming practices to avoid conflicts with your application code.
Related hooks you will also like
useIsClient
Client detection needed for safe script loading and global access
useBoolean
Toggle state management for script-dependent feature enablement
useLocalStorage
Persistent storage for script preferences and consent management
useEventListener
Event handling for script load callbacks and interactions
useIsMounted
Mount state checking for safe script initialization
useDebounceCallback
Debounced callbacks for script-dependent operations
Questions you might have
React useScreen Hook
React useScreen hook for screen information tracking. Monitor display dimensions, orientation, and capabilities with TypeScript support for Next.js apps.
React useScrollLock Hook
React useScrollLock hook for scroll prevention. Lock document or element scrolling with layout shift prevention and automatic cleanup using TypeScript for Next.js.