Accelerating Product-Led Growth With a Data Layer

By
in Conversion Optimization on

A product data layer can accelerate PLG (product-led-growth) with customer-specific homepage and pricing personalization.

What Is A Data Layer?

A data layer is an index of data points and values, usually expressed in a JavaScript array or JSON format to make it easy to parse. A data layer is where website interactions and event metadata is stored. These are usually implemented in website tag management tools (Google Tag Manager notably calls their data layer object "dataLayer") or via tools such as Twilio Segment that can then push this data to multiple other tools via APIs. 

In the context of web development and web analytics, a data layer is used to capture and store key information about a webpage or user. For example, in the case of an eCommerce website, this may include information like product price, if the item is in stock or not, shipping costs and other product customization options (ie. colors/sizes). This may also include information that may not be explicitly shown on the page. Once implemented in a data layer, this information can then be consumed and sent to third-party tools like web analytics (Google Analytics or Adobe Analytics) or marketing automation systems like Marketo or HubSpot CRM. Additionally, the values can easily be stored on the user's machine (ie. via cookies or session storage) to support personalization as part of a formal CRO program.

What Is A Product Data Layer?

A product data layer stores key authenticated account and user information such as their original sign-up date, current product plan, and key product feature usage. The data can be used for product behavior analysis and reporting (for example, in Amplitude), consumed to improve product onboarding in tools like Pendo, or even be leveraged for user personalization or website account-based marketing.

Example Product Data Layer

Here is an example data layer used for a SaaS product that offered a 14-day free trial and monthly/yearly payment options. This software was targeted to web developers and QA engineers to help optimize websites across virtual mobile devices and browsers. 

The values of the fields were implemented by our product/engineering teams while marketing provided the solution design and format of the values. Luckily, these values and attributes were all already available in the back-end product database and easily added to the website as a JavaScript array whose valued were pushed via PHP. 

window.productDataMap = {
    "user": {
        "userId": userId,
        "name": name,
        "lastName": lastName,
        "email": email,
        "company": company,
        "phone": phone,
        "startDate": startDate
    },
    "plan": {
        "trialStatus": trialStatus,
        "period": period,
        "plan": plan,
        "expiration": expiration,
        "planLocal": planLocal
    },
    "account": {
        "isMaH": isMaH,
        "MaHemail": MaHemail,
        "seats": seats,
        "maxSeats": maxSeats,
        "autoMinutes,": autoMinutes,
        "autoMinutesUsed,": autoMinutesUsed
    }
}

Fields Explained and Example Values

User Fields 

  • userId: A unique number string representing the userId - this matched our product and also let us tie anonymous pre-trial signup behaviors to users.
  • name: The user's first name.
  • lastName: The user's last name.
  • email: The user's email.
  • company: The user's company name.
  • phone: The user's phone number.
  • startDate: The user's original account sign-up date.

Plan Fields 

  • trialStatus: A binary "true" or "false" depending if the user was currently actively enrolled in a 14-day trial.
  • period: Payment period of plan - either "monthly" if they were on a paid monthly tier or "yearly" if they were on a yearly tier. We used "n/a" to indicate if the user was on a free 14-day trial.
  • plan: The name of the current product plan. This included partner-sourced account sign-ups, our 14-day free trial, and varying product tiers/SKUs.
  • expiration: The expiration date of the current tier or free plan.
  • planLocal: A binary "true" or "false" if the user had installed local website testing for our product.
    • This was primarily an indicator that the user was a web developer.

Account Fields 

  • isMah: A binary "true" or "false" depending if the user was the master account holder.
    • Only master account holders could downgrade/upgrade plans or purchase additional functionality.
  • MaHemail: The email address of the master account holder.
  • seats: Current seats used under the current plan.
  • maxSeats: Total maximum seats available under the current plan.
  • autoMinutes: Total automated testing minutes.
    • Our product offered a certain amount of automated testing minutes depending on plan. This # was the total amount allowable monthly on the plan.
  • autoMinutesUsedThe total usage of automated testing minutes used in their account.
    • This was a significant indicator that users would fit into higher cost/enterprise plans.

