useScript Deep Dive
The useScript hook is a universal tool for managing script injection in Archibald applications. It supports multiple loading strategies, SSR integration, and experimental features like Partytown.
- Loading Strategies
- SSR & Hydration
- Suspense Integration
- Partytown (Worker Strategy)
- How it Works Step-by-Step
Loading Strategies
The strategy parameter determines when and how the script is injected into the document.
afterInteractive (Default)
The script is injected on the client-side after the page has become interactive. It uses a MutationObserver to wait for hydration to complete before injection.
beforeHydration
The script is injected on the server-side during the initial render pass. It will be present in the HTML sent to the client, ensuring it runs as early as possible.
worker
Experimental strategy that leverages Partytown to run scripts in a Web Worker, offloading them from the main thread.
SSR & Hydration
useScript handles the transition between server-side rendering and client-side hydration.
- Server-Side: If
strategy: 'beforeHydration'is used, the script is added to theHeadContextand rendered in the<head>as part of the initial HTML. - Client-Side: For
afterInteractive, the hook waits for thedocument.bodyto stabilize using aMutationObserver. Once stabilized, the script is injected into the<body>. This prevents hydration mismatches and ensures scripts don't interfere with the initial React mount.
Suspense Integration
If suspense: true is provided (or enabled globally via DataClient), useScript will throw a Promise while the script is loading. This allows you to catch the loading state using a standard React Suspense boundary.
<Suspense fallback={<p>Loading analytics...</p>}>
<AnalyticsComponent />
</Suspense>
// Inside AnalyticsComponent:
useScript({
id: 'analytics',
src: 'https://example.com/script.js',
suspense: true
});
Partytown (Worker Strategy)
To use the worker strategy, you must have Partytown initialized in your application and enabled in the Archibald configuration:
// archibald.config.ts
export default {
experimental: {
partytown: true
}
}
The hook will verify that window.partytown is available before attempting to load the script.
How it Works Step-by-Step
Scenario: strategy: 'afterInteractive'
- Component Mounts: The hook initializes and sets up a
MutationObserverondocument.body. - Hydration Check: The hook waits for the DOM to settle (monitored via
observeHydrationChanges). - Script Check: The hook checks if a script with the same
idalready exists in the document to prevent duplicates. - Injection: A new
<script>element is created and injected into the<body>. - State Update: If using Suspense, a
DecoratedPromiseis created and "thrown" to the nearest boundary. - Load/Error Events: The hook listens for the native
loadanderrorevents of the script element and triggers the corresponding callbacks (onLoad,onError). - Cleanup: When the component unmounts, the
MutationObserveris disconnected, but the script remains in the document (unless manually removed via Script API).
Scenario: strategy: 'beforeHydration'
- Server Rendering: The hook detects it's running on the server.
- Context Injection: The script content is generated and added to the
HeadManager. - HTML Generation: The script is rendered into the
<head>as part of the initial server response (via{{ page.tags }}). - Client Hydration: The hook runs on the client but detects the script already exists via its
idand skips re-injection.