Kigo Context - UI/UX Page Configuration

Kigo UI/UX Page Configuration System

Overview

The Kigo Page Configuration System enables SDK-hosted sites and white-label implementations to customize the layout, components, and content displayed on key pages throughout the user experience. This system supports dynamic component injection and complete page overrides, providing flexibility for partner-specific layouts and user experiences without modifying core SDK functionality.

The configuration is defined under the uiuxOverride['page-configurations'] key within the SDK context and allows partners to tailor the homepage experience based on whether location data is available.


Priority & Structure

Page configuration settings follow a hierarchy of overrides for maximum flexibility and control.

Configuration Priority

  1. Program-level configuration (set in database)
  2. SDK context override via uiuxOverride['page-configurations']
  3. SDK default layout (fallbacks)

Page Configuration Structure

type PageConfigurationMode = "fully_override" | "inject_at_index";

type PageConfiguration = {
  mode: PageConfigurationMode;
  components: PageComponent[];
};

type PageComponent = {
  title: string;
  component_code_type: PageComponentType;
  sorting_order: number; // Starts at 1, determines display order within the page
  [key: string]: ComponentMetadata; // Component-specific metadata (varies by component_code_type)
};

type PageComponentType =
  | "generic_offer_carousel"
  | "generic_category_grid"
  | "component_share_location"
  | "component_user_survey"
  | "component_offer_map_no_location"
  | "component_hero_advertisement_carousel"
  | "component_trending_merchants"
  | "component_just_for_you";

Sorting Order

The sorting_order property determines the display order of components within each page configuration (homepage-with-location or homepage-no-location).

Key Points:

  • Starts at 1: The first component should have sorting_order: 1
  • Sequential ordering: Components are displayed in ascending order (1, 2, 3, etc.)
  • Page-specific: Sorting is independent for each page type—homepage-with-location and homepage-no-location have their own sorting sequences
  • Gaps allowed: You can use gaps (1, 3, 5) to allow for future insertions

Example:

components: [
  { title: 'Featured Deals', sorting_order: 1 },  // Displays first
  { title: 'Near Me', sorting_order: 2 },         // Displays second
  { title: 'Categories', sorting_order: 3 },      // Displays third
]

Configuration Modes

1. Fully Override Mode

Mode: 'fully_override'

Completely replaces all database-configured components with the components defined in the SDK context. This mode gives you full control over the page layout.

Use Cases:

  • Complete UI redesign for specific partners
  • Removing all default components
  • Creating a fully custom homepage experience

Example:

'homepage-with-location': {
  mode: 'fully_override',
  components: [
    // These components will replace ALL database components
  ]
}

2. Inject at Index Mode

Mode: 'inject_at_index'

Injects custom components at specific positions within the existing database-configured layout. The SDK will find the best matching index based on the sorting_order value.

Use Cases:

  • Adding promotional content to existing layouts
  • Inserting partner-specific components without losing default content
  • Testing new components alongside existing ones

Example:

'homepage-with-location': {
  mode: 'inject_at_index',
  components: [
    // These components will be injected at the specified sorting_order
  ]
}

Page Types

1. Homepage with Location

Key: 'homepage-with-location'

Used when the user has shared their location or the SDK context includes location data. This configuration enables location-based features such as nearby offers, distance calculations, and geo-filtered content.

Location-Specific Features:

  • Query filters support latitude, longitude, and radius
  • search_radius_unit can be set to 'MI' or 'KM'
  • Dynamic filtering based on user's current location
  • Proximity-based sorting and filtering

Example Configuration:

'homepage-with-location': {
  mode: 'fully_override',
  components: [
    {
      title: 'Lightning Deals',
      component_code_type: 'generic_offer_carousel',
      sorting_order: 1,  // First component
      generic_offer_carousel_metadata: {
        subtitle: null,
        minimum_required_offers_to_show: 0,
        show_integrated_offer_map: false,
        saved_offer_query: {
          static_query_filters: {
            filter: {
              catalog_filter_ids: [
                '81f190bc-54b9-4cc0-a296-eebef9244435',
              ],
            },
            single_offer_per_merchant: true,
            return_count_only: false,
            search_radius_unit: 'MI',
          },
          dynamic_query_filters: {
            latitude: null,  // Populated from user location
            longitude: null, // Populated from user location
            radius: null,    // Populated from user location
          },
          online_fallback: false,
        },
        go_to_link_above: 'true',
        go_to_link_display_text: 'See all',
        go_to_link_url_parameters: '/',
      },
    },
  ],
}

2. Homepage without Location

