Astro SDK

Astro integration for Entrolytics with View Transitions support

Astro SDK

The @entrolytics/astro-sdk package provides an Astro integration that automatically injects the Entrolytics tracking script and supports Astro's View Transitions for seamless SPA-like navigation tracking.

Installation

pnpm add @entrolytics/astro-sdk

Quick Start

Add Integration to Astro Config

Add the Entrolytics integration to your astro.config.mjs:

astro.config.mjs
import { defineConfig } from 'astro/config'
import entrolytics from '@entrolytics/astro-sdk'

export default defineConfig({
  integrations: [
    entrolytics({
      websiteId: import.meta.env.PUBLIC_ENTROLYTICS_WEBSITE_ID,
      host: import.meta.env.PUBLIC_ENTROLYTICS_HOST,
      autoTrack: true
    })
  ]
})

Add Environment Variables

Create a .env file:

.env
PUBLIC_ENTROLYTICS_WEBSITE_ID=your-website-id
PUBLIC_ENTROLYTICS_HOST=https://entrolytics.dev

Note: Use the PUBLIC_ prefix to make environment variables available in your Astro components.

Start Tracking

The integration automatically tracks page views. For custom events, use the client module:

src/pages/index.astro
---
// Server-side code (runs at build time)
---

<script>
  import { trackEvent } from '@entrolytics/astro-sdk/client'

  document.getElementById('signup-btn')?.addEventListener('click', () => {
    trackEvent('signup-click', {
      plan: 'pro',
      source: 'landing-page'
    })
  })
</script>

<button id="signup-btn">Sign Up for Pro</button>

Configuration

Integration Options

interface EntrolyticsOptions {
  /** Website ID (required) */
  websiteId: string
  /** Link ID for link tracking */
  linkId?: string
  /** Pixel ID for conversion tracking */
  pixelId?: string
  /** Custom analytics host URL */
  host?: string
  /** Auto-track page views (default: true) */
  autoTrack?: boolean
  /** Track outbound link clicks (default: true) */
  trackOutboundLinks?: boolean
  /** Track file downloads (default: false) */
  trackFileDownloads?: boolean
  /** Tag for A/B testing */
  tag?: string
  /** Restrict to specific domains */
  domains?: string[]
  /** Strip query params from URLs */
  excludeSearch?: boolean
  /** Strip hash fragments from URLs */
  excludeHash?: boolean
  /** Honor Do Not Track */
  respectDnt?: boolean
  /** Disable on localhost */
  ignoreLocalhost?: boolean
}

Example Configuration

astro.config.mjs
import { defineConfig } from 'astro/config'
import entrolytics from '@entrolytics/astro-sdk'

export default defineConfig({
  integrations: [
    entrolytics({
      websiteId: 'abc-123-def',
      host: 'https://analytics.company.com',
      autoTrack: true,
      trackOutboundLinks: true,
      trackFileDownloads: true,
      domains: ['example.com', 'blog.example.com'],
      excludeSearch: true,
      ignoreLocalhost: true
    })
  ]
})

Client Module

trackEvent

Track custom events from your Astro components:

src/components/ProductCard.astro
---
export interface Props {
  product: {
    id: string
    name: string
    price: number
  }
}

const { product } = Astro.props
---

<script define:vars={{ product }}>
  import { trackEvent } from '@entrolytics/astro-sdk/client'

  // Track product view on mount
  trackEvent('product-view', {
    productId: product.id,
    productName: product.name,
    price: product.price
  })

  // Track add to cart
  document.getElementById(`add-${product.id}`)?.addEventListener('click', () => {
    trackEvent('add-to-cart', {
      productId: product.id,
      price: product.price
    })
  })

  // Track purchase
  document.getElementById(`buy-${product.id}`)?.addEventListener('click', () => {
    trackEvent('purchase', {
      productId: product.id,
      revenue: product.price,
      currency: 'USD'
    })
  })
</script>

<div class="product-card">
  <h3>{product.name}</h3>
  <p>${product.price}</p>
  <button id={`add-${product.id}`}>Add to Cart</button>
  <button id={`buy-${product.id}`}>Buy Now</button>
</div>

identify

Identify logged-in users:

src/components/UserProfile.astro
---
const user = Astro.locals.user
---

{user && (
  <script define:vars={{ user }}>
    import { identify } from '@entrolytics/astro-sdk/client'

    identify(user.id, {
      email: user.email,
      name: user.name,
      plan: user.subscription,
      company: user.company
    })
  </script>
)}

<div class="user-profile">
  <h2>Welcome, {user.name}!</h2>
</div>

trackPageView

Manually track page views (useful for SPAs or custom routing):

<script>
  import { trackPageView } from '@entrolytics/astro-sdk/client'

  // Track custom page view
  trackPageView('/virtual-page', 'https://referrer.com')
</script>

View Transitions Support

The integration automatically handles Astro's View Transitions. Page views are re-tracked on each navigation:

src/layouts/Layout.astro
---
import { ViewTransitions } from 'astro:transitions'
---

<html lang="en">
  <head>
    <ViewTransitions />
    <!-- Entrolytics script automatically injected -->
  </head>
  <body>
    <slot />
  </body>
</html>

The integration listens for astro:page-load events and automatically tracks new page views during client-side navigation.

Phase 2: Web Vitals

