Skip to main content

Configuration Guide

The Glood Hydrogen SDK supports both basic and advanced configuration patterns to fit different use cases and environments.

Configuration Overview

The SDK follows a zero-configuration principle with sensible defaults, while providing full customization options for advanced use cases.

Configuration Hierarchy

  1. Basic Configuration - Only API key and domain required
  2. Client-Level App Config - Override app settings in main config
  3. App-Level Config - Individual app module configuration
  4. Environment Variables - External configuration management

Basic Configuration

Minimal Setup

The simplest configuration requires only your API key and Shopify domain:
import { createGlood, recommendations, search, wishlist } from '@glood/hydrogen';

const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
})
  .use(recommendations())
  .use(search())
  .use(wishlist());
What this provides:
  • ✅ All apps enabled with default endpoints
  • ✅ Pixel tracking enabled for all apps
  • ✅ Default consent requirements per app
  • ✅ Automatic event subscriptions
  • ✅ Production-ready configuration

Basic with Debug Mode

Enable debug logging for development:
const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
  debug: process.env.NODE_ENV === 'development',
});

Selective App Usage

Enable only specific apps to reduce bundle size:
// Only recommendations and search
const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
})
  .use(recommendations())
  .use(search());
  // .use(wishlist()); // Commented out

// Only recommendations
const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
})
  .use(recommendations());

Advanced Configuration

Client-Level App Configuration

Override app settings in the main client configuration:
import { createGlood, CONSENT_TYPES } from '@glood/hydrogen';

const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
  apps: {
    recommendations: {
      endpoint: 'https://custom-storefront.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://custom-events.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS], // Only analytics
      },
      subscribedEvents: ['product_viewed', 'cart_viewed'], // Limited events
    },
    search: {
      endpoint: 'https://s-s.glood.ai',
      pixel: {
        enabled: false, // Disable search pixels
        endpoint: 'https://s-pixel.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS],
      },
    },
    wishlist: {
      endpoint: 'https://w-s.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://w-pixel.glood.ai',
        consent: [
          CONSENT_TYPES.ANALYTICS,
          CONSENT_TYPES.PREFERENCES,
          CONSENT_TYPES.MARKETING
        ], // Require all three
      },
    },
  },
  debug: true,
  settings: {
    customKey: 'customValue',
    trackingVersion: '2.0',
  },
})
  .use(recommendations())
  .use(search())
  .use(wishlist());

App-Level Configuration

Configure individual apps with custom settings:
import { recommendations, search, wishlist, CONSENT_TYPES } from '@glood/hydrogen';

const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
})
  .use(recommendations({
    endpoint: 'https://custom-recommendations.glood.ai',
    pixel: {
      enabled: true,
      endpoint: 'https://custom-pixel.glood.ai',
      consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
    },
    subscribedEvents: ['product_viewed', 'collection_viewed'],
  }))
  .use(search({
    endpoint: 'https://search-api.glood.ai',
    pixel: {
      enabled: true,
      endpoint: 'https://search-pixel.glood.ai',
      consent: [CONSENT_TYPES.ANALYTICS],
    },
  }))
  .use(wishlist()); // Use defaults

Environment-Specific Configuration

Multi-Environment Setup

Configure different settings for different environments:
const getGloodConfig = () => {
  const env = process.env.NODE_ENV;
  const isDev = env === 'development';
  const isStaging = env === 'staging';
  const isProd = env === 'production';

  return {
    apiKey: process.env.GLOOD_API_KEY!,
    myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,
    debug: isDev || isStaging,
    apps: {
      recommendations: {
        endpoint: isDev
          ? 'https://dev-storefront.glood.ai'
          : isStaging
          ? 'https://staging-storefront.glood.ai'
          : 'https://storefront.glood.ai',
        pixel: {
          enabled: isProd || isStaging, // No pixels in dev
          endpoint: isDev
            ? 'https://dev-events.glood.ai'
            : isStaging
            ? 'https://staging-events.glood.ai'
            : 'https://events.glood.ai',
          consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
        },
      },
      search: {
        endpoint: isDev
          ? 'https://dev-search.glood.ai'
          : isStaging
          ? 'https://staging-search.glood.ai'
          : 'https://s-s.glood.ai',
        pixel: {
          enabled: isProd || isStaging,
          endpoint: isDev
            ? 'https://dev-s-pixel.glood.ai'
            : isStaging
            ? 'https://staging-s-pixel.glood.ai'
            : 'https://s-pixel.glood.ai',
          consent: [CONSENT_TYPES.ANALYTICS],
        },
      },
      wishlist: {
        endpoint: isDev
          ? 'https://dev-wishlist.glood.ai'
          : isStaging
          ? 'https://staging-wishlist.glood.ai'
          : 'https://w-s.glood.ai',
        pixel: {
          enabled: isProd, // Only in production
          endpoint: 'https://w-pixel.glood.ai',
          consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.PREFERENCES],
        },
      },
    },
  };
};