The data layer values were updated once every 24 hours by the engineering teams. Here is an example of the above data layer inflated with example user values:

window. productDataMap = {
"user": { "userId": "534020", "name": "John", "lastName": "Smith", "email": "john.smith@acme.com", "company": "Acme Inc.", "phone": "212-111-2222", "startDate": "08-10-2018" }, "plan": { "trialStatus": "false", "period": "year", "plan": "Yearly Enterprise Testing Plan", "expiration": "08-09-2019", "planLocal": "true" }, "account": { "isMaH": "false", "MaHemail": "development@acme.com", "seats": "10", "maxSeats": "30", "autoMinutes,": "10000.0", "autoMinutesUsed,": "500.0" } }

Using the Data Layer for Personalization

Upon user login, I used Google Tag Manager to store the data layer values in local storage (if they were not set originally).  I was then able to parse the values with custom JavaScript in Optimizely, which enabled us to build custom a/b tests and personalization experiences based on certain data layer values.

Homepage Upsell & Cross-selling

About 40% of visitors who viewed our marketing homepage were existing customers (based on their login tokens). Historically I've seen 20% - 30%, and we wanted to take advantage of this significant traffic segment with better personalization. A traditional marketing homepage with a product overview and broad toolset/market introduction was wasted on these existing, authenticated customers. 

  • Upsell Customers Actively in a Trial
    • Using the # of days remaining in a trial (by comparing the current date and startdate) we advertised a monthly upgrade option
  • Push Documentation / Onboarding
    • Based on true/false flags (ie. planLocal) we actively pushed developer documentation to improve customer onboarding 
  • Upselling Yearly Plans to Monthly Plan subscribers
    • For users who were NOT in a trial, currently on a paid plan with a monthly tier (plan field), and master account holders (via isMaH) I pushed a yearly upsell with a discount (20%). I also tested more aggressive discounts (30%) for monthly customers whose plans were about to expire (less than 15 business days from expiration).
  • Pushing Enterprise Sales Demos
    • For customers who were on non-enterprise tiers and close to or hitting their automation minutes limits, I pushed them to a custom demo form where our sales team would focus on helping them scale test automation and ultimately upsell to a higher enterprise plan (often with multi-year discounts). 

Pricing Upsell

Our software product pricing followed a typical free / good / better / best SaaS pricing model - all plans were shown by default to unauthenticated users. However, users who were not master account holders (isMaH = "false") would not be able to make account changes so we heavily personalized the pricing page based on product data layer values.

  • When users were not master account holders I exposed the MaHemail with a message like "Please contact development@acme.com to make account changes".
    • For larger enterprise companies especially, many tool users did not know who or what department was in charge of account management so exposing this led to individual power users pushing for tier upgrades within their own organization.
  • Based on plan values, I hid lower or free tiers and highlighted the user's active tier while showcasing features unique to higher tiers to more effectively support product tier upselling.
  • I inserted custom messaging to master account holders where maxSeats or autoMinutesUsed were underutilized, linking them to an in-product form to add users to their account.  

For more pricing page suggestions see my article on SaaS Pricing Page Testing Examples and SaaS Pricing Page Best Practices

Help / Documentation

As a SaaS product targeting web developers our product documentation and features were extensive. We saw significant overlap in authenticated accounts accessing documentation and used the product data layer for further personalization. 

  • When users were viewing features or documentation that were not available in their plan, we'd notify users their plan didn't support this feature and either offer them an upgrade path via eCommerce (if they were master account holders) or link a sales meeting booking form and automatically CC'd the master account email (via MaHemail).
  • When individual account users explored features they do not have, I also flagged these the account level via an invisible Marketo call. This automatically alerted the account manager so they could proactively reach out to the user. 

Other Applications

In-app Onboarding and Email Messaging

  • We leveraged Intercom heavily for in-app messaging and fed all data layer fields to Intercom upon login using Intercom's API. This allowed for better segmentation for in-app messaging (ie. introduce automation guides for users who had 0 minutes used but automated testing enabled).
  • This also allowed for more segmented emails and a full email nurture program to be sent to users whose trials or accounts were expiring.