Key: 'homepage-no-location'

Used when the user has not shared their location. This configuration disables location-based filtering and displays content that doesn't require geographic data.

No-Location Characteristics:

  • No latitude, longitude, or radius filters
  • No search_radius_unit required
  • dynamic_query_filters typically empty
  • Focus on online offers or national campaigns

Example Configuration:

'homepage-no-location': {
  mode: 'fully_override',
  components: [
    {
      title: 'Lightning Deals',
      component_code_type: 'generic_offer_carousel',
      sorting_order: 1,  // First component
      generic_offer_carousel_metadata: {
        subtitle: null,
        minimum_required_offers_to_show: 0,
        show_integrated_offer_map: false,
        saved_offer_query: {
          static_query_filters: {
            filter: {
              catalog_filter_ids: [
                '81f190bc-54b9-4cc0-a296-eebef9244435',
              ],
            },
            single_offer_per_merchant: true,
            return_count_only: false,
            // No search_radius_unit for no-location page
          },
          dynamic_query_filters: {}, // Empty - no location values
          online_fallback: false,
        },
        go_to_link_above: 'true',
        go_to_link_display_text: 'See all',
        go_to_link_url_parameters: '/',
      },
    },
  ],
}

Component Types

The following component types are available for page configurations:

1. Generic Offer Carousel

Type: 'generic_offer_carousel'

Displays a horizontal scrollable carousel of offers based on query filters.

Important: The generic_offer_carousel_metadata object only applies when component_code_type is set to 'generic_offer_carousel'. Other component types have their own specific metadata structures.

Metadata Structure:

generic_offer_carousel_metadata: {
  subtitle: string | null;
  minimum_required_offers_to_show: number;
  show_integrated_offer_map: boolean;
  saved_offer_query: SavedOfferQuery;  // See "Saved Offer Query" section below
  go_to_link_above: 'true' | 'false';
  go_to_link_display_text?: string;
  go_to_link_url_parameters?: string;
}

Metadata Properties:

PropertyTypeDescription
subtitlestring | nullOptional subtitle displayed below the carousel title
minimum_required_offers_to_shownumberMinimum number of offers required to display the carousel (0 = always show)
show_integrated_offer_mapbooleanWhether to show an integrated map view with the carousel
saved_offer_queryobjectQuery configuration for fetching offers (see below)
go_to_link_above'true' | 'false'Whether to show a "See all" link
go_to_link_display_textstringText for the "See all" link (default: "See all")
go_to_link_url_parametersstringURL path for the "See all" link

Saved Offer Query

The saved_offer_query object defines the query parameters used to fetch offers from the Kigo Offers API. This configuration maps directly to the GET /api/v1/offers endpoint parameters.

Structure:

saved_offer_query: {
  static_query_filters: {
    filter: {
      catalog_filter_ids: string[];  // Curated offer collections
      // Any additional filter params from GET /offers API
    };
    single_offer_per_merchant: boolean;
    return_count_only: boolean;
    search_radius_unit?: 'MI' | 'KM';
  };
  dynamic_query_filters: {
    latitude?: number | null;
    longitude?: number | null;
    radius?: number | null;
  };
  online_fallback: boolean;
}

Static Query Filters

These are fixed filter parameters that don't change based on user context. Any query parameter supported by the GET /offers API can be added here.

PropertyTypeDescription
filter.catalog_filter_idsstring[]Array of catalog filter IDs for curated offer collections
single_offer_per_merchantbooleanIf true, only shows one offer per merchant to avoid duplicates
return_count_onlybooleanIf true, only returns the count (set to false for carousel display)
search_radius_unit'MI' | 'KM'Unit for radius-based searches (Miles or Kilometers)

Dynamic Query Filters

These filters are populated at runtime based on user context (e.g., location):

PropertyTypeDescription
latitudenumber | nullUser's latitude (auto-populated from location)
longitudenumber | nullUser's longitude (auto-populated from location)
radiusnumber | nullSearch radius (auto-populated from location settings)

Online Fallback

PropertyTypeDescription
online_fallbackbooleanIf true, falls back to online offers when no local offers are found

Catalog Filter IDs

The catalog_filter_ids array allows you to display curated collections of offers in your carousel. These IDs represent pre-configured offer sets that can be tailored for specific use cases.

What are Catalog Filter IDs?

Catalog filter IDs are unique identifiers for curated offer collections. They allow you to:

  • Display specific categories of offers (e.g., Pizza, Dining, Shopping)
  • Promote seasonal or featured deals
  • Create themed offer sections
  • Target specific merchant types