Track Core Web Vitals metrics with automatic or manual tracking:

Automatic Tracking

src/layouts/Layout.astro
<script>
  import { initWebVitals } from '@entrolytics/astro-sdk/client'

  // Auto-track all Core Web Vitals (LCP, INP, CLS, FCP, TTFB)
  initWebVitals()
</script>

Manual Tracking

src/components/WebVitalsTracker.astro
<script>
  import { onLCP, onINP, onCLS } from 'web-vitals'
  import { trackVital } from '@entrolytics/astro-sdk/client'

  onLCP((metric) => trackVital({
    metric: 'LCP',
    value: metric.value,
    rating: metric.rating,
    delta: metric.delta,
    id: metric.id,
    navigationType: metric.navigationType
  }))

  onINP((metric) => trackVital({
    metric: 'INP',
    value: metric.value,
    rating: metric.rating
  }))

  onCLS((metric) => trackVital({
    metric: 'CLS',
    value: metric.value,
    rating: metric.rating
  }))
</script>

Phase 2: Form Analytics

Track form interactions with the createFormTracker helper or manual events:

Using Form Tracker

src/components/ContactForm.astro
<script>
  import { createFormTracker } from '@entrolytics/astro-sdk/client'

  const form = document.getElementById('contact-form')
  const tracker = createFormTracker('contact-form', 'Contact Form')

  // Track form start
  form?.addEventListener('focusin', () => tracker.trackStart(), { once: true })

  // Track field focus/blur
  form?.querySelectorAll('input, textarea').forEach((field, index) => {
    field.addEventListener('focus', () => {
      tracker.trackFieldFocus(field.name, field.type, index)
    })
    field.addEventListener('blur', () => {
      tracker.trackFieldBlur(field.name, field.type, index)
    })
  })

  // Track form submission
  form?.addEventListener('submit', (e) => {
    e.preventDefault()
    // Submit form...
    tracker.trackSubmit(true)
  })

  // Track abandonment on page leave
  window.addEventListener('beforeunload', () => {
    if (form?.contains(document.activeElement)) {
      tracker.trackAbandon()
    }
  })
</script>

<form id="contact-form">
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Submit</button>
</form>

Manual Form Event Tracking

<script>
  import { trackFormEvent } from '@entrolytics/astro-sdk/client'

  // Track form submission
  trackFormEvent({
    eventType: 'submit',
    formId: 'signup-form',
    formName: 'Signup Form',
    success: true,
    timeSinceStart: 15000
  })

  // Track field error
  trackFormEvent({
    eventType: 'field_error',
    formId: 'signup-form',
    fieldName: 'email',
    errorMessage: 'Invalid email format'
  })
</script>

Advanced Usage

Content Collections

Track content views with Astro Content Collections:

src/pages/blog/[...slug].astro
---
import { getCollection, getEntry } from 'astro:content'
import Layout from '@/layouts/Layout.astro'

const { slug } = Astro.params
const post = await getEntry('blog', slug)
---

<Layout title={post.data.title}>
  <script define:vars={{ post: post.data }}>
    import { trackEvent } from '@entrolytics/astro-sdk/client'

    // Track blog post view
    trackEvent('blog-post-view', {
      title: post.title,
      category: post.category,
      author: post.author,
      publishDate: post.publishDate
    })
  </script>

  <article>
    <h1>{post.data.title}</h1>
    <div set:html={post.body} />
  </article>
</Layout>

Project Structure

index.astro
astro.config.mjs
.env

SSR and Static Sites

The integration works with both SSR and static Astro sites:

Static Sites (SSG)

astro.config.mjs
import { defineConfig } from 'astro/config'
import entrolytics from '@entrolytics/astro-sdk'

export default defineConfig({
  output: 'static',
  integrations: [
    entrolytics({
      websiteId: 'your-website-id'
    })
  ]
})

Server-Side Rendering (SSR)

astro.config.mjs
import { defineConfig } from 'astro/config'
import entrolytics from '@entrolytics/astro-sdk'
import vercel from '@astrojs/vercel/serverless'

export default defineConfig({
  output: 'server',
  adapter: vercel(),
  integrations: [
    entrolytics({
      websiteId: 'your-website-id'
    })
  ]
})

TypeScript Support

Full TypeScript support with exported types:

import type {
  EntrolyticsOptions,
  TrackEventData,
  IdentifyTraits
} from '@entrolytics/astro-sdk'

// Type-safe configuration
const options: EntrolyticsOptions = {
  websiteId: 'abc-123',
  trackOutboundLinks: true,
  trackFileDownloads: true
}

// Type-safe event data
const eventData: TrackEventData = {
  revenue: 99.99,
  currency: 'USD',
  productId: 'pro-plan'
}

Peer Dependencies

  • astro: >=5.0.0
  • web-vitals: >=5.0.0 (optional, for automatic Web Vitals tracking)

Features

  • ✅ Astro 5+ integration
  • ✅ Automatic script injection
  • ✅ View Transitions support
  • ✅ Auto-track page views
  • ✅ Outbound link tracking
  • ✅ File download tracking
  • ✅ Phase 2: Web Vitals tracking
  • ✅ Phase 2: Form Analytics
  • ✅ SSR and SSG support
  • ✅ Content Collections integration
  • ✅ TypeScript-first with full type safety
  • ✅ Zero runtime dependencies

Support