{"id":34584,"date":"2024-06-27T07:00:00","date_gmt":"2024-06-27T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=34584"},"modified":"2024-07-08T11:52:18","modified_gmt":"2024-07-08T18:52:18","slug":"add-unique-viewer-analytics-video-nuxtjs","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs","title":{"rendered":"Add Unique Viewer Analytics to Your Video in Nuxt.js"},"content":{"rendered":"\n<p>You can integrate unique video viewer analytics to understand video engagement, enhance the viewer experience, and optimize your video&#8217;s performance. This will provide valuable insights into how users engage with your videos, track views, and optimize your video strategy for conversion.<\/p>\n\n\n\n<p>In this tutorial, you\u2019ll learn how to add unique video viewer analytics to your video in Nuxt.js using the <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/video_analytics\" rel=\"noreferrer noopener\">Cloudinary video analytics<\/a> library. Simply put, you\u2019ll display all your video\u2019s unique views on the page.<\/p>\n\n\n\n<p><a href=\"https:\/\/cloudinary.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a> provides a comprehensive and secure API for tracking video analytics and uploading media files quickly and efficiently from the server side, the browser, or a mobile application.<\/p>\n\n\n\n<p>Check out the Github repository <a href=\"https:\/\/github.com\/Olanetsoft\/cloudinary-video-analytics-in-nuxt\">here<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>You should have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Node.js installed on your computer.<\/li>\n\n\n\n<li>Knowledge of Nuxt.js.<\/li>\n\n\n\n<li>An understanding of JavaScript.<\/li>\n\n\n\n<li>A free <a href=\"https:\/\/cloudinary.com\/users\/register\/free?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary account<\/a>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Set Up the Project and Install Dependencies<\/h2>\n\n\n\n<p>We provide a starter project to help you speed through to the analytics implementation. Clone the <a target=\"_blank\" href=\"https:\/\/github.com\/Olanetsoft\/cloudinary-video-analytics-in-nuxt\" rel=\"noreferrer noopener\">starter project<\/a> into your preferred folder and checkout to the starter branch using the git commands below.&nbsp;<\/p>\n\n\n\n<p>The project contains a video served by Cloudinary, to which you will add unique viewer analytics.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">git <span class=\"hljs-keyword\">clone<\/span> https:<span class=\"hljs-comment\">\/\/github.com\/Olanetsoft\/cloudinary-video-analytics-in-nuxt.git<\/span>\ncd cloudinary-video-analytics-in-nuxt\ngit checkout starter<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Run the following command to install all dependencies using the npm package manager and start the project on <a href=\"http:\/\/localhost:3000\/\" target=\"_blank\" rel=\"noreferrer noopener\"><u>http:\/\/localhost:3000<\/u><\/a>.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">npm install &amp;&amp; npm run dev<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Get Environment Variables From Cloudinary&nbsp;<\/h2>\n\n\n\n<p>Log in to your Cloudinary dashboard to retrieve product environment credentials such as the <strong>cloud name<\/strong>, <strong>API key<\/strong>, and <strong>API secret<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"445\" data-public-id=\"Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_445,c_scale\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA\" alt=\"\" class=\"wp-post-34584 wp-image-34585\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1719432365\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719432365\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-1.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Then, create an <code>.env<\/code> file in the root folder of the project using the following command:<\/p>\n\n\n\n<p>For macOS and Linux:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">touch<\/span> <span class=\"hljs-selector-class\">.env<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>For Windows(Command Prompt):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">type<\/span> <span class=\"hljs-selector-tag\">NUL<\/span> &gt; <span class=\"hljs-selector-class\">.env<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>For Windows(PowerShell):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">New-Item<\/span> <span class=\"hljs-selector-tag\">-Path<\/span> <span class=\"hljs-selector-class\">.env<\/span> <span class=\"hljs-selector-tag\">-ItemType<\/span> <span class=\"hljs-selector-tag\">File<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Add your product environment credentials:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\nCLOUDINARY_CLOUD_NAME=<span class=\"hljs-string\">\"*********************\"<\/span>\nNUXT_ENV_CLOUDINARY_PUBLIC_ID=<span class=\"hljs-string\">\"*********************\"<\/span>\nNUXT_ENV_CLOUDINARY_API_KEY=<span class=\"hljs-string\">\"*********************\"<\/span>\nNUXT_ENV_CLOUDINARY_API_SECRET=<span class=\"hljs-string\">\"*********************\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Replace <code>*********************<\/code> with your credentials.<\/p>\n\n\n\n<p>Add <code>samples\/sea-turtle<\/code> to your <code>.env<\/code> as your <code>NUXT_ENV_CLOUDINARY_PUBLIC_ID<\/code> for this tutorial.&nbsp;<\/p>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>For this demo, we took a video already on Cloudinary. In your implementation, you should have handled the video upload to Cloudinary and retrieved the video\u2019s public ID on the front end.<\/p>\n<\/div>\n\n\n<p>You can access your media library on Cloudinary to obtain a public ID for your video. To do this, go to the <strong>Media Library<\/strong> on your dashboard.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"344\" data-public-id=\"Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_344,c_scale\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA\" alt=\"\" class=\"wp-post-34584 wp-image-34587\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1719436089\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436089\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-2.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, copy the link.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"371\" data-public-id=\"Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_371,c_scale\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA\" alt=\"\" class=\"wp-post-34584 wp-image-34588\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1719436084\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436084\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-3.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The link you copied should look like this: <code>https:\/\/res.cloudinary.com\/&lt;your-cloud-name&gt;\/video\/upload\/v1554336425\/&lt;public_id&gt;.mp4<\/code>. Add the <code>public_id<\/code> value to your <code>.env<\/code>.<\/p>\n\n\n\n<p>Next, if you navigate to <a href=\"http:\/\/localhost:3000\/\" target=\"_blank\" rel=\"noreferrer noopener\"><u>http:\/\/localhost:3000<\/u><\/a>, you should see a page similar to what is shown below if you used samples\/sea-turtle as the public ID. That&#8217;s all you need to get started.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"792\" data-public-id=\"Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_792,c_scale\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA\" alt=\"\" class=\"wp-post-34584 wp-image-34589\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1719436079\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436079\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-4.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Implement a Function to Fetch Video Analytics<\/h2>\n\n\n\n<p>The <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_video_player\" rel=\"noreferrer noopener\">Cloudinary Video Player<\/a> automatically collects metrics for all videos delivered through it. To collect analytics for videos not delivered through the Cloudinary Video Player, you can install the <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#video_analytics_for_other_players\" rel=\"noreferrer noopener\">JavaScript library<\/a> and configure it on any page with a video player or by accessing video view <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#access_video_views_data_programmatically\" rel=\"noreferrer noopener\">data programmatically<\/a>.<\/p>\n\n\n\n<p>In this next step, you\u2019ll learn how to access video view data programmatically within your Nuxt.js application.&nbsp;<\/p>\n\n\n\n<p>Create a folder inside the <strong>server<\/strong> directory called <strong>api<\/strong> and add a file named <strong>fetchAnalyticsData.js<\/strong>. In this file, you&#8217;ll define a <em>serverless function<\/em> to send API requests to <code>https:\/\/api.cloudinary.com\/v1_1\/&lt;cloud name&gt;\/video\/analytics\/views?expression=video_public_id=&lt;public id&gt;<\/code> with your cloud name, video public ID, API key, and API secret to retrieve the analytics data. You can learn more about the <a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#endpoint\" target=\"_blank\" rel=\"noreferrer noopener\">parameters<\/a>.<\/p>\n\n\n\n<p>The following code snippet makes an API request to retrieve video analytics data inside the <code>fetchAnalyticsData.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ server\/api\/fetchAnalyticsData.js<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> defineEventHandler(<span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> {\n    CLOUDINARY_CLOUD_NAME,\n    NUXT_ENV_CLOUDINARY_PUBLIC_ID,\n    NUXT_ENV_CLOUDINARY_API_KEY,\n    NUXT_ENV_CLOUDINARY_API_SECRET,\n  } = process.env;\n\n  <span class=\"hljs-keyword\">const<\/span> cloudinaryUrl = <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v1_1\/<span class=\"hljs-subst\">${CLOUDINARY_CLOUD_NAME}<\/span>\/video\/analytics\/views?expression=video_public_id=<span class=\"hljs-subst\">${NUXT_ENV_CLOUDINARY_PUBLIC_ID}<\/span>&amp;max_results=500`<\/span>;\n\n  <span class=\"hljs-keyword\">const<\/span> authorizationHeader = <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${Buffer.<span class=\"hljs-keyword\">from<\/span>(\n    <span class=\"hljs-string\">`<span class=\"hljs-subst\">${NUXT_ENV_CLOUDINARY_API_KEY}<\/span>:<span class=\"hljs-subst\">${NUXT_ENV_CLOUDINARY_API_SECRET}<\/span>`<\/span>\n  ).toString(<span class=\"hljs-string\">\"base64\"<\/span>)}<\/span>`<\/span>;\n\n  <span class=\"hljs-keyword\">let<\/span> response;\n  <span class=\"hljs-keyword\">try<\/span> {\n    response = <span class=\"hljs-keyword\">await<\/span> fetch(cloudinaryUrl, {\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-attr\">Authorization<\/span>: authorizationHeader,\n      },\n    });\n  } <span class=\"hljs-keyword\">catch<\/span> (fetchError) {\n    <span class=\"hljs-keyword\">throw<\/span> createError({\n      <span class=\"hljs-attr\">statusCode<\/span>: <span class=\"hljs-number\">502<\/span>,\n      <span class=\"hljs-attr\">statusMessage<\/span>: <span class=\"hljs-string\">\"Failed to fetch analytics data from Cloudinary\"<\/span>,\n    });\n  }\n\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n    <span class=\"hljs-keyword\">return<\/span> data;\n  } <span class=\"hljs-keyword\">catch<\/span> (parseError) {\n    <span class=\"hljs-keyword\">throw<\/span> createError({\n      <span class=\"hljs-attr\">statusCode<\/span>: <span class=\"hljs-number\">500<\/span>,\n      <span class=\"hljs-attr\">statusMessage<\/span>: <span class=\"hljs-string\">\"Failed to parse analytics data\"<\/span>,\n    });\n  }\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To aid troubleshooting, handle errors in case the request fails.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ server\/api\/fetchAnalyticsData.js<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> defineEventHandler(<span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n  <span class=\"hljs-comment\">\/\/...<\/span>\n\n  <span class=\"hljs-keyword\">if<\/span> (\n    !CLOUDINARY_CLOUD_NAME ||\n    !NUXT_ENV_CLOUDINARY_PUBLIC_ID ||\n    !NUXT_ENV_CLOUDINARY_API_KEY ||\n    !NUXT_ENV_CLOUDINARY_API_SECRET\n  ) {\n    <span class=\"hljs-keyword\">throw<\/span> createError({\n      <span class=\"hljs-attr\">statusCode<\/span>: <span class=\"hljs-number\">500<\/span>,\n      <span class=\"hljs-attr\">statusMessage<\/span>: <span class=\"hljs-string\">\"Cloudinary environment variables are not set\"<\/span>,\n    });\n  }\n\n  <span class=\"hljs-comment\">\/\/...<\/span>\n\n  <span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n    <span class=\"hljs-keyword\">throw<\/span> createError({\n      <span class=\"hljs-attr\">statusCode<\/span>: response.status,\n      <span class=\"hljs-attr\">statusMessage<\/span>: response.statusText,\n    });\n  }\n\n  <span class=\"hljs-comment\">\/\/...<\/span>\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Navigate to the <code>VideoAnalyticsData.vue<\/code> file inside the components folder to implement the <code>fetchAnalyticsData.js<\/code> API.<\/p>\n\n\n\n<p>Inside the VideoAnalyticsData.vue file:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Import <code>ref<\/code>, <code>onMounted<\/code>, and <code>computed<\/code> hooks from Vue.<\/li>\n\n\n\n<li>Define a <code>ref<\/code> called <code>analyticsData<\/code> variable with an initial null value.<\/li>\n\n\n\n<li>Fetch analytics data in the <code>onMounted<\/code> block.<\/li>\n\n\n\n<li>Set the response to the <code>analyticsData<\/code> variable created.<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\n<span class=\"hljs-comment\">&lt;!-- VideoAnalyticsData.vue  --&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n  <span class=\"hljs-comment\">&lt;!-- \/\/... --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">setup<\/span>&gt;<\/span><span class=\"javascript\">\n  <span class=\"hljs-keyword\">import<\/span> { ref, onMounted, computed } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"vue\"<\/span>;\n  \n  <span class=\"hljs-keyword\">const<\/span> analyticsData = ref(<span class=\"hljs-literal\">null<\/span>);\n  \n  onMounted(<span class=\"hljs-keyword\">async<\/span> () =&gt; {\n    <span class=\"hljs-keyword\">try<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">\"\/api\/fetchAnalyticsData\"<\/span>);\n\n      <span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n        <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">\"Failed to fetch analytics data\"<\/span>);\n      }\n      analyticsData.value = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n    } <span class=\"hljs-keyword\">catch<\/span> (error) {\n      <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching analytics data:\"<\/span>, error);\n    }\n  });\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, start your application or check your console to see if your application is still running. You should see something similar to what is shown below (if you logged the data output):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\">\n{ <span class=\"hljs-attribute\">request_id<\/span>: <span class=\"hljs-string\">'c42c30475fd5fd0f4bff9fb8085b7afc'<\/span>,\n  next_cursor: null,\n  data:\n   &#91; \n      { \n         video_public_id: <span class=\"hljs-string\">'samples\/sea-turtle'<\/span>,\n         video_duration: <span class=\"hljs-number\">15<\/span>,\n         video_transformation: <span class=\"hljs-string\">'q_auto\/f_auto:video'<\/span>,\n         video_extension: <span class=\"hljs-string\">''<\/span>,\n         viewer_application_name: <span class=\"hljs-string\">'Chrome'<\/span>,\n         viewer_location_country_code: <span class=\"hljs-string\">'NG'<\/span>,\n         viewer_os_identifier: <span class=\"hljs-string\">'Mac OS X 10.15.7'<\/span>,\n         view_watch_time: <span class=\"hljs-number\">0<\/span>,\n         view_ended_at: <span class=\"hljs-string\">'2024-05-18T23:32:27.000Z'<\/span> \n     },\n     { \n        <span class=\"hljs-attribute\">video_public_id<\/span>: <span class=\"hljs-string\">'samples\/sea-turtle'<\/span>,\n        video_duration: <span class=\"hljs-number\">15<\/span>,\n        video_transformation: null,\n        video_extension: null,\n        viewer_application_name: <span class=\"hljs-string\">'Chrome'<\/span>,\n        viewer_location_country_code: <span class=\"hljs-string\">'NG'<\/span>,\n        viewer_os_identifier: <span class=\"hljs-string\">'Mac OS X 10.15.7'<\/span>,\n        view_watch_time: <span class=\"hljs-number\">1<\/span>,\n        view_ended_at: <span class=\"hljs-string\">'2024-05-18T23:21:27.000Z'<\/span> \n     },\n      ...\n    } \n  ] \n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Add Data for Unique Video Views on the UI&nbsp;<\/h2>\n\n\n\n<p>In this step, you will add the views data returned from the API you implemented. While multiple datapoints are returned, for the sake of this tutorial, you\u2019ll only focus on implementing unique video views.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Navigate to the <code>VideoAnalyticsData.vue<\/code> file.<\/li>\n\n\n\n<li>Use the <code>computed<\/code> hook to implement unique views for the video.<\/li>\n\n\n\n<li>Create a <code>Set<\/code> to store unique view identifiers.<\/li>\n\n\n\n<li>Combine <code>viewer_application_name<\/code> and <code>view_ended_at<\/code> to create a unique key for each view.<\/li>\n\n\n\n<li>Count the number of unique keys in the set to get the total number of unique views.<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\n<span class=\"hljs-comment\">&lt;!-- VideoAnalyticsData.vue  --&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n <span class=\"hljs-comment\">&lt;!-- \/\/... --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">setup<\/span>&gt;<\/span><span class=\"javascript\">\n &lt;!-- <span class=\"hljs-comment\">\/\/...  --&gt;<\/span>\n\n  <span class=\"hljs-keyword\">const<\/span> uniqueViews = computed(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">if<\/span> (!analyticsData.value?.data) <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n\n  <span class=\"hljs-keyword\">const<\/span> uniqueViewSet = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Set<\/span>();\n\n  analyticsData.value.data.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">view<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/ Create a unique identifier for each view<\/span>\n    <span class=\"hljs-keyword\">const<\/span> uniqueKey = <span class=\"hljs-string\">`<span class=\"hljs-subst\">${view.viewer_application_name}<\/span>-<span class=\"hljs-subst\">${view.view_ended_at}<\/span>`<\/span>;\n    uniqueViewSet.add(uniqueKey);\n  });\n\n  <span class=\"hljs-keyword\">return<\/span> uniqueViewSet.size;\n});\n\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Test the Application<\/h2>\n\n\n\n<p>If you&#8217;ve made it this far, congratulations! It&#8217;s time to test the application to verify the unique views feature. Start by clicking to watch the video on your current device. Based on the API response, you should see the unique views count increase after a while.<\/p>\n\n\n\n<p>Try viewing and playing the video on another device or browser to ensure the count accurately reflects unique views. After a while, the video views count should also increase, confirming that the feature works as intended.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"777\" data-public-id=\"Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_777,c_scale\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA\" alt=\"\" class=\"wp-post-34584 wp-image-34590\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1719436074\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1719436074\/Web_Assets\/blog\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5\/blog-Add-Unique-Viewer-Analytics-to-Your-Video-in-Nuxtjs-5.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This blog post teaches you how to add unique video viewer analytics to your video in the Nuxt.js application using the Cloudinary video analytics library. This data could be crucial to making informed content decisions, improving content strategies, and creating a more successful video presence.&nbsp;<\/p>\n\n\n\n<p>If you found this blog post helpful and want to discuss it in more detail, feel free to join the <a target=\"_blank\" href=\"https:\/\/community.cloudinary.com\/\" rel=\"noreferrer noopener\"><u>Cloudinary Community forum<\/u><\/a> and its associated <a target=\"_blank\" href=\"https:\/\/discord.com\/invite\/cloudinary\" rel=\"noreferrer noopener\"><u>Discord<\/u><\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.npmjs.com\/package\/next-cloudinary\" target=\"_blank\" rel=\"noreferrer noopener\">Next Cloudinary<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary video analytics<\/a> library<\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#https:\/\/cloudinary.com\/documentation\/video_analytics#access_video_views_data_programmatically\" target=\"_blank\" rel=\"noreferrer noopener\">Access video analytics data programmatically<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_video_player\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary Video Player<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>You can integrate unique video viewer analytics to understand video engagement, enhance the viewer experience, and optimize your video&#8217;s performance. This will provide valuable insights into how users engage with your videos, track views, and optimize your video strategy for conversion. In this tutorial, you\u2019ll learn how to add unique video viewer analytics to your [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":34592,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[372,303],"class_list":["post-34584","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-nuxtjs","tag-video"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Add Unique Viewer Analytics to Your Video in Nuxt.js<\/title>\n<meta name=\"description\" content=\"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Add Unique Viewer Analytics to Your Video in Nuxt.js\" \/>\n<meta property=\"og:description\" content=\"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-06-27T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-07-08T18:52:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Add Unique Viewer Analytics to Your Video in Nuxt.js\",\"datePublished\":\"2024-06-27T14:00:00+00:00\",\"dateModified\":\"2024-07-08T18:52:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\"},\"wordCount\":875,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA\",\"keywords\":[\"NuxtJS\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\",\"url\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\",\"name\":\"Add Unique Viewer Analytics to Your Video in Nuxt.js\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA\",\"datePublished\":\"2024-06-27T14:00:00+00:00\",\"dateModified\":\"2024-07-08T18:52:18+00:00\",\"description\":\"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Add Unique Viewer Analytics to Your Video in Nuxt.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Add Unique Viewer Analytics to Your Video in Nuxt.js","description":"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.","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:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs","og_locale":"en_US","og_type":"article","og_title":"Add Unique Viewer Analytics to Your Video in Nuxt.js","og_description":"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.","og_url":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs","og_site_name":"Cloudinary Blog","article_published_time":"2024-06-27T14:00:00+00:00","article_modified_time":"2024-07-08T18:52:18+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog-jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Add Unique Viewer Analytics to Your Video in Nuxt.js","datePublished":"2024-06-27T14:00:00+00:00","dateModified":"2024-07-08T18:52:18+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs"},"wordCount":875,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA","keywords":["NuxtJS","Video"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs","url":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs","name":"Add Unique Viewer Analytics to Your Video in Nuxt.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA","datePublished":"2024-06-27T14:00:00+00:00","dateModified":"2024-07-08T18:52:18+00:00","description":"Follow this tutorial to add unique video viewer analytics in Nuxt.js: install dependencies, fetch analytics data, and display unique views.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/add-unique-viewer-analytics-video-nuxtjs#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Add Unique Viewer Analytics to Your Video in Nuxt.js"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718408225\/video_views_nuxtjs-blog\/video_views_nuxtjs-blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=34584"}],"version-history":[{"count":5,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34584\/revisions"}],"predecessor-version":[{"id":34647,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34584\/revisions\/34647"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/34592"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=34584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=34584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=34584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}