DocsIntegrationsReact Integration
Integrations

React Integration

Overview

Integrate CONSETO into React applications using hooks and context. Works with Next.js, Vite, Create React App, and other React frameworks.

Difficulty: Medium

Requires basic React knowledge. Works with any React-based framework.

Method 1: Script Tag (Recommended)

Next.js App Router

In Next.js App Router, layout.tsx is a Server Component by default. Since event handlers like onLoad require client-side JavaScript, you need to create a separate Client Component.

Why a separate component?

Server Components cannot have event handlers. The onLoad callback ensures the SDK is fully loaded before initialization, preventing race conditions.

Step 1: Create the Client Component

tsx
// components/conseto-init.tsx
'use client'

import Script from 'next/script'

export function ConsetoInit() {
  return (
    <Script
      src="https://www.conseto.io/dist/conseto.min.js"
      strategy="afterInteractive"
      onLoad={() => {
        if (typeof window !== 'undefined' && window.Conseto) {
          window.Conseto.init({
            clientId: process.env.NEXT_PUBLIC_CONSETO_CLIENT_ID,
            language: 'sk',
            theme: 'auto'
          }).then(conseto => {
            window.conseto = conseto;
          });
        }
      }}
    />
  )
}

Step 2: Add to your layout

tsx
// app/layout.tsx
import { ConsetoInit } from '@/components/conseto-init'

export default function RootLayout({ children }) {
  return (
    <html lang="sk">
      <body>
        {children}
        <ConsetoInit />
      </body>
    </html>
  )
}

Alternative: Inline Script (No Client Component)

If you prefer not to create a separate component, you can use an inline script. This works directly in Server Components but is slightly less elegant:

tsx
// app/layout.tsx
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html lang="sk">
      <body>
        {children}

        {/* Load SDK */}
        <Script
          src="https://www.conseto.io/dist/conseto.min.js"
          strategy="afterInteractive"
        />

        {/* Initialize after load */}
        <Script id="conseto-init" strategy="lazyOnload">
          {`
            (function checkConseto() {
              if (window.Conseto) {
                window.Conseto.init({
                  clientId: '${process.env.NEXT_PUBLIC_CONSETO_CLIENT_ID}',
                  language: 'sk',
                  theme: 'auto'
                });
              } else {
                setTimeout(checkConseto, 50);
              }
            })();
          `}
        </Script>
      </body>
    </html>
  )
}

Method 2: React Hook

Create a custom hook for CONSETO:

tsx
// hooks/useConseto.ts
import { useEffect, useState } from 'react'

interface ConsetoConfig {
  clientId: string
  language?: string
  theme?: 'dark' | 'light'
  ga4?: string
  gtm?: string
  autoTrackEcommerce?: boolean
}

export function useConseto(config: ConsetoConfig) {
  const [conseto, setConseto] = useState<any>(null)
  const [isReady, setIsReady] = useState(false)

  useEffect(() => {
    const script = document.createElement('script')
    script.src = 'https://www.conseto.io/dist/conseto.min.js'
    script.async = true

    script.onload = async () => {
      const instance = await (window as any).Conseto.init(config)
      setConseto(instance)
      setIsReady(true)
      ;(window as any).conseto = instance
    }

    document.head.appendChild(script)

    return () => {
      document.head.removeChild(script)
    }
  }, [])

  const track = (eventName: string, data?: Record<string, any>) => {
    if (conseto) {
      conseto.track(eventName, data)
    }
  }

  const trackConversion = (conversionType: string, data?: Record<string, any>) => {
    if (conseto) {
      conseto.trackConversion(conversionType, data)
    }
  }

  return { conseto, isReady, track, trackConversion }
}

Usage in Components

tsx
// components/AddToCartButton.tsx
'use client'

import { useConseto } from '@/hooks/useConseto'

export function AddToCartButton({ product }) {
  const { track, isReady } = useConseto({
    clientId: process.env.NEXT_PUBLIC_CONSETO_CLIENT_ID!,
    language: 'sk',
    theme: 'dark'
  })

  const handleAddToCart = () => {
    // Add to cart logic...

    // Track the event
    track('add_to_cart', {
      item_id: product.id,
      item_name: product.name,
      price: product.price,
      quantity: 1
    })
  }

  return (
    <button onClick={handleAddToCart}>
      Add to Cart
    </button>
  )
}

Method 3: Context Provider

tsx
// context/ConsetoContext.tsx
'use client'

import { createContext, useContext, useEffect, useState, ReactNode } from 'react'

interface ConsetoContextType {
  conseto: any
  isReady: boolean
  track: (event: string, data?: Record<string, any>) => void
  trackConversion: (type: string, data?: Record<string, any>) => void
}

const ConsetoContext = createContext<ConsetoContextType | null>(null)

export function ConsetoProvider({
  children,
  clientId,
  ...config
}: { children: ReactNode; clientId: string; [key: string]: any }) {
  const [conseto, setConseto] = useState<any>(null)
  const [isReady, setIsReady] = useState(false)

  useEffect(() => {
    const script = document.createElement('script')
    script.src = 'https://www.conseto.io/dist/conseto.min.js'
    script.async = true

    script.onload = async () => {
      const instance = await (window as any).Conseto.init({
        clientId,
        ...config
      })
      setConseto(instance)
      setIsReady(true)
    }

    document.head.appendChild(script)
  }, [clientId])

  const track = (event: string, data?: Record<string, any>) => {
    conseto?.track(event, data)
  }

  const trackConversion = (type: string, data?: Record<string, any>) => {
    conseto?.trackConversion(type, data)
  }

  return (
    <ConsetoContext.Provider value={{ conseto, isReady, track, trackConversion }}>
      {children}
    </ConsetoContext.Provider>
  )
}

export function useConsetoContext() {
  const context = useContext(ConsetoContext)
  if (!context) {
    throw new Error('useConsetoContext must be used within ConsetoProvider')
  }
  return context
}
CONSETO - GDPR Compliance & Web Analytics