npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lytics/lio-client-contentstack

v0.1.6

Published

Contentstack integration for Lytics lio-client - enrich CMS content with Lytics analytics

Downloads

654

Readme

@lytics/lio-client-contentstack

Contentstack CMS integration plugin for @lytics/lio-client.

Overview

Monitors Contentstack sync workflows and enriches CMS entries with Lytics analytics (topics, engagement, segments).

Installation

# Requires core client
npm install @lytics/lio-client @lytics/lio-client-contentstack

Usage

import { createLioClient } from '@lytics/lio-client';
import { contentstackPlugin } from '@lytics/lio-client-contentstack';

const lio = createLioClient({
  apiKey: process.env.LYTICS_API_KEY,
  plugins: [contentstackPlugin]
});

await lio.init();

// Check sync status
const status = await lio.contentstack.getSyncStatus();
console.log(`Last sync: ${status.lastSync}`);
console.log(`Entries synced: ${status.entriesSynced}`);

// Enrich a Contentstack entry
const entry = await csStack.entry('blt123').fetch();
const enriched = await lio.contentstack.enrich(entry);
console.log(enriched._lytics.topics);

// Batch enrichment
const entries = await csStack.contentType('blog_post').query().find();
const enrichedList = await lio.contentstack.enrichMany(entries.entries);

// Scan all Contentstack content in Lytics
for await (const content of lio.contentstack.scanContent()) {
  console.log(content.url, content.lytics);
}

// Get analytics
const analytics = await lio.contentstack.getAnalytics();
console.log(`Total entries: ${analytics.totalEntries}`);
console.log(`Top topics:`, analytics.topTopics);

API

getSyncStatus()

Returns Contentstack workflow sync status (last sync, entries synced, content types).

Returns: Promise<SyncStatus>

{
  status: 'sleeping' | 'running' | 'completed' | 'failed' | 'not_configured',
  lastSync: string | null,
  entriesSynced: number,
  contentTypes: string[],
  workflowId?: string
}

getEnrichmentData(entryOrUrl)

Gets Lytics enrichment data for a specific Contentstack entry or URL.

Parameters:

  • entryOrUrl: Contentstack entry object or URL string

Returns: Promise<ContentEntity>

scanContent(options?)

Scans all Contentstack content in Lytics. Returns an async generator for memory-efficient iteration.

Parameters:

  • options: Optional scan options (filter, limit, fields)

Returns: AsyncGenerator<ContentEntity[]>

getAnalytics()

Gets aggregated content analytics for Contentstack entries.

Returns: Promise<ContentAnalytics>

{
  totalEntries: number,
  topTopics: Array<{ topic: string; count: number }>,
  contentTypes: Record<string, number>
}

enrich(entry)

Enriches a single Contentstack entry with Lytics data by URL matching.

Parameters:

  • entry: Contentstack entry object with url or href field

Returns: Promise<T & { _lytics?: LyticsEnrichment }>

The _lytics field contains:

{
  topics?: Record<string, number>,
  hashedurl?: string,
  segments?: string[],
  url?: string
}

enrichMany(entries)

Efficiently enriches multiple entries (uses batch operations).

Parameters:

  • entries: Array of Contentstack entry objects

Returns: Promise<Array<T & { _lytics?: LyticsEnrichment }>>

How It Works

  1. Matches Contentstack entries to Lytics content by URL
  2. Adds _lytics field with topics, hashedurl, segments
  3. Uses /v2/content/entity for single lookups
  4. Uses /api/segment/scan for batch operations
  5. Monitors contentstack-import workflow for sync status

Configuration

Customize the plugin behavior:

const lio = createLioClient({
  apiKey: process.env.LYTICS_API_KEY,
  plugins: [contentstackPlugin],
  contentstack: {
    workflowName: 'contentstack-import',  // Workflow to monitor
    streamName: 'contentstack',            // Stream name in Lytics
  },
});

Use Cases

Marketplace App Dashboard

function DashboardWidget() {
  const [status, setStatus] = useState(null);

  useEffect(() => {
    async function fetchStatus() {
      const sync = await lio.contentstack.getSyncStatus();
      setStatus(sync);
    }
    fetchStatus();
  }, []);

  return <div>Last sync: {status?.lastSync}</div>;
}

Entry Sidebar Widget

function EntrySidebarWidget({ entry }) {
  const [enrichment, setEnrichment] = useState(null);

  useEffect(() => {
    async function fetchEnrichment() {
      const enriched = await lio.contentstack.enrich(entry);
      setEnrichment(enriched._lytics);
    }
    fetchEnrichment();
  }, [entry]);

  return (
    <div>
      <h3>Topics</h3>
      {enrichment?.topics && Object.keys(enrichment.topics).map(topic => (
        <span key={topic}>{topic}</span>
      ))}
    </div>
  );
}

Content Performance Analytics

const analytics = await lio.contentstack.getAnalytics();

console.log(`Total synced entries: ${analytics.totalEntries}`);
console.log('Top topics:');
analytics.topTopics.forEach(({ topic, count }) => {
  console.log(`  ${topic}: ${count} entries`);
});

License

MIT