Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@akson/cortex-landing-hooks

antoineschaller451MIT0.4.1TypeScript support: included

React hooks for landing pages - device detection, API calls, form submission, analytics, and performance

akson, landing, react-hooks, device-detection, api-calls, form-submission, analytics, performance, image-preloader

readme

@akson/cortex-landing-hooks

React hooks for landing pages - device detection, API calls, form submission, analytics, and performance optimization.

Installation

npm install @akson/cortex-landing-hooks

Features

  • Device Detection - Responsive breakpoints and screen size detection with SSR support
  • API Calls - Robust HTTP requests with retries, error handling, and authentication
  • Form Submission - Validation, debouncing, auto-save, and submission state management
  • Analytics - Multi-platform tracking (GTM, PostHog, Facebook Pixel) with type safety
  • Performance - Image preloading, lazy loading, and optimization utilities

Quick Start

import { 
  useMobileDetection, 
  useApiCall, 
  useFormSubmission,
  useAnalytics,
  useImagePreloader 
} from '@akson/cortex-landing-hooks';

function MyLandingPage() {
  // Device detection
  const { isMobile, deviceType } = useMobileDetection();

  // API calls
  const api = useApiCall({ 
    url: '/api/contact',
    method: 'POST' 
  });

  // Form submission
  const form = useFormSubmission({
    endpoint: '/api/contact',
    onSuccess: (data) => console.log('Success!', data)
  });

  // Analytics
  const analytics = useAnalytics({
    gtmId: 'GTM-XXXXXXX',
    posthogKey: 'phc_xxxxx'
  });

  // Image preloading
  const { progress } = useImagePreloader({
    images: ['/hero.jpg', '/product1.jpg', '/product2.jpg']
  });

  return (
    <div>
      {isMobile ? 'Mobile View' : 'Desktop View'}
      <p>Preload progress: {progress}%</p>
    </div>
  );
}

Device Detection

useMobileDetection

Responsive device detection with customizable breakpoints:

import { useMobileDetection } from '@akson/cortex-landing-hooks/device';

function ResponsiveComponent() {
  const { isMobile, isTablet, isDesktop, deviceType, screenWidth } = useMobileDetection({
    mobileBreakpoint: 768,
    tabletBreakpoint: 1024,
    debounceMs: 150
  });

  return (
    <div>
      <p>Device: {deviceType}</p>
      <p>Screen width: {screenWidth}px</p>
      {isMobile && <MobileMenu />}
      {isDesktop && <DesktopMenu />}
    </div>
  );
}

useWindowDimensions

Safe window dimensions with SSR support:

import { useWindowDimensions } from '@akson/cortex-landing-hooks/device';

function WindowInfo() {
  const { width, height } = useWindowDimensions();
  return <p>{width} × {height}</p>;
}

API Calls

useApiCall

Robust API calls with retry logic:

import { useApiCall } from '@akson/cortex-landing-hooks/data';

