Growcado’s JavaScript SDK

Welcome to personalized content made simple! The Growcado SDK transforms complex content personalization into elegant, automatic experiences. With just a few lines of code, you can serve different content to different users based on where they came from, who they are, and how they behave.

What we're building: A recipe website that automatically shows vegan ingredients to plant-based visitors and traditional ingredients to everyone else — without any manual detection logic. Same recipe, multiple personalities! 🍝

Why the SDK rocks: Instead of managing UTM parameters, headers, and API calls manually, the SDK handles all the complexity automatically while giving you powerful personalization features out of the box.

Want to understand the fundamentals first? Check out our Quick Start Guide for a deep dive into how Growcado personalization works under the hood.

Ready to cook with the pros? Let's go! 👨‍🍳

📦 Installation

First, let's get the SDK into your project:

npm install @growcado/sdk
# or
yarn add @growcado/sdk
# or
pnpm add @growcado/sdk

⚙️ Step 1: One-Time Configuration

Remember all that tenant ID management and header setup? Gone. One configuration call handles everything:

import { GrowcadoSDK } from '@growcado/sdk';

// Configure once, use everywhere
GrowcadoSDK.configure({
  tenantId: 'your-tenant-id',
  enableAutoUTM: true,        // 🎯 Automatic UTM parameter tracking
  enableReferrerTracking: true // 📈 Automatic referrer attribution
});

That's it! The SDK now automatically:

  • ✅ Tracks UTM parameters from URLs

  • ✅ Captures referrer information

  • ✅ Handles all API authentication

  • ✅ Manages storage (memory on server, localStorage on client)

🍝 Step 2: Setting Up Your Content

For this guide, we'll create a personalized recipe system. You'll need two content types in your Growcado CMS:

1. Ingredient (stores individual ingredients)

  • Name (text): "Mozzarella Cheese" or "Vegan Mozzarella"

  • Amount (text): "200g", "1 cup", etc.

2. Recipe (the main content)

  • Name (text): "Lasagna"

  • Image (media): A delicious photo

  • Ingredients (reference): Links to multiple Ingredient entries

The magic: By creating different ingredient entries (regular vs vegan) and using audience segments, the same recipe automatically shows different ingredient lists to different visitors.

Need help setting up content types and entries? Our Quick Start Guide walks through the entire content creation process step-by-step.

📡 Step 3: Fetching Personalized Content

Here's where the SDK really shines. Instead of managing API endpoints, headers, UTM parameters, and response parsing manually, you get clean, simple content fetching:

// Simple and automatic
const response = await GrowcadoSDK.getContent({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});

if (response.data) {
  console.log('Perfect! Here\'s your personalized recipe:', response.data);
} else {
  console.error('Oops:', response.error.message);
}

Behind the scenes, the SDK automatically:

  • ✅ Includes UTM parameters from the current page URL

  • ✅ Adds referrer information for attribution

  • ✅ Handles tenant routing and authentication

  • ✅ Provides clean error handling

  • ✅ Returns structured, parsed data

  • ✅ Applies audience targeting for personalization

What you get back: The exact same recipe data, but automatically personalized based on who's viewing it. A visitor from vegan.shop gets vegan ingredients, while everyone else gets the traditional version.

Curious about the raw API calls and personalization logic? Our Quick Start Guide explains exactly how audience targeting and content variants work.

👤 Step 4: Customer Identification for Super-Personalization

Want to enable the advanced personalization we teased? Set customer identifiers once, and every subsequent content request becomes hyper-personalized:

// Set customer context (usually after login/signup)
GrowcadoSDK.setCustomerIdentifiers({
  userId: 'user_12345',
  email: 'sarah@example.com',
  dietaryPreference: 'vegan',
  familySize: 4,
  subscriptionTier: 'premium'
});

// Now every content request is automatically personalized
const personalizedRecipe = await GrowcadoSDK.getContent({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});

// Sarah gets:
// - Vegan ingredients (because dietaryPreference: 'vegan')
// - Recipe titled "Sarah's Perfect Vegan Lasagna" 
// - Serving size adjusted for 4 people
// - Premium wine pairing suggestions

The magic? You never have to think about this again. Set it once, get personalized content forever.

