Try for free

Site personalization with customer information? Easy.

July 08, 2025

With EdgeTag our customers are able to quickly and effectively connect analytics channels with their customer-facing sites and maintain a long-lived user identity that is attributed to events generated while using the site.

In this post we'll show how to use that information in order to drive user experiences on your site using custom code, tailoring the experience to that particular user's past interactions.

ready, set, go!

Our SDK provides a method called ready that allows registering a callback that will be called once the tag has initialized. The callback will also receive an object containing information on the current user and session:

edgetag('ready', (parameters: InitParams) => {
  /* code here will run once the tag is initialized */
})

The parameter of this function contains the following information:

type InitParams = {
  destination: string
  userId: string
  sessionId: string
  isNewUser: boolean
  isNewSession: boolean
}
  • destination: this parameter contains the tag's URL endpoint which can be used to determine the context of which tag has initialized if more than one is present on the page
  • userId: the user ID of the current user for the given tag
  • sessionId: the session ID associated with the current page visit
  • isNewUser: will be true when the current page impression is the first time this user was seen visiting the page. Subsequent page loads within the same session will be false for this parameter
  • isNewSession: will be true on the first page impression when the session starts and false for all subsequent page loads

This information allows us to show a greeting to the user visiting the site for the very first time, or a welcome back message for return visitors on the first page impression:

edgetag('ready', ({ isNewUser, isNewSession }) => {
  if (isNewUser) {
    window.alert('Hello and welcome to our shop! Have a look around.')
  } else if (isNewSession) {
    window.alert('Welcome back! We have new items in stock for you.')
  }
})

If this is the user's first time on the site, the isNewUser flag will be true and the welcome message will pop up. If it is false, we check the isNewSession to determine whether it is a previously seen user returning to the site and show the welcome back message instead. For all other cases, no popups are shown to the user.

Guiding the user during their first visit

Let's say that we wanted to present a banner to the user on their first visit, but the banner should be persistent during their entire first session, not just the page load. To do that, we're going to store that information in localStorage so that we can persist this information between page loads. We'll use the sessionId parameter to compare against the stored information in order to determine whether the current session needs to show the banner.

const isFirstVisit = (sessionId: string) =>
  localStorage.getItem('firstVisit') == sessionId
 
edgetag('ready', ({ isNewUser, isNewSession, sessionId }) => {
  if (isNewUser && isNewSession) {
    // the very first page load sets the sessionId for later comparison
    localStorage.setItem('firstVisit', sessionId)
  } else if (localStorage.getItem('firstVisit') != sessionId) {
    // if this isn't the very first page load, we check to see if
    // the session ID is still the same as the first session. if not,
    // delete the stored information.
    localStorage.removeItem('firstVisit')
  }
 
  if (isFirstVisit(sessionId)) {
    // here we can call any custom code that triggers showing the
    // banner for the user during their first visit.
  } else {
    // if needed, you can run code here that only runs on subsequent
    // visits to the site
  }
})

Storing and retrieving custom properties

Our ID graph also allows storing additional data about the user that you might like to use later to customize their experience.

For demonstration purposes, suppose our shop sells specialty food and beverages. As some people might have allergies, we would like to store this information so that search filters and recommendations would apply these restrictions automatically without the user having to specify them every time they browse the store.

To do this, we can use data method in our SDK to persist this information. We'll use a comma separated list of strings to identify the allergens:

// our app collects this information while changing properties, data here
// is just for illustration purposes
const allergens = ['eggs', 'gluten', 'dairy']
 
// whenever these preferences change in our app, we call this method
// to update the user properties; only string values can be stored here
edgetag('data', { allergies: allergens.join(',') })

We can use this API to access the user data when needed. We'll write a helper function that will convert the callback-style call into a Promise that we can then await:

// helper function to convert a callback into a Promise
const getData = (keys: string[]) =>
  new Promise<Record<string, string>>((resolve) => {
    edgetag('getData', keys, (data) => resolve(data))
  })
 
// we can now await the value in our code
const { allergies } = await getData(['allergies'])
 
// we split the comma-separated string to get an array of allergens.
// if no data is available, return an empty array
const allergens = allergies?.split(',') ?? []

You can use this API to store any kind of information you'd like to persist for the lifetime of the user. Not all information requires that kind of persistence; given that accessing this information adds latency, you might consider storing other less important information in local persistence mechanisms in the browser itself, like localStorage, IndexedDB or cookies.

New and returning customers

Lastly, we can also use information about previous purchases associated with the current user to determine whether the user is a returning customer. This approach requires adding a CRM channel for your ecommerce platform.

Let's say that we want to present a coupon popup when a returning customer visits the site after making their purchase. We'll do this by fetching a special user property called isNewCustomer:

// helper function to convert a callback into a Promise
const getData = (keys: string[]) =>
  new Promise<Record<string, string>>((resolve) => {
    edgetag('getData', keys, (data) => resolve(data))
  })
 
edgetag('ready', async ({ isNewUser, isNewSession }) => {
  if (!isNewUser && isNewSession) {
    // we will only run this code on the first page load for a
    // returning user
 
    // fetch the custom property
    const { isNewCustomer, emailExists } = await getData([
      'isNewCustomer',
      'email',
    ])
 
    // handle the 3 cases that can happen
    switch (isNewCustomer) {
      case 'true': {
        // the user has a known email but has not yet purchased anything
        showNewCustomerFlow()
        break
      }
      case 'false': {
        // the user has made a previous purchase
        showReturningCustomerFlow()
        break
      }
      default: {
        // we could not determine the NC/RC status, so let's entice the
        // user to provide their email if they have not done so already
        if (!emailExists) {
          showSubscribeToNewsletter()
        }
      }
    }
  }
})

This allows us to present different flows for the three different scenarios that a user can experience when revisiting the site. This can also be combined with all of the examples above to create a rich personalization experience beyond just the scenarios described here.

... and so much more

There are many more scenarios that our ID graph and SDK allow you to build without having to store and manage information yourselves. As your user base grows and are considering enhancing your site's user experience, remember that you already know your customer — all you have to do is use what you already have.