How to Get Catalog Filter IDs:

Contact the Kigo team if you need custom catalog filter IDs for your implementation. We can create curated offer collections for specific sections like:

  • "Pizza Deals" - Only pizza-related offers
  • "Weekend Specials" - Curated weekend promotions
  • "New Merchants" - Recently added merchant offers
  • Custom collections based on your requirements

Example Usage:

saved_offer_query: {
  static_query_filters: {
    filter: {
      catalog_filter_ids: [
        '81f190bc-54b9-4cc0-a296-eebef9244435',  // Pizza deals collection
        'a2b3c4d5-e6f7-8901-2345-6789abcdef01',  // Featured merchants
      ],
    },
    single_offer_per_merchant: true,
    return_count_only: false,
    search_radius_unit: 'MI',
  },
  dynamic_query_filters: {
    latitude: null,
    longitude: null,
    radius: null,
  },
  online_fallback: false,
}

Empty Catalog Filter IDs:

If you leave catalog_filter_ids as an empty array [], the carousel will display all available offers based on other filter criteria (location, etc.):

filter: {
  catalog_filter_ids: [],  // Shows all offers (no specific collection filter)
}

Legacy Metadata Reference

For reference, the complete generic_offer_carousel_metadata structure:

generic_offer_carousel_metadata: {
  subtitle: string | null;
  minimum_required_offers_to_show: number;
  show_integrated_offer_map: boolean;
  saved_offer_query: {
    static_query_filters: {
      filter: {
        catalog_filter_ids: string[];
      };
      single_offer_per_merchant: boolean;
      return_count_only: boolean;
      search_radius_unit?: 'MI' | 'KM';
    };
    dynamic_query_filters: {
      latitude?: number | null;
      longitude?: number | null;
      radius?: number | null;
    };
    online_fallback: boolean;
  };
  go_to_link_above: 'true' | 'false';
  go_to_link_display_text?: string;
  go_to_link_url_parameters?: string;
}

2. Generic Category Grid

Type: 'generic_category_grid'

Displays a grid layout of category cards for navigation.

3. Share Location Component

Type: 'component_share_location'

Prompts users to share their location for personalized content.

4. User Survey Component

Type: 'component_user_survey'

Displays user surveys or feedback forms.

5. Offer Map (No Location)

Type: 'component_offer_map_no_location'

Shows a map interface without requiring user location data.

6. Hero Advertisement Carousel

Type: 'component_hero_advertisement_carousel'

Displays promotional banners or hero images in a carousel format.

7. Trending Merchants

Type: 'component_trending_merchants'

Showcases popular or trending merchant partners.

8. Just For You

Type: 'component_just_for_you'

Personalized recommendations based on user behavior and preferences.


Complete Integration Example

This example shows a complete configuration with multiple carousels sorted by sorting_order:

window.Kigo.setContext({
  uiuxOverride: {
    "welcome-modal": { enabled: true },
    "estimated-savings-count": { enabled: false },
    "wallet-icon": { enabled: true },
    "wallet-icon-url": {
      url: "https://www.svgrepo.com/show/19461/url-link.svg",
    },
    "page-configurations": {
      "homepage-with-location": {
        mode: "fully_override",
        components: [
          {
            title: "Lightning Deals",
            component_code_type: "generic_offer_carousel",
            sorting_order: 1,  // Displays first
            generic_offer_carousel_metadata: {
              subtitle: null,
              minimum_required_offers_to_show: 0,
              show_integrated_offer_map: true,
              saved_offer_query: {
                static_query_filters: {
                  filter: {
                    catalog_filter_ids: [
                      "81f190bc-54b9-4cc0-a296-eebef9244435",  // Contact Kigo for custom IDs
                    ],
                  },
                  single_offer_per_merchant: true,
                  return_count_only: false,
                  search_radius_unit: "MI",
                },
                dynamic_query_filters: {
                  latitude: null,   // Auto-populated from user location
                  longitude: null,  // Auto-populated from user location
                  radius: null,     // Auto-populated from user location
                },
                online_fallback: false,
              },
              go_to_link_above: "true",
              go_to_link_display_text: "See all",
              go_to_link_url_parameters: "/",
            },
          },
          {
            title: "Near Me",
            component_code_type: "generic_offer_carousel",
            sorting_order: 2,  // Displays second
            generic_offer_carousel_metadata: {
              subtitle: "Offers in your area",
              minimum_required_offers_to_show: 0,
              show_integrated_offer_map: false,
              saved_offer_query: {
                static_query_filters: {
                  filter: {
                    catalog_filter_ids: [],  // Empty = all offers
                  },
                  single_offer_per_merchant: true,
                  return_count_only: false,
                  search_radius_unit: "MI",
                },
                dynamic_query_filters: {
                  latitude: null,
                  longitude: null,
                  radius: null,
                },
                online_fallback: false,
              },
              go_to_link_above: "true",
              go_to_link_display_text: "See all",
              go_to_link_url_parameters: "/",
            },
          },
        ],
      },
      "homepage-no-location": {
        mode: "fully_override",
        components: [
          {
            title: "Lightning Deals",
            component_code_type: "generic_offer_carousel",
            sorting_order: 1,
            generic_offer_carousel_metadata: {
              subtitle: null,
              minimum_required_offers_to_show: 0,
              show_integrated_offer_map: false,
              saved_offer_query: {
                static_query_filters: {
                  filter: {
                    catalog_filter_ids: [
                      "81f190bc-54b9-4cc0-a296-eebef9244435",
                    ],
                  },
                  single_offer_per_merchant: true,
                  return_count_only: false,
                  // No search_radius_unit for no-location page
                },
                dynamic_query_filters: {},  // Empty for no-location
                online_fallback: false,
              },
              go_to_link_above: "true",
              go_to_link_display_text: "See all",
              go_to_link_url_parameters: "/",
            },
          },
        ],
      },
    },
  },
});