🧪 Step 5: Testing Your Personalization

Testing variants is now incredibly simple:

// Test different UTM scenarios
GrowcadoSDK.setUTMParameters({
  source: 'vegan.shop',
  campaign: 'recipe-share',
  medium: 'blog'
});

const veganRecipe = await GrowcadoSDK.getContent({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});
console.log('Vegan version:', veganRecipe.data);

// Test referrer-based personalization
GrowcadoSDK.setReferrer('https://healthyfood.com/plant-based-recipes');

const healthRecipe = await GrowcadoSDK.getContent({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});
console.log('Health-focused version:', healthRecipe.data);

// Clear and test default
GrowcadoSDK.clearUTMParameters();
GrowcadoSDK.clearReferrer();

const defaultRecipe = await GrowcadoSDK.getContent({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});
console.log('Default version:', defaultRecipe.data);

⚡ Step 6: Framework Integration (Next.js Example)

The SDK shines in modern frameworks with built-in SSR support:

Server Component (App Router)

// app/recipe/[slug]/page.tsx
import { GrowcadoSDK } from '@growcado/sdk';

// Configure once (in layout or config file)
GrowcadoSDK.configure({
  tenantId: 'your-tenant-id',
  storage: 'auto' // Memory on server, localStorage on client
});

export default async function RecipePage({ params }: { params: { slug: string } }) {
  // This runs on the server - automatically personalized
  const response = await GrowcadoSDK.getContent({
    modelIdentifier: 'recipe',
    contentIdentifier: params.slug
  });

  if (response.error) {
    return <div>Recipe not found</div>;
  }

  const { name, imageUrl, ingredients } = response.data;

  return (
    <div>
      <h1>{name}</h1>
      <img src={imageUrl} alt={name} />
      <ul>
        {ingredients.map(ingredient => (
          <li key={ingredient.id}>
            {ingredient.name} - {ingredient.amount}
          </li>
        ))}
      </ul>
    </div>
  );
}

Client-Side Hydration

// components/PersonalizationTracker.tsx
'use client';

import { useEffect } from 'react';
import { GrowcadoSDK } from '@growcado/sdk';

export default function PersonalizationTracker() {
  useEffect(() => {
    // Hydrate client-side features
    GrowcadoSDK.hydrate();
    
    // Set user context after hydration
    GrowcadoSDK.setCustomerIdentifiers({
      userId: getCurrentUserId(), // Your auth function
      email: getCurrentUserEmail()
    });
  }, []);

  return null; // This component just handles tracking
}

🎯 Step 7: Advanced Features

TypeScript Support

The SDK is fully typed - get autocomplete for everything:

interface RecipeData {
  name: string;
  imageUrl: string;
  ingredients: Ingredient[];
}

const response = await GrowcadoSDK.getContent<RecipeData>({
  modelIdentifier: 'recipe',
  contentIdentifier: 'lasagna'
});

// response.data is fully typed as RecipeData!

Manual UTM Management

Full control when you need it:

// Set specific campaign tracking
GrowcadoSDK.setUTMParameters({
  source: 'newsletter',
  medium: 'email',
  campaign: 'autumn-recipes-2024',
  customParam: 'special-offer'
});

// Check current tracking
const currentUTM = GrowcadoSDK.getUTMParameters();
console.log('Currently tracking:', currentUTM);

Smart Storage Management

The SDK automatically handles different environments:

  • Server-side: Uses memory storage (no localStorage)

  • Client-side: Uses localStorage for persistence

  • Hydration: Seamlessly migrates data from server to client

  • Auto-detection: No configuration needed

🎉 What You've Accomplished

You've just built the same personalized lasagna system as the manual tutorial, but with:

90% less code - One config, simple content fetching ✅ Automatic tracking - UTM and referrer handling built-in ✅ Customer journey mapping - Cross-session personalization ✅ Framework optimization - SSR support with hydration ✅ Type safety - Full TypeScript support ✅ Error handling - Graceful fallbacks included ✅ Testing tools - Easy variant testing and debugging


Pro tip: The same customer identifiers you set work across ALL your content types. Set them once, get personalization everywhere! ✨

Last updated