{"_id":"@akson/landing-hooks","_rev":"4-a6772fcb2b28f7de650c6dd60d738276","name":"@akson/landing-hooks","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@akson/landing-hooks","version":"0.1.0","keywords":["akson","landing","react-hooks","device-detection","api-calls","form-submission","analytics","performance","image-preloader"],"author":{"name":"Akson"},"license":"MIT","_id":"@akson/landing-hooks@0.1.0","maintainers":[{"name":"antoineschaller","email":"antoine.schaller@akson.ch"}],"dist":{"shasum":"64c80164c3a49f9668d6a835fefe440ba8bbc6d7","tarball":"https://registry.npmjs.org/@akson/landing-hooks/-/landing-hooks-0.1.0.tgz","fileCount":33,"integrity":"sha512-RgX9dyjI7XNhQ19klqVq83NlGUdBePXVYbWwy4tmKTPGJEiUoy0KaWn5cASnG6d8RGrFcNd+VhkyvU43Cuu+fQ==","signatures":[{"sig":"MEYCIQDq4sCur11nG3PSTteZ+xkcum2nk3LH93TQbNVwfLgIWQIhAIcUvjLN1ABEUnNHJNwA8zLSB3tH29KhRmAkf0hvb59b","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":233467},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./data":{"types":"./dist/data/index.d.ts","import":"./dist/data/index.mjs","require":"./dist/data/index.js"},"./forms":{"types":"./dist/forms/index.d.ts","import":"./dist/forms/index.mjs","require":"./dist/forms/index.js"},"./device":{"types":"./dist/device/index.d.ts","import":"./dist/device/index.mjs","require":"./dist/device/index.js"},"./analytics":{"types":"./dist/analytics/index.d.ts","import":"./dist/analytics/index.mjs","require":"./dist/analytics/index.js"},"./performance":{"types":"./dist/performance/index.d.ts","import":"./dist/performance/index.mjs","require":"./dist/performance/index.js"}},"gitHead":"0a93c6383edd072e1a4a09bd0d0a05abf61b6e60","scripts":{"dev":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --watch","lint":"biome check .","test":"vitest run","build":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --clean","clean":"rm -rf dist node_modules/.cache","lint:fix":"biome check --write .","test:watch":"vitest"},"_npmUser":{"name":"antoineschaller","email":"antoine.schaller@akson.ch"},"_npmVersion":"11.3.0","description":"React hooks for landing pages - device detection, API calls, form submission, analytics, and performance","directories":{},"_nodeVersion":"24.2.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","react":"^18.2.0","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0","@types/react":"^18.2.0","@biomejs/biome":"^1.8.3"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/landing-hooks_0.1.0_1757534937518_0.725591250286145","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has been renamed to @akson/cortex-landing-hooks. Please update your dependencies."},"0.1.1":{"name":"@akson/landing-hooks","version":"0.1.1","keywords":["akson","landing","react-hooks","device-detection","api-calls","form-submission","analytics","performance","image-preloader"],"author":{"name":"Akson"},"license":"MIT","_id":"@akson/landing-hooks@0.1.1","maintainers":[{"name":"antoineschaller","email":"antoine.schaller@akson.ch"}],"dist":{"shasum":"0453c603a180ddcf40be6de9df52eaa5196fd846","tarball":"https://registry.npmjs.org/@akson/landing-hooks/-/landing-hooks-0.1.1.tgz","fileCount":33,"integrity":"sha512-Y+02hSAK9uZuUSmpUrAf8pP3h4swCvjeUmMyrqjEbw7wJJYisoxjtdcigFFCm5NVdXvk7AKdwtJf0HlUPgpn3g==","signatures":[{"sig":"MEUCIAg4nZ6VCE0ZR7fVg9/ujlo/4PoZ+j3QF/h4Y/oYNlNsAiEAtPBObLhrN0MuCrT97jC3xUaYQbwZJVA67AfKGSq+6e8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":233531},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./data":{"types":"./dist/data/index.d.ts","import":"./dist/data/index.mjs","require":"./dist/data/index.js"},"./forms":{"types":"./dist/forms/index.d.ts","import":"./dist/forms/index.mjs","require":"./dist/forms/index.js"},"./device":{"types":"./dist/device/index.d.ts","import":"./dist/device/index.mjs","require":"./dist/device/index.js"},"./analytics":{"types":"./dist/analytics/index.d.ts","import":"./dist/analytics/index.mjs","require":"./dist/analytics/index.js"},"./performance":{"types":"./dist/performance/index.d.ts","import":"./dist/performance/index.mjs","require":"./dist/performance/index.js"}},"gitHead":"51f2c821cbcc8a61efd48592066a121a601d3545","scripts":{"dev":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --watch","lint":"biome check .","test":"vitest run","build":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --clean","clean":"rm -rf dist node_modules/.cache","lint:fix":"biome check --write .","test:watch":"vitest"},"_npmUser":{"name":"antoineschaller","email":"antoine.schaller@akson.ch"},"_npmVersion":"11.3.0","description":"React hooks for landing pages - device detection, API calls, form submission, analytics, and performance","directories":{},"_nodeVersion":"24.2.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","react":"^19.1.0","vitest":"^1.2.0","react-dom":"^19.1.0","typescript":"^5.3.3","@types/node":"^20.11.0","@types/react":"^19.0.0","@biomejs/biome":"^1.8.3","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/landing-hooks_0.1.1_1757597465282_0.3724451602645136","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has been renamed to @akson/cortex-landing-hooks. Please update your dependencies."},"0.1.2":{"name":"@akson/landing-hooks","version":"0.1.2","keywords":["akson","landing","react-hooks","device-detection","api-calls","form-submission","analytics","performance","image-preloader"],"author":{"name":"Akson"},"license":"MIT","_id":"@akson/landing-hooks@0.1.2","maintainers":[{"name":"antoineschaller","email":"antoine.schaller@akson.ch"}],"dist":{"shasum":"a30c6d7a33fd88a05ff1f07dfacbb118f7b77c46","tarball":"https://registry.npmjs.org/@akson/landing-hooks/-/landing-hooks-0.1.2.tgz","fileCount":33,"integrity":"sha512-Ai7KwCbA3jUa81wfKTl9/uRfr3Rwwj+58btEOocaRQY1KovslmEdSM5id0uqo16+lbd9C0tLYCc2VZb/71KVNw==","signatures":[{"sig":"MEQCIGl3QlthyMNfjzL7casYBru9W5I6HsPdQ4+L/CqwUyp4AiBVYvwC3mEf2VvogXxhcImve38RTo41jUxjStJqep/6gg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":234353},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./data":{"types":"./dist/data/index.d.ts","import":"./dist/data/index.mjs","require":"./dist/data/index.js"},"./forms":{"types":"./dist/forms/index.d.ts","import":"./dist/forms/index.mjs","require":"./dist/forms/index.js"},"./device":{"types":"./dist/device/index.d.ts","import":"./dist/device/index.mjs","require":"./dist/device/index.js"},"./analytics":{"types":"./dist/analytics/index.d.ts","import":"./dist/analytics/index.mjs","require":"./dist/analytics/index.js"},"./performance":{"types":"./dist/performance/index.d.ts","import":"./dist/performance/index.mjs","require":"./dist/performance/index.js"}},"gitHead":"51f2c821cbcc8a61efd48592066a121a601d3545","scripts":{"dev":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --watch","lint":"biome check .","test":"vitest run","build":"tsup src/index.ts src/device/index.ts src/performance/index.ts src/data/index.ts src/forms/index.ts src/analytics/index.ts --format cjs,esm --dts --clean","clean":"rm -rf dist node_modules/.cache","lint:fix":"biome check --write .","test:watch":"vitest"},"_npmUser":{"name":"antoineschaller","email":"antoine.schaller@akson.ch"},"_npmVersion":"11.3.0","description":"React hooks for landing pages - device detection, API calls, form submission, analytics, and performance","directories":{},"_nodeVersion":"24.2.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","react":"^19.1.0","vitest":"^1.2.0","react-dom":"^19.1.0","typescript":"^5.3.3","@types/node":"^20.11.0","@types/react":"^19.0.0","@biomejs/biome":"^1.8.3","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/landing-hooks_0.1.2_1757623646291_0.19047594062486195","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has been renamed to @akson/cortex-landing-hooks. Please update your dependencies."}},"time":{"created":"2025-09-10T20:08:57.425Z","modified":"2025-09-12T15:44:52.347Z","0.1.0":"2025-09-10T20:08:57.730Z","0.1.1":"2025-09-11T13:31:05.477Z","0.1.2":"2025-09-11T20:47:26.491Z"},"author":{"name":"Akson"},"license":"MIT","keywords":["akson","landing","react-hooks","device-detection","api-calls","form-submission","analytics","performance","image-preloader"],"description":"React hooks for landing pages - device detection, API calls, form submission, analytics, and performance","maintainers":[{"name":"antoineschaller","email":"antoine.schaller@akson.ch"}],"readme":"# @akson/landing-hooks\n\nReact hooks for landing pages - device detection, API calls, form submission, analytics, and performance optimization.\n\n## Installation\n\n```bash\nnpm install @akson/landing-hooks\n```\n\n## Features\n\n- **Device Detection** - Responsive breakpoints and screen size detection with SSR support\n- **API Calls** - Robust HTTP requests with retries, error handling, and authentication\n- **Form Submission** - Validation, debouncing, auto-save, and submission state management\n- **Analytics** - Multi-platform tracking (GTM, PostHog, Facebook Pixel) with type safety\n- **Performance** - Image preloading, lazy loading, and optimization utilities\n\n## Quick Start\n\n```tsx\nimport { \n  useMobileDetection, \n  useApiCall, \n  useFormSubmission,\n  useAnalytics,\n  useImagePreloader \n} from '@akson/landing-hooks';\n\nfunction MyLandingPage() {\n  // Device detection\n  const { isMobile, deviceType } = useMobileDetection();\n  \n  // API calls\n  const api = useApiCall({ \n    url: '/api/contact',\n    method: 'POST' \n  });\n  \n  // Form submission\n  const form = useFormSubmission({\n    endpoint: '/api/contact',\n    onSuccess: (data) => console.log('Success!', data)\n  });\n  \n  // Analytics\n  const analytics = useAnalytics({\n    gtmId: 'GTM-XXXXXXX',\n    posthogKey: 'phc_xxxxx'\n  });\n  \n  // Image preloading\n  const { progress } = useImagePreloader({\n    images: ['/hero.jpg', '/product1.jpg', '/product2.jpg']\n  });\n  \n  return (\n    <div>\n      {isMobile ? 'Mobile View' : 'Desktop View'}\n      <p>Preload progress: {progress}%</p>\n    </div>\n  );\n}\n```\n\n## Device Detection\n\n### useMobileDetection\n\nResponsive device detection with customizable breakpoints:\n\n```tsx\nimport { useMobileDetection } from '@akson/landing-hooks/device';\n\nfunction ResponsiveComponent() {\n  const { isMobile, isTablet, isDesktop, deviceType, screenWidth } = useMobileDetection({\n    mobileBreakpoint: 768,\n    tabletBreakpoint: 1024,\n    debounceMs: 150\n  });\n\n  return (\n    <div>\n      <p>Device: {deviceType}</p>\n      <p>Screen width: {screenWidth}px</p>\n      {isMobile && <MobileMenu />}\n      {isDesktop && <DesktopMenu />}\n    </div>\n  );\n}\n```\n\n### useWindowDimensions\n\nSafe window dimensions with SSR support:\n\n```tsx\nimport { useWindowDimensions } from '@akson/landing-hooks/device';\n\nfunction WindowInfo() {\n  const { width, height } = useWindowDimensions();\n  return <p>{width} × {height}</p>;\n}\n```\n\n## API Calls\n\n### useApiCall\n\nRobust API calls with retry logic:\n\n```tsx\nimport { useApiCall } from '@akson/landing-hooks/data';\n\nfunction UserProfile({ userId }) {\n  const { data, loading, error, execute } = useApiCall({\n    url: \\`/api/users/\\${userId}\\`,\n    retries: 3,\n    retryDelay: 1000,\n    onSuccess: (user) => console.log('User loaded:', user),\n    onError: (err) => console.error('Failed:', err)\n  });\n\n  useEffect(() => {\n    execute();\n  }, [userId]);\n\n  if (loading) return <div>Loading...</div>;\n  if (error) return <div>Error: {error.message}</div>;\n  return <div>Hello, {data?.name}!</div>;\n}\n```\n\n### useAuthenticatedApiCall\n\nAPI calls with authentication:\n\n```tsx\nimport { useAuthenticatedApiCall } from '@akson/landing-hooks/data';\n\nfunction ProtectedData() {\n  const api = useAuthenticatedApiCall({\n    url: '/api/protected',\n    getToken: () => localStorage.getItem('jwt_token')\n  });\n\n  return (\n    <button onClick={() => api.execute()}>\n      {api.loading ? 'Loading...' : 'Fetch Data'}\n    </button>\n  );\n}\n```\n\n## Form Submission\n\n### useFormSubmission\n\nAdvanced form handling with validation and auto-save:\n\n```tsx\nimport { useFormSubmission, createFormValidator, ValidationPatterns } from '@akson/landing-hooks/forms';\n\nconst validator = createFormValidator({\n  email: {\n    required: true,\n    pattern: ValidationPatterns.email\n  },\n  name: {\n    required: true,\n    minLength: 2\n  }\n});\n\nfunction ContactForm() {\n  const form = useFormSubmission({\n    endpoint: '/api/contact',\n    validateBeforeSubmit: validator,\n    autosave: true,\n    onSuccess: () => alert('Success!'),\n    onError: (error) => alert('Error: ' + error.message)\n  });\n\n  const handleSubmit = (e) => {\n    e.preventDefault();\n    const formData = new FormData(e.target);\n    form.submit(Object.fromEntries(formData));\n  };\n\n  return (\n    <form onSubmit={handleSubmit}>\n      <input name=\"email\" type=\"email\" required />\n      <input name=\"name\" type=\"text\" required />\n      \n      {form.validationErrors.map(error => (\n        <p key={error} style={{ color: 'red' }}>{error}</p>\n      ))}\n      \n      <button type=\"submit\" disabled={form.isSubmitting}>\n        {form.isSubmitting ? 'Submitting...' : 'Submit'}\n      </button>\n      \n      {form.success && <p style={{ color: 'green' }}>Form submitted successfully!</p>}\n      {form.isDirty && <p>Unsaved changes</p>}\n    </form>\n  );\n}\n```\n\n## Analytics\n\n### useAnalytics\n\nMulti-platform analytics tracking:\n\n```tsx\nimport { useAnalytics } from '@akson/landing-hooks/analytics';\n\nfunction AnalyticsExample() {\n  const analytics = useAnalytics({\n    gtmId: 'GTM-XXXXXXX',\n    posthogKey: 'phc_xxxxx',\n    debug: true\n  });\n\n  const handleButtonClick = () => {\n    analytics.track('button_click', {\n      button_name: 'hero_cta',\n      page: 'landing'\n    });\n  };\n\n  const handleFormSubmit = (userData) => {\n    analytics.identify(userData);\n    analytics.trackConversion('form_submission', 100);\n  };\n\n  useEffect(() => {\n    analytics.trackPageView();\n  }, []);\n\n  return (\n    <button onClick={handleButtonClick}>\n      Track This Click\n    </button>\n  );\n}\n```\n\n### useEcommerceAnalytics\n\nE-commerce specific tracking:\n\n```tsx\nimport { useEcommerceAnalytics } from '@akson/landing-hooks/analytics';\n\nfunction ProductPage({ product }) {\n  const analytics = useEcommerceAnalytics({ gtmId: 'GTM-XXXXXXX' });\n\n  useEffect(() => {\n    analytics.trackViewItem(product);\n  }, [product]);\n\n  const handleAddToCart = () => {\n    analytics.trackAddToCart(product);\n  };\n\n  const handlePurchase = (transactionId, items, total) => {\n    analytics.trackPurchase(transactionId, items, total);\n  };\n\n  return (\n    <div>\n      <h1>{product.name}</h1>\n      <button onClick={handleAddToCart}>Add to Cart</button>\n    </div>\n  );\n}\n```\n\n## Performance\n\n### useImagePreloader\n\nPreload images with progress tracking:\n\n```tsx\nimport { useImagePreloader } from '@akson/landing-hooks/performance';\n\nfunction ImageGallery() {\n  const { progress, loadedImages, isPreloading } = useImagePreloader({\n    images: [\n      '/gallery/image1.jpg',\n      '/gallery/image2.jpg',\n      '/gallery/image3.jpg'\n    ],\n    concurrency: 2,\n    onComplete: () => console.log('All images preloaded!'),\n    onError: (src, error) => console.warn('Failed to load:', src)\n  });\n\n  return (\n    <div>\n      {isPreloading && <p>Loading images... {progress}%</p>}\n      <div className=\"gallery\">\n        {images.map(src => (\n          <img \n            key={src} \n            src={src} \n            style={{ \n              opacity: loadedImages.has(src) ? 1 : 0.5 \n            }} \n          />\n        ))}\n      </div>\n    </div>\n  );\n}\n```\n\n### useLazyImage\n\nLazy load images with intersection observer:\n\n```tsx\nimport { useLazyImage } from '@akson/landing-hooks/performance';\n\nfunction LazyImage({ src, alt }) {\n  const { \n    src: currentSrc, \n    isLoading, \n    hasLoaded, \n    ref \n  } = useLazyImage(src, {\n    placeholder: '/placeholder.jpg',\n    rootMargin: '50px'\n  });\n\n  return (\n    <img \n      ref={ref}\n      src={currentSrc}\n      alt={alt}\n      style={{\n        opacity: hasLoaded ? 1 : 0.5,\n        transition: 'opacity 0.3s ease'\n      }}\n    />\n  );\n}\n```\n\n## TypeScript\n\nAll hooks are fully typed with TypeScript. Import types as needed:\n\n```tsx\nimport type { \n  MobileDetection,\n  ApiCallResult,\n  FormSubmissionResult,\n  AnalyticsConfig \n} from '@akson/landing-hooks';\n```\n\n## License\n\nMIT","readmeFilename":"README.md"}