const glood = createGlood(getGloodConfig())
  .use(recommendations())
  .use(search())
  .use(wishlist());

Environment Variables

Use environment variables for external configuration:
# .env.development
GLOOD_API_KEY=dev_api_key
GLOOD_DEBUG=true
GLOOD_PIXEL_ENABLED=false
GLOOD_RECOMMENDATIONS_ENDPOINT=https://dev-storefront.glood.ai

# .env.staging
GLOOD_API_KEY=staging_api_key
GLOOD_DEBUG=true
GLOOD_PIXEL_ENABLED=true
GLOOD_RECOMMENDATIONS_ENDPOINT=https://staging-storefront.glood.ai

# .env.production
GLOOD_API_KEY=production_api_key
GLOOD_DEBUG=false
GLOOD_PIXEL_ENABLED=true
GLOOD_RECOMMENDATIONS_ENDPOINT=https://storefront.glood.ai
const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,
  debug: process.env.GLOOD_DEBUG === 'true',
  apps: {
    recommendations: {
      endpoint: process.env.GLOOD_RECOMMENDATIONS_ENDPOINT!,
      pixel: {
        enabled: process.env.GLOOD_PIXEL_ENABLED === 'true',
        endpoint: process.env.GLOOD_RECOMMENDATIONS_PIXEL_ENDPOINT!,
        consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
      },
    },
  },
});
Each app has different default consent requirements:
// Default consent per app
const defaultConsent = {
  recommendations: ['analytics', 'marketing'],  // Personalization needs marketing
  search: ['analytics'],                        // Only needs analytics
  wishlist: ['analytics', 'preferences'],       // Needs user preferences
};
Customize consent requirements for compliance:
import { CONSENT_TYPES } from '@glood/hydrogen';

// GDPR-compliant minimal consent
const minimalConsent = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
  apps: {
    recommendations: {
      endpoint: 'https://storefront.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://events.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS], // Only analytics
      },
    },
    search: {
      endpoint: 'https://s-s.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://s-pixel.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS], // Only analytics
      },
    },
    wishlist: {
      endpoint: 'https://w-s.glood.ai',
      pixel: {
        enabled: false, // No tracking for wishlist
        endpoint: 'https://w-pixel.glood.ai',
        consent: [],
      },
    },
  },
});

// Strict privacy requirements
const strictConsent = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
  apps: {
    recommendations: {
      endpoint: 'https://storefront.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://events.glood.ai',
        consent: [
          CONSENT_TYPES.ANALYTICS,
          CONSENT_TYPES.MARKETING,
          CONSENT_TYPES.PREFERENCES,
          CONSENT_TYPES.SALE_OF_DATA, // All consents required
        ],
      },
    },
  },
});
Different configurations for different privacy requirements:
const getConsentConfig = (privacyLevel: 'minimal' | 'standard' | 'full') => {
  const consentMap = {
    minimal: [CONSENT_TYPES.ANALYTICS],
    standard: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.PREFERENCES],
    full: [
      CONSENT_TYPES.ANALYTICS,
      CONSENT_TYPES.MARKETING,
      CONSENT_TYPES.PREFERENCES,
      CONSENT_TYPES.SALE_OF_DATA,
    ],
  };

  return {
    apiKey: process.env.GLOOD_API_KEY!,
    myShopifyDomain: 'your-store.myshopify.com',
    apps: {
      recommendations: {
        endpoint: 'https://storefront.glood.ai',
        pixel: {
          enabled: true,
          endpoint: 'https://events.glood.ai',
          consent: consentMap[privacyLevel],
        },
      },
      // ... other apps
    },
  };
};

