# Managing non-authenticated user state with AMP **Table of contents** - [Background](#background) - [Display contexts for AMP pages](#display-contexts-for-amp-pages) - [Multiple contexts means multiple state management](#multiple-contexts-means-multiple-state-management) - [Implementation guide](#implementation-guide) - [Before getting started](#before-getting-started) - [Task 1: For non-AMP pages on the publisher origin, set up an identifier and send analytics pings](#task-1-for-non-amp-pages-on-the-publisher-origin-set-up-an-identifier-and-send-analytics-pings) - [Task 2: For AMP pages, set up an identifier and send analytics pings by including Client ID replacement in amp-analytics pings](#task-2-for-amp-pages-set-up-an-identifier-and-send-analytics-pings-by-including-client-id-replacement-in-amp-analytics-pings) - [Task 3: Process analytics pings from pages on the publisher origin](#task-3-process-analytics-pings-from-pages-on-the-publisher-origin) - [Task 4: Process analytics pings from AMP cache or AMP viewer display contexts and establish identifier mappings (if needed)](#task-4-process-analytics-pings-from-amp-cache-or-amp-viewer-display-contexts-and-establish-identifier-mappings-if-needed) - [Task 5: Using Client ID in linking and form submission](#task-5-using-client-id-in-linking-and-form-submission) - [Strongly recommended practices](#strongly-recommended-practices) - [Keep just one association](#keep-just-one-association) - [Respect cookie and local storage deletions](#respect-cookie-and-local-storage-deletions) - [Comply with local laws and regulations](#comply-with-local-laws-and-regulations) User state is an important concept on today’s web. Consider the following use cases that are enabled by managing user state: - A merchant builds a useful **shopping cart** that shows a user the same items during their second visit that they had added to the cart during their first visit many weeks ago. Such an experience increases the chance of the user buying that item by making sure they remain aware of the item they considered buying in the past. - A news publisher who can tailor **recommended articles** to a reader based on the reader’s repeated visits to the publisher’s articles, which helps keep the reader engaged and discovering more content. - A website developer running any type of site collects **analytics** that can tell if two pageviews belong to the same person who saw two pages or to two different people who each saw a single page. Having this insight helps to know how the site is performing, and, ultimately, how to improve it. This article is designed to help you be more successful in **managing non-authenticated user state in AMP**, a way of providing a seamless user journey even if the user hasn’t taken an action to provide their identity, like signing in. After reviewing some of the challenges and considerations in approaching this topic, this guide outlines the ways in which user state is supported by AMP and offers recommendations on how you can approach a technical implementation. ## Background The topic of user state deserves special attention in AMP because AMP pages can display in multiple contexts such as on your website, in Google Search or a third party app. This introduces challenges in managing user state when users travel between these. ### Display contexts for AMP pages You can think of AMP as a portable content format that enables content to be loaded fast anywhere. AMP documents can be displayed via three noteworthy contexts: - The publisher's origin - An AMP cache - An AMP viewer
| Context | Can non-AMP pages be served from here? | Can AMP pages be served from here? | Sample URL |
|---|---|---|---|
| Publisher’s origin | Yes | Yes | https://example.com/article.amp.html |
| AMP cache | No | Yes | https://example-com.cdn.ampproject.org/s/example.com/article.amp.html |
| AMP viewer | No | Yes | https://google.com/amp/s/example.com/article.amp.html |
| amp-analytics configuration looks like: | https://analytics.example.com/ping?type=pageview&user_id=${clientId(uid)} |
| What goes over the network looks like: | https://analytics.example.com/ping?type=pageview&user_id=$amp_client_idIn this case, |
| An analytics ping coming from a non-AMP page on the publisher origin looks like | https://analytics.example.com/ping?type=pageview&user_id=$publisher_origin_identifier |
| An analytics ping coming from an AMP page on the publisher origin looks like | https://analytics.example.com/ping?type=pageview&user_id=$publisher_origin_identifierIn this case, it's the same! By choosing a scope value of uid the underlying value of the uid cookie, which is $publisher_origin_identifier, gets used. |
| User ID on publisher origin | User ID on AMP page that’s NOT on publisher origin (“alias”) |
|---|---|
| Comes from publisher origin identifier or generated as a prospective value if the publisher origin identifier cannot be accessed. | Comes from AMP Client ID |
| User ID on publisher origin | User ID on AMP page that’s NOT on publisher origin (“alias”) |
|---|---|
$existing_publisher_origin_identifier |
$amp_client_id |
| User ID on publisher origin | User ID on AMP page that’s NOT on publisher origin (“alias”) |
|---|---|
$prospective_identifier(generated just-in-time when analytics ping is received) |
$amp_client_id (came from analytics ping) |
##### Processing multiple identifiers in an analytics ping Unlike in [Task 4](#task4) where we configured the analytics ping to contain just one identifier value, with the steps we’ve taken so far in Task 5 we now have two — `orig_user_id` and `user_id`. We will next cover how to process these two identifiers that are part of the inbound analytics ping. Before we proceed, be sure to take note of the steps described in [Parameter validation](#parameter-validation) below and ensure that you are willing to trust both of the values indicated by `orig_user_id` and `user_id`. Check if either of the values corresponding to the inbound analytics ping are present in your mapping table. In our example above, the first pageview happens on an AMP page that’s NOT on the publisher origin followed by the second pageview that happens on the publisher origin. As a result, the values for the analytics ping query parameters will look like this: **Case #1: Identifier arrangement when analytics ping is sent from page on publisher origin**IMPORTANT:
If you choose to process the parameters client-side on the landing page, the landing page should remove identifier information from URLs as soon as the identifier can be captured.
Before removing the parameters, be sure that other code that needs to run to read them has either:
- Run before the removal happens; or
- Can access a place where the code that read and removed the parameters has stored the data
To do this on your non-AMP page, include the following JavaScript, which will remove all query parameters from the URL:
var href = location.href.replace(/\?[^#]+/, ''); history.replaceState(null, null, href);Adapt this as needed to remove fewer query parameters.
| User ID on publisher origin | User ID on AMP page that’s NOT on publisher origin (“alias”) | |
|---|---|---|
| How it’s expressed in analytics ping | user_id=$publisher_origin_id |
orig_user_id=$amp_client_id |
| Parameter key | user_id |
orig_user_id |
| Parameter value | $publisher_origin_id |
$amp_client_id |
| User ID on publisher origin | User ID on AMP page that’s NOT on publisher origin (“alias”) | |
|---|---|---|
| How it’s expressed in analytics ping | orig_user_id=$publisher_origin_id |
user_id=$amp_client_id |
| Parameter key | orig_user_id |
user_id |
| Parameter value | $publisher_origin_id |
$amp_client_id |