function UserProfile({ userId }) {
  const { data, loading, error, execute } = useApiCall({
    url: \`/api/users/\${userId}\`,
    retries: 3,
    retryDelay: 1000,
    onSuccess: (user) => console.log('User loaded:', user),
    onError: (err) => console.error('Failed:', err)
  });

  useEffect(() => {
    execute();
  }, [userId]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <div>Hello, {data?.name}!</div>;
}

useAuthenticatedApiCall

API calls with authentication:

import { useAuthenticatedApiCall } from '@akson/cortex-landing-hooks/data';

function ProtectedData() {
  const api = useAuthenticatedApiCall({
    url: '/api/protected',
    getToken: () => localStorage.getItem('jwt_token')
  });

  return (
    <button onClick={() => api.execute()}>
      {api.loading ? 'Loading...' : 'Fetch Data'}
    </button>
  );
}

Form Submission

useFormSubmission

Advanced form handling with validation and auto-save:

import { useFormSubmission, createFormValidator, ValidationPatterns } from '@akson/cortex-landing-hooks/forms';

const validator = createFormValidator({
  email: {
    required: true,
    pattern: ValidationPatterns.email
  },
  name: {
    required: true,
    minLength: 2
  }
});

function ContactForm() {
  const form = useFormSubmission({
    endpoint: '/api/contact',
    validateBeforeSubmit: validator,
    autosave: true,
    onSuccess: () => alert('Success!'),
    onError: (error) => alert('Error: ' + error.message)
  });

  const handleSubmit = (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    form.submit(Object.fromEntries(formData));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required />
      <input name="name" type="text" required />

      {form.validationErrors.map(error => (
        <p key={error} style={{ color: 'red' }}>{error}</p>
      ))}

      <button type="submit" disabled={form.isSubmitting}>
        {form.isSubmitting ? 'Submitting...' : 'Submit'}
      </button>

      {form.success && <p style={{ color: 'green' }}>Form submitted successfully!</p>}
      {form.isDirty && <p>Unsaved changes</p>}
    </form>
  );
}

Analytics

useAnalytics

Multi-platform analytics tracking:

import { useAnalytics } from '@akson/cortex-landing-hooks/analytics';

function AnalyticsExample() {
  const analytics = useAnalytics({
    gtmId: 'GTM-XXXXXXX',
    posthogKey: 'phc_xxxxx',
    debug: true
  });

  const handleButtonClick = () => {
    analytics.track('button_click', {
      button_name: 'hero_cta',
      page: 'landing'
    });
  };

  const handleFormSubmit = (userData) => {
    analytics.identify(userData);
    analytics.trackConversion('form_submission', 100);
  };

  useEffect(() => {
    analytics.trackPageView();
  }, []);

  return (
    <button onClick={handleButtonClick}>
      Track This Click
    </button>
  );
}

useEcommerceAnalytics

E-commerce specific tracking:

import { useEcommerceAnalytics } from '@akson/cortex-landing-hooks/analytics';

function ProductPage({ product }) {
  const analytics = useEcommerceAnalytics({ gtmId: 'GTM-XXXXXXX' });

  useEffect(() => {
    analytics.trackViewItem(product);
  }, [product]);

  const handleAddToCart = () => {
    analytics.trackAddToCart(product);
  };

  const handlePurchase = (transactionId, items, total) => {
    analytics.trackPurchase(transactionId, items, total);
  };

  return (
    <div>
      <h1>{product.name}</h1>
      <button onClick={handleAddToCart}>Add to Cart</button>
    </div>
  );
}

Performance

useImagePreloader

Preload images with progress tracking:

import { useImagePreloader } from '@akson/cortex-landing-hooks/performance';

function ImageGallery() {
  const { progress, loadedImages, isPreloading } = useImagePreloader({
    images: [
      '/gallery/image1.jpg',
      '/gallery/image2.jpg',
      '/gallery/image3.jpg'
    ],
    concurrency: 2,
    onComplete: () => console.log('All images preloaded!'),
    onError: (src, error) => console.warn('Failed to load:', src)
  });

  return (
    <div>
      {isPreloading && <p>Loading images... {progress}%</p>}
      <div className="gallery">
        {images.map(src => (
          <img 
            key={src} 
            src={src} 
            style={{ 
              opacity: loadedImages.has(src) ? 1 : 0.5 
            }} 
          />
        ))}
      </div>
    </div>
  );
}

useLazyImage

Lazy load images with intersection observer:

import { useLazyImage } from '@akson/cortex-landing-hooks/performance';

function LazyImage({ src, alt }) {
  const { 
    src: currentSrc, 
    isLoading, 
    hasLoaded, 
    ref 
  } = useLazyImage(src, {
    placeholder: '/placeholder.jpg',
    rootMargin: '50px'
  });

  return (
    <img 
      ref={ref}
      src={currentSrc}
      alt={alt}
      style={{
        opacity: hasLoaded ? 1 : 0.5,
        transition: 'opacity 0.3s ease'
      }}
    />
  );
}

TypeScript

All hooks are fully typed with TypeScript. Import types as needed:

import type { 
  MobileDetection,
  ApiCallResult,
  FormSubmissionResult,
  AnalyticsConfig 
} from '@akson/cortex-landing-hooks';

License

MIT