// Usage based on user preference or region
const privacyLevel = getPrivacyLevel(); // 'minimal' | 'standard' | 'full'
const glood = createGlood(getConsentConfig(privacyLevel));

Event Subscription Configuration

Default Event Subscriptions

By default, each app subscribes to all relevant events:
const defaultSubscriptions = {
  recommendations: [
    'page_viewed',
    'product_viewed',
    'collection_viewed',
    'cart_viewed',
    'product_added_to_cart',
    'product_removed_from_cart',
    'search_submitted',
    'custom_promotion_viewed'
  ],
  search: [
    'page_viewed',
    'search_submitted',
    'product_viewed',
    'collection_viewed'
  ],
  wishlist: [
    'page_viewed',
    'product_viewed',
    'cart_viewed',
    'product_added_to_cart'
  ]
};

Custom Event Subscriptions

Limit events for specific use cases:
// Product-focused recommendations
const glood = createGlood(config)
  .use(recommendations({
    subscribedEvents: ['product_viewed', 'cart_viewed'],
  }))
  .use(search({
    subscribedEvents: ['search_submitted'], // Only search events
  }))
  .use(wishlist({
    subscribedEvents: ['product_viewed'], // Only product views
  }));

// Minimal event tracking
const glood = createGlood(config)
  .use(recommendations({
    subscribedEvents: ['product_viewed'], // Only product views
  }))
  .use(search({
    subscribedEvents: ['search_submitted'], // Only searches
  }));
  // No wishlist tracking

Performance Configuration

Development Optimization

Optimize for development experience:
const developmentConfig = {
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: 'your-store.myshopify.com',
  debug: true, // Detailed logging
  apps: {
    recommendations: {
      endpoint: 'https://dev-storefront.glood.ai',
      pixel: {
        enabled: false, // No network requests
        endpoint: '',
        consent: [],
      },
      subscribedEvents: ['product_viewed'], // Minimal events
    },
    search: {
      endpoint: 'https://dev-search.glood.ai',
      pixel: {
        enabled: false,
        endpoint: '',
        consent: [],
      },
      subscribedEvents: ['search_submitted'],
    },
    // No wishlist in development
  },
};

const glood = createGlood(developmentConfig)
  .use(recommendations())
  .use(search());

Production Optimization

Optimize for production performance:
const productionConfig = {
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,
  debug: false, // No debug logging
  apps: {
    recommendations: {
      endpoint: 'https://storefront.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://events.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
      },
      // Use default event subscriptions (all events)
    },
    search: {
      endpoint: 'https://s-s.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://s-pixel.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS],
      },
    },
    wishlist: {
      endpoint: 'https://w-s.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://w-pixel.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.PREFERENCES],
      },
    },
  },
};

Testing Configuration

Test Environment Setup

Configuration for testing environments:
const testConfig = {
  apiKey: 'test_api_key',
  myShopifyDomain: 'test-store.myshopify.com',
  debug: true,
  apps: {
    recommendations: {
      endpoint: 'https://test-storefront.glood.ai',
      pixel: {
        enabled: false, // No external requests in tests
        endpoint: 'https://test-events.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS],
      },
    },
  },
};

// For unit tests
const mockConfig = {
  apiKey: 'mock_api_key',
  myShopifyDomain: 'mock-store.myshopify.com',
  debug: false, // No console output in tests
  apps: {
    recommendations: {
      endpoint: 'http://localhost:3001/mock-api',
      pixel: {
        enabled: false,
        endpoint: '',
        consent: [],
      },
    },
  },
};

Mock Configuration

For testing with mocked services:
// jest.config.js
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/src/test/setup.ts'],
};

// src/test/setup.ts
import { createGlood } from '@glood/hydrogen';

// Mock Glood client for tests
jest.mock('@glood/hydrogen', () => ({
  createGlood: jest.fn().mockReturnValue({
    config: {},
    debug: false,
    apps: new Map(),
    getEnabledApps: jest.fn().mockReturnValue([]),
    getApp: jest.fn().mockReturnValue(undefined),
    use: jest.fn().mockReturnThis(),
  }),
  recommendations: jest.fn(),
  search: jest.fn(),
  wishlist: jest.fn(),
}));

