# Event Rule Variants

This guide shows you how to define and use event rule variants in your Tracking Plans.

## Overview

Event rule variants let you define different property requirements for the same event based on a discriminating property value. This feature is particularly useful when an event needs
different validation rules depending on the context in which it
occurs.

{{< info >}}
Event rule variants use a `discriminator` field to determine which set of property requirements apply. The discriminator is a property whose value determines which variant case to use.
{{< /info >}}

## Define event rule variants

Using your preferred text editor, add variants to your event rules in the [Tracking Plan YAML file]({{< ref "dev-tools/rudder-cli/data-catalog-and-tracking-plans/tracking-plans/create.md#define-tracking-plans" >}}):

### Basic structure

Event rule variants are defined within event rules in Tracking Plans. See [Conditional Validation YAML Reference]({{< ref "dev-tools/rudder-cli/yaml-data-catalog-and-tracking-plans/yaml-conditional-validation.md" >}}) for the detailed variant specification.

The following snippet is a simplified example to demonstrate the structure. See the [Examples](#examples) section below for real-world use cases with complete implementations.

```yaml
version: rudder/v1
kind: tracking-plan
metadata:
  name: mytrackingplan
spec:
  rules:
    - type: event_rule
      id: example_rule
      event: "#event:example_event"
      additional_properties: false

      # Common properties for all variants
      properties:
        - property: "#property:property_1"
          required: true    # Discriminator property must be required
        - property: "#property:property_2"
          required: false   # Common property that may be required by variants
        - property: "#property:property_3"
          required: false   # Property used in default case

      variants:
        - type: discriminator
          discriminator: "#property:property_1"    # Must match the property defined above
          cases:
            - display_name: "Case A"
              match:
                - "value1"
                - "value2"
              description: "Description of Case A"
              properties:
                - property: "#property:property_2"
                  required: true

            - display_name: "Case B"
              match:
                - "value3"
              description: "Description of Case B"
              properties:
                - property: "#property:property_2"
                  required: true

          # Default case for unmatched values
          default:
            - property: "#property:property_3"
              required: true
```

Each variant definition requires:

- The discriminator type (`type: discriminator`)
- The discriminating property name (`discriminator`)
- One or more cases with:

  - A display name (`display_name`)
  - Match values (`match`)
  - Description (`description`) explaining when this case applies
  - Property requirements (`properties`) specific to this case
- Optional default case (`default`) for when no cases match

{{< warning >}}
The discriminator property must be:

- Defined in the event rule's properties section
- Marked as required
- Have a type matching your match values (string, boolean, or number)
{{< /warning >}}

## Supported discriminator types

You can use the following discriminator types in your event rule variants:

| Type | Description | Example values |
| :----| :----| :----|
| String | Match against text values | `"search"`, `"product"`, `"category_search"` |
| Boolean | Match true/false conditions | `true`, `false` |
| Number | Match against numeric thresholds | `500`, `1000`, `2000` |

{{< info >}}
Note that for each type:

- You can specify multiple match values in an array
- Values are matched exactly (no range or pattern matching)
- String matches are case-sensitive
{{< /info >}}

## Examples

The following examples show variant definitions for different use cases:

{{< tabs tabTotal="3" >}}
{{% tab tabName="String discriminator" %}}

**Use Case**: Different property requirements based on page type

This example shows how to validate different properties based on which type of page the user is viewing (search, product, or checkout):

```yaml
version: rudder/v1
kind: tracking-plan
metadata:
  name: ecommerce_tracking_plan
spec:
  rules:
    - type: event_rule
      id: page_viewed_rule
      event: "#event:page_viewed"
      additional_properties: false

      properties:
        - property: "#property:page_type"
          required: true
        - property: "#property:page_url"
          required: false

      variants:
        - type: discriminator
          discriminator: "#property:page_type"
          cases:
            - display_name: "Search Results Page"
              match:
                - "search"
                - "search_results"
                - "category_search"
              description: "When user is on search or category pages"
              properties:
                - property: "#property:search_term"
                  required: true
                - property: "#property:search_filters"
                  required: false

            - display_name: "Product Detail Page"
              match:
                - "product"
                - "product_detail"
              description: "When user is viewing a specific product"
              properties:
                - property: "#property:product_id"
                  required: true
                - property: "#property:product_category"
                  required: true
                - property: "#property:product_price"
                  required: true
                - property: "#property:recommendation_source"
                  required: false

            - display_name: "Checkout Flow Pages"
              match:
                - "checkout"
                - "payment"
                - "review_order"
              description: "When user is in checkout process"
              properties:
                - property: "#property:checkout_step"
                  required: true
                - property: "#property:payment_method"
                  required: false

          default:
            - property: "#property:page_url"
              required: true
```

#### Key takeaways

- Uses string-based page type discrimination
- Handles multiple match values per case (for example, `search`, `search_results`, `category_search`)
- Shows required and optional properties for each page type
- Includes a default case for unmatched page types
{{% /tab %}}

{{% tab tabName="Boolean discriminator" %}}

**Use Case**: Different requirements based on user subscription status

This example demonstrates how to validate different properties based on whether a user has premium access or not:

```yaml
version: rudder/v1
kind: tracking-plan
metadata:
  name: user_management_plan
spec:
  rules:
    - type: event_rule
      id: feature_accessed_rule
      event: "#event:feature_accessed"
      additional_properties: false

      properties:
        - property: "#property:user_id"
          required: true
        - property: "#property:is_premium"
          required: true

      variants:
        - type: discriminator
          discriminator: "#property:is_premium"
          cases:
            - display_name: "Premium Users"
              match:
                - true
              description: "Premium subscribers with full access"
              properties:
                - property: "#property:subscription_tier"
                  required: true
                - property: "#property:feature_access_level"
                  required: true

            - display_name: "Free Users"
              match:
                - false
              description: "Free tier users with limitations"
              properties:
                - property: "#property:trial_days_remaining"
                  required: false
                - property: "#property:usage_limit"
                  required: true
```

#### Key takeaways

- Uses simple boolean discrimination (`true`/`false`)
- Shows different property requirements for premium vs. free users
- Demonstrates required user identification for all cases
- Shows how to handle optional properties like trial information
{{% /tab %}}

{{% tab tabName="Number discriminator" %}}

**Use Case**: Different requirements based on order total amount

This example shows how to validate different properties based on the order value, with special handling for high-value orders:

```yaml
version: rudder/v1
kind: tracking-plan
metadata:
  name: order_tracking_plan
spec:
  rules:
    - type: event_rule
      id: order_placed_rule
      event: "#event:order_placed"
      additional_properties: false

      properties:
        - property: "#property:order_details"
          required: true
        - property: "#property:order_total"
          required: true

      variants:
        - type: discriminator
          discriminator: "#property:order_total"
          cases:
            - display_name: "High Value Orders"
              match:
                - 500
                - 1000
                - 2000
              description: "Orders above $500 threshold"
              properties:
                - property: "#property:loyalty_points_earned"
                  required: true
                - property: "#property:vip_handling"
                  required: true

            - display_name: "Standard Orders"
              match:
                - 50
                - 100
                - 200
              description: "Regular value orders"
              properties:
                - property: "#property:loyalty_points_earned"
                  required: false
```

#### Key takeaways

- Uses numeric value discrimination
- Shows different thresholds for order value categories
- Demonstrates special handling for high-value orders
- Shows how to handle loyalty points based on order value
{{% /tab %}}
{{< /tabs >}}

## Best practices

Follow these best practices when defining event rule variants:

- **Discriminator selection**
  - Choose properties that clearly indicate different contexts
  - Ensure the discriminator property is always available
  - Use simple, predictable property values

- **Case definition**
  - Use clear, descriptive display names
  - Group related match values in the same case
  - Include helpful descriptions

- **Property requirements**
  - Include only relevant properties for each case
  - Consider required vs. optional carefully
  - Use default case for common requirements

- **Validation**
  - Test all variant cases
  - Verify property references
  - Check for edge cases

## Validate and deploy variants

To update your Tracking Plans with the newly-added variants, make sure to [validate and deploy the changes]({{< ref "dev-tools/rudder-cli/data-catalog-and-tracking-plans/tracking-plans/create.md#validate-and-deploy-tracking-plans" >}}) using Rudder CLI.

{{< info >}}
See the [End-to-end Walkthrough]({{< ref "dev-tools/rudder-cli/data-governance-walkthrough.md" >}}) for detailed steps on validating and deploying Tracking Plans.
{{< /info >}}

## See also

- [Custom Type Variants]({{< ref "dev-tools/rudder-cli/data-catalog-and-tracking-plans/conditional-validation/custom-type-rules.md" >}})
- [Conditional Validation YAML Reference]({{< ref "dev-tools/rudder-cli/yaml-data-catalog-and-tracking-plans/yaml-conditional-validation.md" >}})
- Automated validation and deployment using [CLI-based Workflows]({{< ref "dev-tools/rudder-cli/github-actions/" >}})

<br />

