@hsfx/attr
v2.0.29
Published
Auto-initializing JavaScript library for Webflow sites with animations, accessibility, and utility functions.
Readme
@hsfx/attr
Auto-initializing JavaScript library for Webflow sites with animations, accessibility, and utility functions.
Installation
Standard Installation
<script type="module" src="https://cdn.jsdelivr.net/npm/@hsfx/attr@2/dist/main.js"></script>
<script>!function(){history.scrollRestoration='manual';let e=[];window.hsfx||(window.hsfx={ready:t=>e.push(t)});!function t(){window.hsfx.loaded?e.forEach(e=>{try{e()}catch{}}):window.hsfx.ready&&Array.isArray(window.hsfx)?e.forEach(e=>window.hsfx.ready(e)):setTimeout(t,50)}()}()</script>Next.js Installation
<Script src="https://cdn.jsdelivr.net/npm/@hsfx/attr@2/dist/main.js" strategy="afterInteractive" data-hs-wf-off />
<script dangerouslySetInnerHTML={{ __html: `!function(){history.scrollRestoration='manual';let e=[];window.hsfx||(window.hsfx={ready:t=>e.push(t)});!function t(){window.hsfx.loaded?e.forEach(e=>{try{e()}catch{}}):window.hsfx.ready&&Array.isArray(window.hsfx)?e.forEach(e=>window.hsfx.ready(e)):setTimeout(t,50)}()}()` }} />Local Development
<!-- Local testing (run: npm run dev) -->
<script type="module" src="http://localhost:5173/index.ts"></script>
<script>!function(){history.scrollRestoration='manual';let e=[];window.hsfx||(window.hsfx={ready:t=>e.push(t)});!function t(){window.hsfx.loaded?e.forEach(e=>{try{e()}catch{}}):window.hsfx.ready&&Array.isArray(window.hsfx)?e.forEach(e=>window.hsfx.ready(e)):setTimeout(t,50)}()}()</script>Inline Helper Script
The inline script ensures window.hsfx is available for external scripts:
<script>!function(){history.scrollRestoration='manual';let e=[];window.hsfx||(window.hsfx={ready:t=>e.push(t)});!function t(){window.hsfx.loaded?e.forEach(e=>{try{e()}catch{}}):window.hsfx.ready&&Array.isArray(window.hsfx)?e.forEach(e=>window.hsfx.ready(e)):setTimeout(t,50)}()}()</script>What it does:
- Creates a temporary
window.hsfx.ready()shim immediately - Queues callbacks from external scripts before hsfx loads
- Polls for real hsfx to load
- Flushes queued callbacks to real hsfx when ready
- Guarantees external scripts can use
window.hsfx.ready()safely
SPA Mode
For Barba.js, Swup, etc.: Add data-hs-spa="true" to the module loader
<script type="module" src="https://cdn.jsdelivr.net/npm/@hsfx/attr@2/dist/main.js" data-hs-spa="true"></script>
<script>!function(){history.scrollRestoration='manual';let e=[];window.hsfx||(window.hsfx={ready:t=>e.push(t)});!function t(){window.hsfx.loaded?e.forEach(e=>{try{e()}catch{}}):window.hsfx.ready&&Array.isArray(window.hsfx)?e.forEach(e=>window.hsfx.ready(e)):setTimeout(t,50)}()}()</script>Configuration
// Example: Barba.js integration
barba.hooks.before(() => {
window.dispatchEvent(new CustomEvent('hsfx:transition-exit'));
});
barba.hooks.after(() => {
window.dispatchEvent(new CustomEvent('hsfx:transition-enter'));
});API Usage
External Script Integration
When using external scripts & libraries (Barba.js, GSAP ScrollTrigger, etc.) that need to wait for hsfx to be ready, the inline helper script (included with standard installation) ensures window.hsfx is available.
External scripts should use the callback pattern:
<script>
window.hsfx.ready(() => {
// Your code here - guaranteed to run when hsfx is fully loaded
});
</script>Why this works:
The inline helper script creates a temporary window.hsfx.ready() shim immediately, so external scripts can safely call it even before the real hsfx library loads. Callbacks are queued and then flushed to the real hsfx when initialization completes.
Cleanup
// Destroy all modules (useful for SPA navigation)
window.hsfx.destroy();
// Reinitialize everything
await window.hsfx.reinitialize();Manual Module Loading
// Load a single module
window.hsfx.load('counter');
// With callback
window.hsfx.push([
'counter',
() => {
console.log('Counter module ready');
},
]);Lifecycle Hooks
// Execute code after all modules load
window.hsfx.ready(() => {
console.log('Library fully initialized');
});
// Check module status
const status = window.hsfx.status('counter');
console.log(status); // { loaded: true, loading: false }Modal Manager & Lenis Integration
Modal manager automatically detects and handles Lenis smooth scroll (stops on modal open, starts on close).
// Auto-detection works with zero config
// Just use modals normally - Lenis is handled automatically
// Disable auto Lenis handling if needed
window.hsfx.modal.setLenisEnabled(false);
// Manual modal control
window.hsfx.modal.open();
window.hsfx.modal.close();
// Custom callbacks (run in addition to auto Lenis handling)
window.hsfx.modal.onOpen(() => {
console.log('Modal opened');
});
window.hsfx.modal.onClose(() => {
console.log('Modal closed');
});jsDelivr Cache Purge
After publishing to npm, go to https://www.jsdelivr.com/tools/purge and paste:
https://cdn.jsdelivr.net/npm/@hsfx/attr@2Architecture
- TypeScript: Full type safety with TypeScript source
- Vite Bundled: Optimized build with code splitting (~24kb gzipped total)
- Config-driven: Centralized configuration in
config.json - SPA Compatible: Works with Barba.js, Swup, and other routers
- Memory Safe: Proper cleanup tracking for observers and event handlers
- Phase-based Loading: Optimized initialization sequence