Configuration Validation

Runtime Validation

Add validation for production deployments:
function validateConfig(config: any): void {
  if (!config.apiKey) {
    throw new Error('GLOOD_API_KEY environment variable is required');
  }

  if (!config.myShopifyDomain) {
    throw new Error('PUBLIC_STORE_DOMAIN environment variable is required');
  }

  if (!config.myShopifyDomain.includes('.myshopify.com')) {
    console.warn('Warning: Domain does not appear to be a Shopify domain');
  }

  // Validate app configurations
  if (config.apps) {
    Object.entries(config.apps).forEach(([appName, appConfig]: [string, any]) => {
      if (!appConfig.endpoint) {
        throw new Error(`Missing endpoint for ${appName} app`);
      }

      if (appConfig.pixel?.enabled && !appConfig.pixel.endpoint) {
        throw new Error(`Missing pixel endpoint for ${appName} app`);
      }
    });
  }
}

// Usage
const config = {
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,
  // ... other config
};

validateConfig(config);
const glood = createGlood(config);

TypeScript Configuration Validation

Use TypeScript for compile-time validation:
// Strict configuration type
interface StrictGloodConfig {
  apiKey: string;
  myShopifyDomain: string;
  debug: boolean;
  apps: {
    recommendations: Required<RecommendationsAppConfig>;
    search: Required<SearchAppConfig>;
    wishlist: Required<WishlistAppConfig>;
  };
}

function createStrictGlood(config: StrictGloodConfig) {
  return createGlood(config);
}

// Usage - TypeScript will enforce all required fields
const strictGlood = createStrictGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,
  debug: false,
  apps: {
    recommendations: {
      endpoint: 'https://storefront.glood.ai',
      pixel: {
        enabled: true,
        endpoint: 'https://events.glood.ai',
        consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
      },
      subscribedEvents: ['product_viewed', 'cart_viewed'],
    },
    // ... must define search and wishlist too
  },
});

Best Practices

1. Environment-Based Configuration

Use different configurations for different environments:
// ✅ Good - Environment-specific config
const config = getConfigForEnvironment(process.env.NODE_ENV);

// ❌ Avoid - Hardcoded production config everywhere
const config = { /* production settings */ };

2. Gradual Rollout

Start with minimal configuration and gradually add features:
// Phase 1: Basic setup
const glood = createGlood({ apiKey, myShopifyDomain })
  .use(recommendations());

// Phase 2: Add search
const glood = createGlood({ apiKey, myShopifyDomain })
  .use(recommendations())
  .use(search());

// Phase 3: Full setup with custom config
const glood = createGlood({
  apiKey,
  myShopifyDomain,
  apps: { /* custom settings */ }
})
  .use(recommendations())
  .use(search())
  .use(wishlist());

3. Privacy-First Configuration

Design configurations with privacy in mind:
// ✅ Good - Minimal consent by default
const baseConsent = [CONSENT_TYPES.ANALYTICS];

// ✅ Good - Explicit consent requirements
const marketingConsent = [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING];

// ❌ Avoid - Requiring all consents by default
const consent = Object.values(CONSENT_TYPES);

4. Configuration Documentation

Document your configuration choices:
const glood = createGlood({
  apiKey: process.env.GLOOD_API_KEY!,
  myShopifyDomain: process.env.PUBLIC_STORE_DOMAIN!,

  // Enable debug logging in non-production environments
  debug: process.env.NODE_ENV !== 'production',

  apps: {
    recommendations: {
      endpoint: 'https://storefront.glood.ai',
      pixel: {
        // Enable pixel tracking for personalization
        enabled: true,
        endpoint: 'https://events.glood.ai',
        // Require both analytics and marketing consent for personalization
        consent: [CONSENT_TYPES.ANALYTICS, CONSENT_TYPES.MARKETING],
      },
      // Track key e-commerce events for recommendations
      subscribedEvents: [
        'product_viewed',
        'cart_viewed',
        'product_added_to_cart'
      ],
    },
  },
})
  .use(recommendations())
  .use(search())
  .use(wishlist());

Configuration Examples

See the Examples section for complete configuration examples:

See Also