Note: For custom catalog_filter_ids (e.g., "Pizza Deals", "Featured Merchants"), contact the Kigo team. We can create curated offer collections tailored to your needs.


Best Practices

1. Choose the Right Mode

  • Use fully_override when you need complete control over the page layout
  • Use inject_at_index when you want to preserve existing components and add new ones

2. Sorting Order Management

  • Start with sorting_order: 1 for the first component
  • Use sequential numbering (1, 2, 3...) for clear ordering
  • Optionally leave gaps (1, 3, 5) to allow for future insertions without renumbering
  • Remember: sorting is independent for each page type—components in homepage-with-location are sorted separately from homepage-no-location

3. Location Awareness

  • Always provide both homepage-with-location and homepage-no-location configurations
  • Ensure location-based queries are only used in the homepage-with-location configuration
  • Consider online_fallback options for location-based queries

4. Component Metadata

  • Each component_code_type has its own metadata structure (e.g., generic_offer_carousel_metadata only applies to generic_offer_carousel)
  • Set minimum_required_offers_to_show to control visibility thresholds
  • Use single_offer_per_merchant: true to avoid merchant duplication
  • Set appropriate search_radius_unit for your target audience ('MI' for US, 'KM' for international)

5. Query Optimization

  • The saved_offer_query maps directly to the GET /offers API—any supported filter parameter can be added
  • Use catalog_filter_ids to target specific offer collections (contact Kigo team for custom IDs)
  • Set return_count_only: false to retrieve full offer details for display
  • Enable show_integrated_offer_map only when location data is available
  • Use empty catalog_filter_ids: [] to show all offers without collection filtering

6. Navigation Links

  • Use go_to_link_above: 'true' to provide "See all" navigation
  • Keep go_to_link_display_text concise and actionable
  • Ensure go_to_link_url_parameters points to valid routes

Troubleshooting

Common Issues

  1. Components not appearing:

    • Verify mode is set correctly (fully_override or inject_at_index)
    • Check that sorting_order values are non-zero
    • Ensure component metadata structure matches expected schema
  2. Location-based queries not working:

    • Confirm user has shared location or SDK context includes location data
    • Verify search_radius_unit is set in homepage-with-location configuration
    • Check that dynamic_query_filters structure is correct
  3. Offers not showing in carousel:

    • Verify catalog_filter_ids are valid
    • Check minimum_required_offers_to_show threshold
    • Ensure return_count_only is set to false
  4. Override not taking effect:

    • Clear SDK cache and reload
    • Verify configuration is in the correct format
    • Check browser console for validation errors
  5. Wrong page configuration loading:

    • Confirm location detection is working properly
    • Verify both configurations are defined
    • Check SDK initialization logs

Summary

The page configuration system provides partners and hosted sites with powerful tools to customize homepage layouts and content. By supporting both location-aware and location-free configurations, partners can deliver optimized experiences regardless of user location sharing preferences. The dual-mode system (fully_override vs inject_at_index) enables everything from complete redesigns to subtle enhancements—all without modifying core SDK logic.

This flexibility allows partners to align the user experience with their brand guidelines, business objectives, and user engagement strategies while maintaining consistency with the Kigo platform's core functionality.