{"id":148378,"date":"2025-03-21T20:32:27","date_gmt":"2025-03-21T20:32:27","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/improve-data-collection-with-four-custom-dimensions\/"},"modified":"2025-03-21T20:32:27","modified_gmt":"2025-03-21T20:32:27","slug":"improve-data-collection-with-four-custom-dimensions","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=148378","title":{"rendered":"Improve Data Collection With Four Custom Dimensions"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>Since writing my rant about the <a href=\"https:\/\/www.simoahava.com\/analytics\/the-schema-conspiracy\/\"><em>schema conspiracy<\/em><\/a> of web analytics platforms, I\u2019ve been giving the whole idea of hit-level data collection a lot of thought. Sessionization is very heavily implemented in <a href=\"https:\/\/analytics.google.com\">Google Analytics<\/a>, which is understandable, but the regular Google Analytics API just doesn\u2019t give you the kind of information you\u2019d need, if you wanted to stitch hits together differently in your own backend. In fact, there are <strong>four<\/strong> distinct levels of aggregation that are not exposed via the API, even though I think they should:<\/p>\n<ol>\n<li>\n<p><strong>Hit timestamp<\/strong> &#8211; You can\u2019t query for the exact <em>timestamp<\/em> of a Google Analytics hit via the API. You can\u2019t get it in your custom reports, either. However, this might be very meaningful information, especially if you want to verify data integrity across systems.<\/p>\n<\/li>\n<li>\n<p><strong>Session ID<\/strong> &#8211; Hits are grouped together into <em>sessions<\/em>. However, using the API alone, you will not be able to easily identify if two distinct hits belong to the same session.<\/p>\n<\/li>\n<li>\n<p><strong>Client ID<\/strong> &#8211; Sessions are bunched under a <em>Client ID<\/em>. Every instance of the <code>_ga<\/code> cookie gets a unique Client ID, which is how the Google Analytics backend knows that the same \u201cUser\u201d has visited the site multiple times. This Client ID is not exposed in any dimension you can query via the API.<\/p>\n<\/li>\n<li>\n<p><strong>User ID<\/strong> &#8211; The <em>User ID<\/em> feature in Universal Analytics groups together hits, sessions, and Client IDs. It is the highest possible level of abstraction and aggregation available in Google Analytics. However, the data rows do not expose if a hit\/session belongs to a specific User ID.<\/p>\n<\/li>\n<\/ol>\n<p>So, the purpose of this post is to give you the tools to annotate your incoming hit-stream data with all the information listed above. For data integration, this is almost a necessity, especially if you have a complex mesh of systems across which you want to join arbitrary data.<\/p>\n<p>In the following chapters, we\u2019ll build four <strong>Custom Dimensions<\/strong> and four data collection methods that will let you include this information in your data set. We will, of course, be using <a href=\"https:\/\/tagmanager.google.com\">Google Tag Manager<\/a> to make things more manageable.<\/p>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"1-the-method\">1. The Method<\/h2>\n<p>I\u2019ve created a Custom Dimension for each of the four use cases. Two of the dimensions are session-scoped, and two are hit-scoped. The dimensions are:<\/p>\n<ol>\n<li>\n<p><strong>Client ID<\/strong> &#8211; <em>session-scoped<\/em> Custom Dimension that collects the Client ID set by Google Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Session ID<\/strong> &#8211; <em>session-scoped<\/em> Custom Dimension that collects a randomized Session ID<\/p>\n<\/li>\n<li>\n<p><strong>Hit Timestamp<\/strong> &#8211; <em>hit-scoped<\/em> Custom Dimension that collects the actual timestamp of each hit in local time, with the timezone offset included<\/p>\n<\/li>\n<li>\n<p><strong>User ID<\/strong> &#8211; <em>hit-scoped<\/em> Custom Dimension that collects the User ID that gets set when someone logs into your website<\/p>\n<\/li>\n<\/ol>\n<div style=\"aspect-ratio: 645 \/ 221;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/03\/Custom-dimensions.jpg\" title=\"Custom Dimensions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"221\" width=\"645\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/03\/Custom-dimensions.jpg#ZgotmplZ\" alt=\"Custom Dimensions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Why a hit-scoped Custom Dimension for User ID, you ask? Well, the whole privacy discussion around user tracking is complicated, and I would rather be poked repeatedly in the eye with a dead ferret than be drawn into it. By tracking User ID with a hit-scoped Custom Dimension, you\u2019ll only collect the data from <em>logged-in users<\/em>. As soon as they log out, or if they re-enter the website having logged out, User ID will not be sent with the hits. If the Custom Dimension were <em>session-scoped<\/em>, or even <em>user-scoped<\/em>, you would be collecting User ID for potentially logged-out visitors as well, and that might be in the grey area privacy-wise.<\/p>\n<p>The end result of combining all this information will be something like this:<\/p>\n<div style=\"aspect-ratio: 696 \/ 249;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/data-export.jpg\" title=\"Example of a data export\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"249\" width=\"696\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/data-export.jpg#ZgotmplZ\" alt=\"Example of a data export\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In this (fictional) data export, you can see 7 unique hits, made by two different client IDs (e.g. different browsers or devices), which span across three distinct sessions, but are all made by the same, logged-in user. With layered information like this, you can build intelligent models using GA data alone, but the possibilities it offers for data integration are remarkable as well.<\/p>\n<p>The most difficult one of these solutions to implement, by far, is Client ID collection, so we\u2019ll start with that.<\/p>\n<h2 id=\"2-client-id\">2. Client ID<\/h2>\n<p>(<strong>UPDATE 5 April 2018<\/strong>: I recommend using <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/use-customtask-access-tracker-values-google-tag-manager\/\">this <code>customTask<\/code> method<\/a> instead for sending the Client ID in a Custom Dimension. The tracker object method outlined below is more complicated and far more unreliable. With <code>customTask<\/code>, you can send the Client ID with any tag you want, with 100% accuracy each time.)<\/p>\n<p>The difficulty with Client ID is that the <code>ga<\/code> interface you use to retrieve the Client ID doesn\u2019t perform well in real time, especially for Tags firing very early in the page load sequence (e.g. your Page View Tag).<\/p>\n<p>You <em>could<\/em> get the Client ID from browser cookies, but if it\u2019s a first-time visitor to your site, chances are that the cookie hasn\u2019t been set by the time the Page View Tag fires, and you\u2019ll miss this information. Also, if there are multiple trackers on the page, how do you know which <code>_ga<\/code> cookie to access? You don\u2019t.<\/p>\n<p>So, I\u2019ve opted for a different approach. I\u2019m sending the Client ID using a <strong>non-interaction Event Tag<\/strong>, which fires when the page has loaded. This almost certainly guarantees that the <code>ga<\/code> interface is up and running, and I can use it to pull the Client ID for the correct tracker. The correct tracker is identified by querying the property ID (UA-XXXXXX-X) associated with the tracker object.<\/p>\n<p>This particular data collection method will require the following ingredients:<\/p>\n<ul>\n<li>\n<p><strong>Session-scoped Custom Dimension<\/strong>, to collect the data in Google Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Custom JavaScript Variable<\/strong>, which gets the correct Client ID<\/p>\n<\/li>\n<li>\n<p><strong>Window Loaded Trigger<\/strong>, which fires when the window has loaded <em>if<\/em> the Custom JavaScript Variable returns a valid value<\/p>\n<\/li>\n<li>\n<p><strong>Event Tag<\/strong>, which sends a <em>non-interaction<\/em> event to Google Analytics when the Window Loaded Trigger fires<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"21-session-scoped-custom-dimension\">2.1. Session-scoped Custom Dimension<\/h3>\n<p>This one is easy. Browse to the Google Analytics Admin of the web property you want to track to, select <strong>Custom Definitions -&gt; Custom Dimensions<\/strong>, and create a new Custom Dimension that looks like the one below.<\/p>\n<div style=\"aspect-ratio: 370 \/ 310;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/client-id.jpg\" title=\"clientId custom dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"310\" width=\"370\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/client-id.jpg#ZgotmplZ\" alt=\"clientId custom dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The important thing is to choose <strong>Session<\/strong> as the scope, and to make note of the index assigned to it.<\/p>\n<p>Note that if you wish, you could just as well scope this to <strong>User<\/strong> instead. The Client ID, by definition, is the same for the user throughout, so it might make sense to scope it accordingly. User-scoped dimensions are a bit questionable in terms of privacy, but in this case I don\u2019t see any issue, as you\u2019re just exposing a dimension that exists anyway. Thanks to Michael Hayes for pointing this out in the comments!<\/p>\n<h3 id=\"22-custom-javascript-variable\">2.2. Custom JavaScript Variable<\/h3>\n<p>The Custom JavaScript Variable is named <strong>{{Get Client ID for current Tracker}}<\/strong>, and it needs the following code:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">try<\/span> {\n    <span style=\"color:#00a\">var<\/span> trackers = ga.getAll();\n    <span style=\"color:#00a\">var<\/span> i, len;\n    <span style=\"color:#00a\">for<\/span> (i = <span style=\"color:#099\">0<\/span>, len = trackers.length; i 1) {\n      <span style=\"color:#00a\">if<\/span> (trackers[i].get(<span style=\"color:#a50\">'trackingId'<\/span>) === {{GA Tracking Code}}) {\n        <span style=\"color:#00a\">return<\/span> trackers[i].get(<span style=\"color:#a50\">'clientId'<\/span>);\n      }\n    }\n  } <span style=\"color:#00a\">catch<\/span>(e) {}  \n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#a50\">'false'<\/span>;\n}\n<\/code><\/pre>\n<\/div>\n<p>The function contents are wrapped in a <code>try...catch<\/code> block, so any errors and problems with loading the <code>ga<\/code> interface are gobbled up. If you want, you can add your own error debugging code into the <code>catch<\/code> block. The key thing is to make sure the Event Tag doesn\u2019t fire if there\u2019s a problem with retrieving the Client ID. This means that you might miss some hits, but since we\u2019re sending the information to a <em>session-scoped<\/em> Custom Dimension, you only need one successful hit sent during the session.<\/p>\n<p>The code is designed so that it cycles through all the GA trackers on the page. Once it encounters a tracker object which tracks to the property ID returned by the <strong>{{GA Tracking Code}}<\/strong> variable, it returns the Client ID associated with this object.<\/p>\n<p>This means that you will need to have a variable called <strong>{{GA Tracking Code}}<\/strong>, which returns a valid property ID (UA-XXXXXX-X). On my website, for example, it\u2019s a Lookup Table Variable, which returns my main property ID for everyone else, but for me it returns a different property ID. This is because I use this secondary property for debugging implementations.<\/p>\n<h3 id=\"23-window-loaded-trigger\">2.3. Window Loaded Trigger<\/h3>\n<p>The Window Loaded Trigger is pretty simple. It\u2019s your basic Page View Trigger, where you set the Trigger Type to <strong>Window Loaded<\/strong>. However, you will need an additional condition in it.<\/p>\n<div style=\"aspect-ratio: 738 \/ 422;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/window-loaded-trigger.jpg\" title=\"Window Loaded Trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"422\" width=\"738\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/window-loaded-trigger.jpg#ZgotmplZ\" alt=\"Window Loaded Trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The condition <strong><em>Get Client ID for current Tracker<\/em> does not equal false<\/strong> ensures that the Trigger only fires if the Custom JavaScript Variable you just created returns a valid value.<\/p>\n<h3 id=\"24-event-tag\">2.4. Event Tag<\/h3>\n<p>The Event Tag is very basic, except for two customizations. First, you need set its <strong>Non-Interaction<\/strong> value to <strong>true<\/strong>. This prevents the Event from being calculated into interaction metrics like Session Duration and Bounce Rate.<\/p>\n<p>Also, you\u2019ll need to add a Custom Dimension to the Tag, via <strong>More Settings -&gt; Custom Dimensions<\/strong>. Add the index number of the dimension you created in step 1 to the <strong>Index<\/strong> field, and add the Variable reference you created in step 2 to the Value field.<\/p>\n<div style=\"aspect-ratio: 798 \/ 341;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/event-tag.jpg\" title=\"Event Tag for Client ID\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"341\" width=\"798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/event-tag.jpg#ZgotmplZ\" alt=\"Event Tag for Client ID\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>You can see how the fields should look from the image above.<\/p>\n<h3 id=\"25-end-result\">2.5. End result<\/h3>\n<p>If you did everything correctly, you should see your sessions populating with a new Custom Dimension that you can add to your reports, and pull out of GA via the API or via the reporting interface, if you wish.<\/p>\n<div style=\"aspect-ratio: 649 \/ 364;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/client-id-as-dimension.jpg\" title=\"Client ID as Custom Dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"364\" width=\"649\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/client-id-as-dimension.jpg#ZgotmplZ\" alt=\"Client ID as Custom Dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The dimension contains the Client ID of the visitor. You can then use this in your backend, for example, when you want to stitch hits sent from the same <code>_ga<\/code> cookie together in meaningful ways.<\/p>\n<h2 id=\"3-session-id\">3. Session ID<\/h2>\n<p>For Session ID, we\u2019re using a randomized string that is sent with each Pageview hit to Google Analytics. The string changes with each Pageview, but this doesn\u2019t matter. Because you\u2019re sending it to a session-scoped Custom Dimension, only the last value you send will be applied to the hits in the session.<\/p>\n<p>The required components are:<\/p>\n<ul>\n<li>\n<p><strong>Session-scoped Custom Dimension<\/strong>, to collect the data in Google Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Custom JavaScript Variable<\/strong>, which returns a valid Session ID string<\/p>\n<\/li>\n<li>\n<p><strong>Small modification to your Page View Tag<\/strong>, so that the Session ID is sent to Google Analytics<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"31-session-scoped-custom-dimension\">3.1. Session-scoped Custom Dimension<\/h3>\n<p>This is pretty much the same step you went through in the previous exercise.<\/p>\n<div style=\"aspect-ratio: 368 \/ 297;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/session-id.jpg\" title=\"Session ID Custom Dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"297\" width=\"368\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/session-id.jpg#ZgotmplZ\" alt=\"Session ID Custom Dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Just remember to make note of the index number, again.<\/p>\n<h3 id=\"32-custom-javascript-variable\">3.2. Custom JavaScript Variable<\/h3>\n<p>The Custom JavaScript Variable is aptly named <strong>{{Random Session ID}}<\/strong>, and it has the following code:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n    <span style=\"color:#00a\">return<\/span> <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>().getTime() + <span style=\"color:#a50\">'.'<\/span> + <span style=\"color:#0aa\">Math<\/span>.random().toString(<span style=\"color:#099\">36<\/span>).substring(<span style=\"color:#099\">5<\/span>);\n}\n<\/code><\/pre>\n<\/div>\n<p>This script creates a pretty unique, randomized session ID. It does it by taking the hit timestamp in Unix time, adding a period, and following with a random string of alphanumeric characters. Because of the timestamp (accurate up to milliseconds), it\u2019s very improbable that two similar session IDs are ever created.<\/p>\n<p>An example of a session ID would be: <strong>1427856715104.jdubr7umobt9<\/strong>.<\/p>\n<h3 id=\"33-modified-page-view-tag\">3.3. Modified Page View Tag<\/h3>\n<p>In your Page View Tag, add a new Custom Dimension under <strong>More Settings -&gt; Custom Dimensions<\/strong>. Set the index number you got from step 1, and set the value to the Variable reference <strong>{{Random Session ID}}<\/strong> you just created.<\/p>\n<p>By using only the Page View Tag, you\u2019ll be sending the Session ID with each page load. Only the last Session ID you send will remain, however, and all the hits in the session will automatically be annotated with this ID, thanks to the session-scoped Custom Dimension. If this is confusing, remember to <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/platform\/customdimsmets\">read up on Custom Dimensions<\/a>!<\/p>\n<h3 id=\"34-end-result\">3.4. End result<\/h3>\n<p>By virtue of the Custom Dimension, you now have an identifier with which you can stitch together arbitrary, discrete hits in Google Analytics.<\/p>\n<div style=\"aspect-ratio: 654 \/ 418;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/session-id-table.jpg\" title=\"Session ID in a table\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"418\" width=\"654\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/session-id-table.jpg#ZgotmplZ\" alt=\"Session ID in a table\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Together with the hit timestamp, you can start building realistic visit paths, if that suits your fancy.<\/p>\n<h2 id=\"4-hit-timestamp\">4. Hit timestamp<\/h2>\n<p>Hit timestamp is something you should send with every single hit you send to Google Analytics. This means that you\u2019ll need to modify all your Google Analytics Tags, which might seem like a chore.<\/p>\n<p>Accuracy is, of course, completely up to you, and you can opt to only send the timestamp with Pageviews and Transactions, instead.<\/p>\n<p>What you\u2019ll need:<\/p>\n<ul>\n<li>\n<p><strong>Hit-scoped Custom Dimension<\/strong>, to collect the timestamp in Google Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Custom JavaScript Variable<\/strong>, which returns a valid timestamp string<\/p>\n<\/li>\n<li>\n<p><strong>Modification to all your tags<\/strong>, to which you want the timestamp to be attached<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"41-hit-scoped-custom-dimension\">4.1. Hit-scoped Custom Dimension<\/h3>\n<p>There\u2019s nothing spectacular about this one. Create a new Custom Dimension in GA Admin, and set its scope to <strong>Hit<\/strong>.<\/p>\n<div style=\"aspect-ratio: 369 \/ 298;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/hit-timestamp.jpg\" title=\"Hit timestamp custom dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"298\" width=\"369\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/hit-timestamp.jpg#ZgotmplZ\" alt=\"Hit timestamp custom dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Remember to make note of the index.<\/p>\n<h3 id=\"42-custom-javascript-variable\">4.2. Custom JavaScript Variable<\/h3>\n<p>The Custom JavaScript Variable needs to return the timestamp in String format. Now, there are many ways you could do this, for example:<\/p>\n<ul>\n<li>\n<p>Get timestamp in Unix time (milliseconds since Jan 1, 1970), adjusted for client timezone<\/p>\n<\/li>\n<li>\n<p>Get timestamp in Unix time, converted to UTC<\/p>\n<\/li>\n<li>\n<p>Get timestamp as an ISO string, adjusted for client timezone<\/p>\n<\/li>\n<li>\n<p>Get timestamp as an ISO string, converted to UTC<\/p>\n<\/li>\n<li>\n<p>Get custom string, adjusted for local time or converted to UTC<\/p>\n<\/li>\n<li>\n<p>Something completely different<\/p>\n<\/li>\n<\/ul>\n<p>In my setup, I wanted the timestamp to be customized for my own tastes. That means that I\u2019m parsing it to resemble an ISO timestamp, but I\u2019m using client local time including the timezone offset, so I can see just which timezone the user is in. So, for example, if a visitor comes from Finland, which is GMT+3 (stupid daylight savings time), the hit timestamp might look like this:<\/p>\n<p><strong>2015-04-03T18:55:27.466+03:00<\/strong><\/p>\n<p>This translates to April 3rd, 2015, at 6:55PM Helsinki time.<\/p>\n<p><em>Thanks to <a href=\"https:\/\/www.aivosto.com\/\"><strong>Tuomas Salste<\/strong><\/a> for spotting a couple of bugs in the code!.<\/em><\/p>\n<p>So, to get something like this, some JavaScript is required. Create a new Custom JavaScript Variable, and name it <strong>{{Hit Timestamp Local Time With Offset}}<\/strong>. Add the following code within:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n    <span style=\"color:#aaa;font-style:italic\">\/\/ Get local time as ISO string with offset at the end\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">var<\/span> now = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>();\n    <span style=\"color:#00a\">var<\/span> tzo = -now.getTimezoneOffset();\n    <span style=\"color:#00a\">var<\/span> dif = tzo &gt;= <span style=\"color:#099\">0<\/span> ? <span style=\"color:#a50\">'+'<\/span> : <span style=\"color:#a50\">'-'<\/span>;\n    <span style=\"color:#00a\">var<\/span> pad = <span style=\"color:#00a\">function<\/span>(num, ms) {\n        <span style=\"color:#00a\">var<\/span> norm = <span style=\"color:#0aa\">Math<\/span>.floor(<span style=\"color:#0aa\">Math<\/span>.abs(num));\n        <span style=\"color:#00a\">if<\/span> (ms) <span style=\"color:#00a\">return<\/span> (norm 10 ? <span style=\"color:#a50\">'00'<\/span> : norm 100 ? <span style=\"color:#a50\">'0'<\/span> : <span style=\"color:#a50\">''<\/span>) + norm;\n        <span style=\"color:#00a\">return<\/span> (norm 10 ? <span style=\"color:#a50\">'0'<\/span> : <span style=\"color:#a50\">''<\/span>) + norm;\n    };\n    <span style=\"color:#00a\">return<\/span> now.getFullYear() \n        + <span style=\"color:#a50\">'-'<\/span> + pad(now.getMonth()+<span style=\"color:#099\">1<\/span>)\n        + <span style=\"color:#a50\">'-'<\/span> + pad(now.getDate())\n        + <span style=\"color:#a50\">'T'<\/span> + pad(now.getHours())\n        + <span style=\"color:#a50\">':'<\/span> + pad(now.getMinutes()) \n        + <span style=\"color:#a50\">':'<\/span> + pad(now.getSeconds())\n        + <span style=\"color:#a50\">'.'<\/span> + pad(now.getMilliseconds(), <span style=\"color:#00a\">true<\/span>)\n        + dif + pad(tzo \/ <span style=\"color:#099\">60<\/span>) \n        + <span style=\"color:#a50\">':'<\/span> + pad(tzo % <span style=\"color:#099\">60<\/span>);\n}\n<\/code><\/pre>\n<\/div>\n<p>This code has been gratefully copy-pasted form <a href=\"http:\/\/stackoverflow.com\/a\/17415677\">this StackOverflow discussion<\/a>.<\/p>\n<p>This script works across all browsers, and returns a parsed string timestamp, with the timezone offset appended to the string.<\/p>\n<h3 id=\"43-modified-tags\">4.3. Modified Tags<\/h3>\n<p>I send this timestamp with every single Tag that\u2019s firing on my site, but if you feel like this is overkill, you can choose to only send it with business-critical hits you\u2019ll use with other backend data, for example.<\/p>\n<p>The only thing you need to do is add the Custom Dimension to any Tag you want to send it with. The setting looks like this:<\/p>\n<div style=\"aspect-ratio: 798 \/ 339;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/timestamp-in-tag.jpg\" title=\"Timestamp as a Custom Dimension in the Tags\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"339\" width=\"798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/timestamp-in-tag.jpg#ZgotmplZ\" alt=\"Timestamp as a Custom Dimension in the Tags\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Remember to set the Index accordingly. Go back to Google Analytics Admin, and look for the Custom Dimension you created in Step 1 to get the correct index number.<\/p>\n<h3 id=\"44-end-result\">4.4. End result<\/h3>\n<p>What you\u2019ll get is something like this:<\/p>\n<div style=\"aspect-ratio: 710 \/ 401;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/timestamp-with-transactions.jpg\" title=\"Timestamp with transactions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"401\" width=\"710\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/timestamp-with-transactions.jpg#ZgotmplZ\" alt=\"Timestamp with transactions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>It\u2019s all your transactions, coupled with the accurate hit timestamp in local time when the transaction was recorded. The timezone offset helps you compare data with your backend, if it uses server time or some fixed timezone in its own data collection.<\/p>\n<h2 id=\"5-user-id\">5. User ID<\/h2>\n<p>For User ID, you\u2019ll need to have it already implemented in some way or another. In this example, we\u2019ll pull the ID from <code>dataLayer<\/code>, but you might be using a 1st Party Cookie instead, which means you\u2019ll need to modify the code accordingly.<\/p>\n<p>Remember that tracking Users across sessions and devices is a tricky business both technologically and ethically. I\u2019ll leave things like <em>consent<\/em>, <em>opt-out<\/em>, <em>anonymisation<\/em>, and <em>privacy<\/em> to linger in the nether regions of your mind, so remember to ensure that what you\u2019re doing is considered OK by at least one other person in the right state of mind.<\/p>\n<p>We\u2019re using a hit-scoped Custom Dimension again, but you can choose what level of accuracy and stitching to implement. I\u2019ve reasoned for hit-level accuracy in the beginning of this article (wow, that was a LONG time ago), and I think the reasoning is well-founded. Also, depending on what you want to do with the data in the backend, you might choose to send the User ID with <em>all<\/em> hits or with just <em>some<\/em> hits.<\/p>\n<p>To expose User ID as a Custom Dimension in your hits, you\u2019ll need:<\/p>\n<ul>\n<li>\n<p><strong>Hit-scoped Custom Dimension<\/strong>, to collect the User ID in Google Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Data Layer Variable<\/strong>, which picks up the User ID from <code>dataLayer<\/code><\/p>\n<\/li>\n<li>\n<p><strong>Modified Tags<\/strong>, to which you want the User ID to be attached<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"51-hit-scoped-custom-dimension\">5.1. Hit-scoped Custom Dimension<\/h3>\n<p>The Custom Dimension is simple, of course. Just go to Google Analytics Admin, browse to Custom Definitions under the web property you want to set this up with, and create a new Custom Dimension of <strong>Hit<\/strong> scope:<\/p>\n<div style=\"aspect-ratio: 359 \/ 288;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/user-id-custom-dimension.jpg\" title=\"User ID Hit Custom Dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"288\" width=\"359\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/user-id-custom-dimension.jpg#ZgotmplZ\" alt=\"User ID Hit Custom Dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As before, make note of the Index.<\/p>\n<h3 id=\"52-data-layer-variable\">5.2. Data Layer Variable<\/h3>\n<p>How you actually retrieve the User ID depends on how you expose it in your website. A very good method is to populate it in <code>dataLayer<\/code> by a server-side process, which renders it together with the rest of the page. This way the User ID will be cemented in the page template, and you can use it with your critical tags that fire early on in the page load sequence.<\/p>\n<p>I use <code>dataLayer<\/code> to implement User ID, so all I need to create is a Data Layer Variable that picks up the User ID from the data model, and returns the value stored within. On my site, the variable is named <strong>{{DLV &#8211; userId}}<\/strong>, and it looks like this:<\/p>\n<div style=\"aspect-ratio: 399 \/ 470;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/datalayer-user-id.jpg\" title=\"userId in Data Layer\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"470\" width=\"399\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/datalayer-user-id.jpg#ZgotmplZ\" alt=\"userId in Data Layer\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As you can see, I\u2019m not setting a default value in the Variable. This means that if <strong>userId<\/strong> is <em>not<\/em> set in <code>dataLayer<\/code>, this Variable will resolve to <em>undefined<\/em>, and the Custom Dimension will be dropped from any Tag that uses it. This is a <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/undefined-dimensions-wont-get-sent\/\">wonderful feature<\/a> of the <em>analytics.js<\/em> library, and it really helps in keeping your Tag setup nice and lean.<\/p>\n<h3 id=\"53-modified-tags\">5.3. Modified Tags<\/h3>\n<p>Next, add the Variable you just created into all the Tags you want to associate with logged in users. I send it with every single hit, because I want a comprehensive analysis of what my visitors do on the site.<\/p>\n<div style=\"aspect-ratio: 798 \/ 342;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/tag-custom-dimension-userId.jpg\" title=\"User ID as a custom dimension\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"342\" width=\"798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/tag-custom-dimension-userId.jpg#ZgotmplZ\" alt=\"User ID as a custom dimension\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Remember to set the Index correctly according to what you setup earlier in Google Analytics Admin.<\/p>\n<h3 id=\"54-end-result\">5.4. End result<\/h3>\n<p>What you\u2019ll get is an extra annotation on all your hits from logged in users:<\/p>\n<div style=\"aspect-ratio: 698 \/ 269;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2015\/04\/user-id-in-reports.jpg\" title=\"User ID in reports\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"269\" width=\"698\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2015\/04\/user-id-in-reports.jpg#ZgotmplZ\" alt=\"User ID in reports\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Now, let\u2019s not kid ourselves. If you\u2019re sending User ID with just a handful of hits, and you\u2019re also collecting Client ID, you can extrapolate User ID in your backend to all the hits done by the Client IDs associated with the User ID dimension. Like I wrote in the beginning of this article, the ethical, legal, and privacy-related considerations are yours to make alone.<\/p>\n<h2 id=\"6-summary\">6. Summary<\/h2>\n<p>This article explores something I feel passionate about: meaningful data collection. Google Analytics uses a lot of information that isn\u2019t exposed in the reporting interface or the APIs, even though this information is central to how the platform aggregates the hits coming in from digital properties.<\/p>\n<p>Being able to access this type of granular data shouldn\u2019t be reserved for BigQuery users alone, so the solutions in this post help you add an extra level of accuracy to the stream of data flowing to the tracking platform. You can then pull this data out, combine it with other backend data, and build powerful models that will allow you to optimize your digital properties better than before.<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Since writing my rant about the schema conspiracy of web analytics platforms, I\u2019ve been giving the whole idea of hit-level data collection a lot of thought. Sessionization is very heavily implemented in Google Analytics, which is understandable, but the regular Google Analytics API just doesn\u2019t give you the kind of information you\u2019d need, if you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":148379,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[2224,834,11603,25354,12638],"dealstore":[],"offerexpiration":[],"class_list":["post-148378","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-collection","tag-custom","tag-data","tag-dimensions","tag-improve"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Improve Data Collection With Four Custom Dimensions - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=148378\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Improve Data Collection With Four Custom Dimensions - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"Since writing my rant about the schema conspiracy of web analytics platforms, I\u2019ve been giving the whole idea of hit-level data collection a lot of thought. Sessionization is very heavily implemented in Google Analytics, which is understandable, but the regular Google Analytics API just doesn\u2019t give you the kind of information you\u2019d need, if you [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=148378\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-21T20:32:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"645\" \/>\n\t<meta property=\"og:image:height\" content=\"221\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=148378#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Improve Data Collection With Four Custom Dimensions\",\"datePublished\":\"2025-03-21T20:32:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378\"},\"wordCount\":3146,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg\",\"keywords\":[\"Collection\",\"Custom\",\"Data\",\"Dimensions\",\"improve\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=148378#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=148378\",\"url\":\"https:\/\/fivemor.com\/?p=148378\",\"name\":\"Improve Data Collection With Four Custom Dimensions - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg\",\"datePublished\":\"2025-03-21T20:32:27+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=148378#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=148378\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=148378#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg\",\"width\":645,\"height\":221},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=148378#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Improve Data Collection With Four Custom Dimensions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Improve Data Collection With Four Custom Dimensions - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=148378","og_locale":"en_US","og_type":"article","og_title":"Improve Data Collection With Four Custom Dimensions - Som2ny Network","og_description":"Since writing my rant about the schema conspiracy of web analytics platforms, I\u2019ve been giving the whole idea of hit-level data collection a lot of thought. Sessionization is very heavily implemented in Google Analytics, which is understandable, but the regular Google Analytics API just doesn\u2019t give you the kind of information you\u2019d need, if you [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=148378","og_site_name":"Som2ny Network","article_published_time":"2025-03-21T20:32:27+00:00","og_image":[{"width":645,"height":221,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=148378#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=148378"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Improve Data Collection With Four Custom Dimensions","datePublished":"2025-03-21T20:32:27+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=148378"},"wordCount":3146,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=148378#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg","keywords":["Collection","Custom","Data","Dimensions","improve"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=148378#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=148378","url":"https:\/\/fivemor.com\/?p=148378","name":"Improve Data Collection With Four Custom Dimensions - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=148378#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=148378#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg","datePublished":"2025-03-21T20:32:27+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=148378#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=148378"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=148378#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/Custom-dimensions.jpg","width":645,"height":221},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=148378#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Improve Data Collection With Four Custom Dimensions"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/148378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=148378"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/148378\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/148379"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=148378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=148378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=148378"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=148378"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=148378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}