{"id":34549,"date":"2024-06-18T07:00:00","date_gmt":"2024-06-18T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=34549"},"modified":"2025-03-23T13:28:18","modified_gmt":"2025-03-23T20:28:18","slug":"add-video-engagement-metrics-nextjs","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs","title":{"rendered":"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0"},"content":{"rendered":"\n<p>Adding video engagement metrics to your video dashboard provides valuable insights into the success of your video content. This tutorial will guide you through adding engagement metrics to your video dashboard using the <a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary video analytics<\/a> library in a Next.js application.<\/p>\n\n\n\n<p>You\u2019ll add the following engagement metrics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Total views.<\/li>\n\n\n\n<li>Engagement rate.<\/li>\n\n\n\n<li>Average watch time in seconds.<\/li>\n\n\n\n<li>Countries.<\/li>\n\n\n\n<li>Applications, e.g., browser.<\/li>\n\n\n\n<li>Operating systems.<\/li>\n<\/ul>\n\n\n\n<p><a target=\"_blank\" href=\"https:\/\/cloudinary.com\/\" rel=\"noreferrer noopener\">Cloudinary<\/a> provides a comprehensive and secure API for tracking video analytics and quickly uploading media files from a server, browser, or mobile application.&nbsp;<\/p>\n\n\n\n<p>Here&#8217;s the <a href=\"https:\/\/github.com\/Olanetsoft\/cloudinary-video-metrics-nextjs\">GitHub repository<\/a>.\u00a0<\/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 Next.js.<\/li>\n\n\n\n<li>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\">Project Setup and Installation<\/h2>\n\n\n\n<p>We\u2019ll provide a starter project to help you speed through to the analytics implementation. The project includes a video hosted by Cloudinary, to which you\u2019ll add engagement metrics. Additionally, the project utilizes <a target=\"_blank\" href=\"https:\/\/www.npmjs.com\/package\/chart.js?activeTab=readme\" rel=\"noreferrer noopener\">chart.js<\/a>, a charting library that enables you to create simple and interactive charts using the HTML5 &lt;canvas&gt; element.&nbsp;<\/p>\n\n\n\n<p>Clone the <a href=\"https:\/\/github.com\/Olanetsoft\/cloudinary-video-metrics-nextjs\" target=\"_blank\" rel=\"noreferrer noopener\">starter project<\/a> into your preferred folder and check out to the starter branch using the following git command.<\/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-metrics-nextjs.git<\/span>\ncd cloudinary-video-metrics-nextjs\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>.\u00a0<\/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-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_445,c_scale\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA\" alt=\"\" class=\"wp-post-34549 wp-image-34550\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1718729145\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729145\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-1.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Then, create a <code>.env.local<\/code> file in the root folder of the project using the following command:<\/p>\n\n\n\n<p><strong>For macOS and Linux:<\/strong><\/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><span class=\"hljs-selector-class\">.local<\/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><strong>For Windows(Command Prompt):<\/strong><\/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><span class=\"hljs-selector-class\">.local<\/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><strong>For Windows(PowerShell):<\/strong><\/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-class\">.local<\/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 credentials to the environment file:<\/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\">NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=<span class=\"hljs-string\">\"*********************\"<\/span>\nNEXT_PUBLIC_CLOUDINARY_API_KEY=<span class=\"hljs-string\">\"*********************\"<\/span>\nNEXT_PUBLIC_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<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>We\u2019ll use a video already on Cloudinary for this demo. In your implementation, you should have handled the video upload to Cloudinary and retrieved the video\u2019s public ID on the frontend.<\/p>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Retrieve the Video\u2019s Public ID<\/h2>\n\n\n\n<p>You can obtain a public ID for your video by accessing your media library on Cloudinary. 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-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_344,c_scale\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png?_i=AA\" alt=\"\" class=\"wp-post-34549 wp-image-34551\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1718729140\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729140\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-2\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-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=\"373\" data-public-id=\"Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_373,c_scale\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png?_i=AA\" alt=\"\" class=\"wp-post-34549 wp-image-34552\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1718729135\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729135\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-3\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-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>\/video\/upload\/v1554336425\/&lt;public_id>.mp4<\/code>. \u00a0Add the <code>public_id<\/code> value to your <code>.env.local<\/code>.\u00a0<\/p>\n\n\n\n<p>If you don\u2019t have any videos in your media library yet, you can upload one and follow the same step above to copy the video&#8217;s public ID. Learn about how to upload videos on <a href=\"https:\/\/cloudinary.com\/documentation\/media_library_upload_tutorial#:~:text=Using%20the%20upload%20widget%20to%20name%20and%20tag%20assets,-0%3A37&amp;text=Click%20the%20Advanced%20link%20on,is%20now%20uploaded%20to%20Cloudinary.\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>.<\/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\">NEXT_PUBLIC_CLOUDINARY_PUBLIC_ID=<span class=\"hljs-string\">\"*********************\"<\/span><\/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>Navigate to your browser and access <a href=\"http:\/\/localhost:3000\/\" target=\"_blank\" rel=\"noreferrer noopener\"><u>http:\/\/localhost:3000<\/u><\/a>, where the project is running. You should see something similar to what is shown below displaying your video.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"586\" data-public-id=\"Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_586,c_scale\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA\" alt=\"\" class=\"wp-post-34549 wp-image-34553\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1718729131\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729131\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-4.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Add Video Engagement Metrics<\/h2>\n\n\n\n<p>Cloudinary offers a video analytics engagement feature that can be accessed directly on your Cloudinary Console by selecting Analytics. Here, you\u2019ll find a set of metrics and graphs that display how your video content has been delivered. For this tutorial, you\u2019ll go beyond the Cloudinary dashboard metrics to implement the same metrics on your app dashboard.&nbsp;<\/p>\n\n\n\n<p>The <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_video_player\" target=\"_blank\" 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 href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#video_analytics_for_other_players\" target=\"_blank\" rel=\"noreferrer noopener\">JavaScript library<\/a> and configure it on any page with a video player or by accessing video view <a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#access_video_views_data_programmatically\" target=\"_blank\" rel=\"noreferrer noopener\">data programmatically<\/a>. In this step, you\u2019ll learn how to access video data programmatically within your Next.js application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fetching Video Analytics Data<\/h2>\n\n\n\n<p>To fetch the analytics data, create a folder in the root directory called utils and add a file <code>fetchAnalyticsData.js<\/code>. In this file, you\u2019ll make API requests to <code>https:\/\/api.cloudinary.com\/v1_1\/&lt;cloud name>\/video\/analytics\/views?expression=video_public_id=&lt;public id><\/code> with your <strong>cloud name<\/strong>, <strong>video public ID<\/strong>, <strong>API key<\/strong>, and <strong>API secret<\/strong> to retrieve the analytics data. 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>In this example, you must add <code>max_results=500<\/code> to the API request to increase the limit of the data returned from the API. The default limit is five, as stated in the <a href=\"https:\/\/cloudinary.com\/documentation\/video_analytics#parameters\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a>.<\/p>\n\n\n\n<p>The query would be: <code>https:\/\/api.cloudinary.com\/v1_1\/${process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME}\/video\/analytics\/views?expression=video_public_id=${process.env.NEXT_PUBLIC_CLOUDINARY_PUBLIC_ID}&amp;max_results=500<\/code>.<\/p>\n\n\n\n<p>Update the <code>fetchAnalyticsData.js<\/code> file with the following content:<\/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\"><span class=\"hljs-comment\">\/\/ utils\/fetchAnalyticsData.js<\/span>\n<span class=\"hljs-string\">\"use server\"<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> fetchAnalyticsData = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(\n    <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v1_1\/<span class=\"hljs-subst\">${process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME}<\/span>\/video\/analytics\/views?expression=video_public_id=<span class=\"hljs-subst\">${process.env.NEXT_PUBLIC_CLOUDINARY_PUBLIC_ID}<\/span>`<\/span>,\n    {\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${btoa(\n          <span class=\"hljs-string\">`<span class=\"hljs-subst\">${process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY}<\/span>:<span class=\"hljs-subst\">${process.env.NEXT_PUBLIC_CLOUDINARY_API_SECRET}<\/span>`<\/span>\n        )}<\/span>`<\/span>,\n      },\n    }\n  );\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\n  <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n  \n  <span class=\"hljs-built_in\">console<\/span>.log(data) <span class=\"hljs-comment\">\/\/ Log the data<\/span>\n  <span class=\"hljs-keyword\">return<\/span> data;\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> fetchAnalyticsData;<\/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>To test and verify that the fetchAnalyticsData.js script is correctly fetching the video analytics data from Cloudinary, you&#8217;ll need to run a simple test that outputs the results to your web browser&#8217;s console. To do that, navigate to page.js inside the app folder and import it as shown below.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ app\/page.js<\/span>\n\n<span class=\"hljs-comment\">\/\/...<\/span>\n<span class=\"hljs-keyword\">import<\/span> fetchAnalyticsData <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/fetchAnalyticsData\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex min-h-screen flex-col items-center justify-center p-6 bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500\"<\/span>&gt;<\/span>\n\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">FetchAnalyticsData<\/span> \/&gt;<\/span> \/\/ Add it here\n\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n  );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>Check your console; similar data is logged below.<\/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{\n  <span class=\"hljs-attribute\">request_id<\/span>: <span class=\"hljs-string\">'e57c6631699ffd338a23958a30a05777'<\/span>,\n  next_cursor: <span class=\"hljs-string\">'2a54714067686dc630b44e3b863163dc'<\/span>,\n  data: &#91;\n    {\n      video_public_id: <span class=\"hljs-string\">'&lt;your_public_id&gt;'<\/span>,\n      video_duration: <span class=\"hljs-number\">48<\/span>,\n      video_transformation: <span class=\"hljs-string\">'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-19T10:32:27.000Z'<\/span>\n    },\n    {\n      <span class=\"hljs-attribute\">video_public_id<\/span>: <span class=\"hljs-string\">'&lt;your_public_id&gt;'<\/span>,\n      video_duration: <span class=\"hljs-number\">48<\/span>,\n      video_transformation: <span class=\"hljs-string\">'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\">41<\/span>,\n      view_ended_at: <span class=\"hljs-string\">'2024-05-19T10:32:26.000Z'<\/span>\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\">Implement the Video Analytics Data Page<\/h2>\n\n\n\n<p>In the previous section, you created a function to fetch the video engagement data. Next, you\u2019ll implement the video analytics data page to preview the info on your application. Create a folder called components and add a file called VideoAnalyticsData.js.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Import <\/strong><strong>R<\/strong><strong>equired <\/strong><strong>D<\/strong><strong>ependencies<\/strong><\/h3>\n\n\n\n<p>Import the required dependencies and the script you wrote earlier to fetch video analytics data.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ components\/VideoAnalyticsData.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { useEffect, useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Bar } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-chartjs-2\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> {\n  Chart <span class=\"hljs-keyword\">as<\/span> ChartJS,\n  CategoryScale,\n  LinearScale,\n  BarElement,\n  Title,\n  Tooltip,\n  Legend,\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"chart.js\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> fetchAnalyticsData <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/fetchAnalyticsData\"<\/span>;\n\nChartJS.register(\n  CategoryScale,\n  LinearScale,\n  BarElement,\n  Title,\n  Tooltip,\n  Legend\n);\n\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-comment\">\/\/...<\/span>\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> VideoAnalyticsData;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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<h3 class=\"wp-block-heading\"><strong>Retrieve and <\/strong><strong>S<\/strong><strong>tore the <\/strong><strong>D<\/strong><strong>ata<\/strong><\/h3>\n\n\n\n<p>Create the state variable called analyticsData and implement useEffect to save the data retrieved into the variable once the component mounts.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ components\/VideoAnalyticsData.js<\/span>\n\n<span class=\"hljs-comment\">\/\/...<\/span>\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;analyticsData, setAnalyticsData] = useState(<span class=\"hljs-literal\">null<\/span>);\n  \n  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> fetchData = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n      <span class=\"hljs-keyword\">try<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> fetchAnalyticsData();\n        setAnalyticsData(data);\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  \n    fetchData();\n  }, &#91;]);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><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>Validate if the data is ready. If not, display a spinner on the UI.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ components\/VideoAnalyticsData.js<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\n  <span class=\"hljs-comment\">\/\/...<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (!analyticsData) {\n    <span class=\"hljs-keyword\">return<\/span> (\n      <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex items-center justify-center w-full mt-8\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"w-16 h-16 border-4 border-dashed rounded-full animate-spin border-gray-500\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n    );\n  }\n}\n\n<span class=\"hljs-comment\">\/\/...<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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<h3 class=\"wp-block-heading\"><strong>Display <\/strong><strong>the <\/strong><strong>D<\/strong><strong>ata <\/strong><strong>W<\/strong><strong>ith <\/strong><strong>C<\/strong><strong>hart.js<\/strong><\/h3>\n\n\n\n<p>Now that you have all the necessary data, you can display the data on the UI using Chart.js with the following code snippet:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ components\/VideoAnalyticsData.js<\/span>\n<span class=\"hljs-comment\">\/\/...<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-comment\">\/\/...<\/span>\n\n  <span class=\"hljs-comment\">\/\/ Get total views<\/span>\n  <span class=\"hljs-keyword\">const<\/span> totalViews = analyticsData.data.length;\n  <span class=\"hljs-keyword\">const<\/span> totalVideoDuration = analyticsData.data&#91;<span class=\"hljs-number\">0<\/span>]?.video_duration || <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-keyword\">const<\/span> countries = analyticsData.data.map(\n    <span class=\"hljs-function\">(<span class=\"hljs-params\">item<\/span>) =&gt;<\/span> item.viewer_location_country_code\n  );\n  <span class=\"hljs-keyword\">const<\/span> os = analyticsData.data.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">item<\/span>) =&gt;<\/span> item.viewer_os_identifier);\n  <span class=\"hljs-keyword\">const<\/span> applications = analyticsData.data.map(\n    <span class=\"hljs-function\">(<span class=\"hljs-params\">item<\/span>) =&gt;<\/span> item.viewer_application_name\n  );\n  <span class=\"hljs-keyword\">const<\/span> watchTimes = analyticsData.data.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">item<\/span>) =&gt;<\/span> item.view_watch_time);\n\n  <span class=\"hljs-keyword\">const<\/span> countryCounts = countries.reduce(<span class=\"hljs-function\">(<span class=\"hljs-params\">acc, country<\/span>) =&gt;<\/span> {\n    acc&#91;country] = (acc&#91;country] || <span class=\"hljs-number\">0<\/span>) + <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">return<\/span> acc;\n  }, {}); <span class=\"hljs-comment\">\/\/ Get Country<\/span>\n\n  <span class=\"hljs-keyword\">const<\/span> osCounts = os.reduce(<span class=\"hljs-function\">(<span class=\"hljs-params\">acc, system<\/span>) =&gt;<\/span> {\n    acc&#91;system] = (acc&#91;system] || <span class=\"hljs-number\">0<\/span>) + <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">return<\/span> acc;\n  }, {}); <span class=\"hljs-comment\">\/\/ Get OS<\/span>\n  \n  <span class=\"hljs-keyword\">const<\/span> appCounts = applications.reduce(<span class=\"hljs-function\">(<span class=\"hljs-params\">acc, app<\/span>) =&gt;<\/span> {\n    acc&#91;app] = (acc&#91;app] || <span class=\"hljs-number\">0<\/span>) + <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">return<\/span> acc;\n  }, {}); <span class=\"hljs-comment\">\/\/ Get Application<\/span>\n\n  <span class=\"hljs-keyword\">const<\/span> totalWatchTime = watchTimes.reduce(<span class=\"hljs-function\">(<span class=\"hljs-params\">acc, time<\/span>) =&gt;<\/span> acc + time, <span class=\"hljs-number\">0<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> averageWatchTime = (totalWatchTime \/ totalViews).toFixed(<span class=\"hljs-number\">2<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> engagementRate =\n    totalVideoDuration &gt; <span class=\"hljs-number\">0<\/span>\n      ? ((averageWatchTime \/ totalVideoDuration) * <span class=\"hljs-number\">100<\/span>).toFixed(<span class=\"hljs-number\">2<\/span>)\n      : <span class=\"hljs-number\">0<\/span>; <span class=\"hljs-comment\">\/\/ Total watch time, average watch time and engagemenr rate.<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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>In the snippet above, we retrieved the individual data points from the dataset returned. The data points for engagementRate and averageWatchTime are also computed.<\/p>\n\n\n\n<p>Next, create a dataset for the chart to display the country, operating system, and application information.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ components\/VideoAnalyticsData.js<\/span>\n<span class=\"hljs-comment\">\/\/...<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-comment\">\/\/...<\/span>\n  <span class=\"hljs-keyword\">const<\/span> countryChartData = {\n    <span class=\"hljs-attr\">labels<\/span>: <span class=\"hljs-built_in\">Object<\/span>.keys(countryCounts),\n    <span class=\"hljs-attr\">datasets<\/span>: &#91;\n      {\n        <span class=\"hljs-attr\">label<\/span>: <span class=\"hljs-string\">\"Views by Country\"<\/span>,\n        <span class=\"hljs-attr\">data<\/span>: <span class=\"hljs-built_in\">Object<\/span>.values(countryCounts),\n        <span class=\"hljs-attr\">backgroundColor<\/span>: <span class=\"hljs-string\">\"rgba(75, 192, 192, 0.6)\"<\/span>,\n        <span class=\"hljs-attr\">borderColor<\/span>: <span class=\"hljs-string\">\"rgba(75, 192, 192, 1)\"<\/span>,\n        <span class=\"hljs-attr\">borderWidth<\/span>: <span class=\"hljs-number\">1<\/span>,\n      },\n    ],\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> osChartData = {\n    <span class=\"hljs-attr\">labels<\/span>: <span class=\"hljs-built_in\">Object<\/span>.keys(osCounts),\n    <span class=\"hljs-attr\">datasets<\/span>: &#91;\n      {\n        <span class=\"hljs-attr\">label<\/span>: <span class=\"hljs-string\">\"Views by OS\"<\/span>,\n        <span class=\"hljs-attr\">data<\/span>: <span class=\"hljs-built_in\">Object<\/span>.values(osCounts),\n        <span class=\"hljs-attr\">backgroundColor<\/span>: <span class=\"hljs-string\">\"rgba(153, 102, 255, 0.6)\"<\/span>,\n        <span class=\"hljs-attr\">borderColor<\/span>: <span class=\"hljs-string\">\"rgba(153, 102, 255, 1)\"<\/span>,\n        <span class=\"hljs-attr\">borderWidth<\/span>: <span class=\"hljs-number\">1<\/span>,\n      },\n    ],\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> appChartData = {\n    <span class=\"hljs-attr\">labels<\/span>: <span class=\"hljs-built_in\">Object<\/span>.keys(appCounts),\n    <span class=\"hljs-attr\">datasets<\/span>: &#91;\n      {\n        <span class=\"hljs-attr\">label<\/span>: <span class=\"hljs-string\">\"Views by Application\"<\/span>,\n        <span class=\"hljs-attr\">data<\/span>: <span class=\"hljs-built_in\">Object<\/span>.values(appCounts),\n        <span class=\"hljs-attr\">backgroundColor<\/span>: <span class=\"hljs-string\">\"rgba(255, 159, 64, 0.6)\"<\/span>,\n        <span class=\"hljs-attr\">borderColor<\/span>: <span class=\"hljs-string\">\"rgba(255, 159, 64, 1)\"<\/span>,\n        <span class=\"hljs-attr\">borderWidth<\/span>: <span class=\"hljs-number\">1<\/span>,\n      },\n    ],\n  };\n  <span class=\"hljs-comment\">\/\/...<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><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>Next, update the UI.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/...<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> VideoAnalyticsData = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\n  <span class=\"hljs-comment\">\/\/...<\/span>\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex flex-col items-center w-full bg-white rounded-lg shadow-lg p-6\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-2xl font-bold mb-4 text-gray-900\"<\/span>&gt;<\/span>\n        Video Analytics Summary\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"grid grid-cols-1 md:grid-cols-2 gap-4 w-full\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center mb-4\"<\/span>&gt;<\/span>\n            Total Views\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-2xl font-bold text-gray-900 text-center\"<\/span>&gt;<\/span>\n            {totalViews}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center mb-4\"<\/span>&gt;<\/span>\n            Avg Watch Time (seconds)\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-2xl font-bold text-gray-900 text-center\"<\/span>&gt;<\/span>\n            {averageWatchTime}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center mb-4\"<\/span>&gt;<\/span>\n            Engagement Rate (%)\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-2xl font-bold text-gray-900 text-center\"<\/span>&gt;<\/span>\n            {engagementRate}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center\"<\/span>&gt;<\/span>\n            Countries\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Bar<\/span> <span class=\"hljs-attr\">data<\/span>=<span class=\"hljs-string\">{countryChartData}<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center\"<\/span>&gt;<\/span>\n            Operating Systems\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Bar<\/span> <span class=\"hljs-attr\">data<\/span>=<span class=\"hljs-string\">{osChartData}<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-100 rounded-lg p-4 shadow\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-semibold text-gray-700 text-center\"<\/span>&gt;<\/span>\n            Applications\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Bar<\/span> <span class=\"hljs-attr\">data<\/span>=<span class=\"hljs-string\">{appChartData}<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> VideoAnalyticsData;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><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<h3 class=\"wp-block-heading\"><strong>Import VideoAnalyticsData<\/strong> Component in page.js<\/h3>\n\n\n\n<p>You\u2019re all set! Import the VideoAnalytics.js component, delete the \u201cAdd video analytics data here\u201d placeholder, and delete the <code>fetchDataAnalytics<\/code> imported earlier with the following code snippet:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">\n<span class=\"hljs-comment\">\/\/ app\/page.js<\/span>\n\n<span class=\"hljs-comment\">\/\/..<\/span>\nimport VideoAnalyticsData from <span class=\"hljs-string\">\"..\/components\/VideoAnalyticsData\"<\/span>;\n\nexport <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    &lt;main className=<span class=\"hljs-string\">\"flex min-h-screen flex-col items-center justify-center p-6 bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500\"<\/span>&gt;\n      &lt;section className=<span class=\"hljs-string\">\"flex flex-col items-center w-full max-w-6xl mt-8 bg-white rounded-lg shadow-lg p-6\"<\/span>&gt;\n           {<span class=\"hljs-comment\">\/* ... *\/<\/span>}\n          &lt;div className=<span class=\"hljs-string\">\"w-full md:w-1\/2 p-4\"<\/span>&gt;\n            &lt;VideoAnalyticsData \/&gt; <span class=\"hljs-comment\">\/\/ Add it here<\/span>\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/section&gt;\n    &lt;\/main&gt;\n  );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><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<h2 class=\"wp-block-heading\">Testing 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 and see all the video engagement data and analytics. You should have something similar to what is shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"648\" data-public-id=\"Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_648,c_scale\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png?_i=AA\" alt=\"\" class=\"wp-post-34549 wp-image-34555\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1718729123\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718729123\/Web_Assets\/blog\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-5\/blog-Add-Video-Engagement-Metrics-to-Your-Video-Dashboard-in-Nextjs-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 shows you how to add engagement metrics to your video dashboard using the <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/video_analytics\" rel=\"noreferrer noopener\">Cloudinary video analytics<\/a> library in your Next.js application. You can try to compute and render other metrics from the provided data.<\/p>\n\n\n\n<p>If you found this blog post helpful and want to discuss it in more detail, head over to 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>Adding video engagement metrics to your video dashboard provides valuable insights into the success of your video content. This tutorial will guide you through adding engagement metrics to your video dashboard using the Cloudinary video analytics library in a Next.js application. You\u2019ll add the following engagement metrics: Cloudinary provides a comprehensive and secure API for [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":34557,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[212,303,310],"class_list":["post-34549","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-next-js","tag-video","tag-video-player"],"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 Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0<\/title>\n<meta name=\"description\" content=\"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.\" \/>\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-video-engagement-metrics-nextjs\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0\" \/>\n<meta property=\"og:description\" content=\"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-06-18T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-23T20:28:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-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-video-engagement-metrics-nextjs#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0\",\"datePublished\":\"2024-06-18T14:00:00+00:00\",\"dateModified\":\"2025-03-23T20:28:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\"},\"wordCount\":1026,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA\",\"keywords\":[\"Next.js\",\"Video\",\"Video Player\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\",\"url\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\",\"name\":\"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA\",\"datePublished\":\"2024-06-18T14:00:00+00:00\",\"dateModified\":\"2025-03-23T20:28:18+00:00\",\"description\":\"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0\"}]},{\"@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 Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0","description":"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.","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-video-engagement-metrics-nextjs","og_locale":"en_US","og_type":"article","og_title":"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0","og_description":"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.","og_url":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs","og_site_name":"Cloudinary Blog","article_published_time":"2024-06-18T14:00:00+00:00","article_modified_time":"2025-03-23T20:28:18+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-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-video-engagement-metrics-nextjs#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0","datePublished":"2024-06-18T14:00:00+00:00","dateModified":"2025-03-23T20:28:18+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs"},"wordCount":1026,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA","keywords":["Next.js","Video","Video Player"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs","url":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs","name":"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA","datePublished":"2024-06-18T14:00:00+00:00","dateModified":"2025-03-23T20:28:18+00:00","description":"Add video analytics to your Next.js project with Cloudinary. Fetch metrics like user demographics, total views, engagement rate, and average watch time.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/add-video-engagement-metrics-nextjs#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Add Video Engagement Metrics to Your Video Dashboard in Next.js\u00a0"}]},{"@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\/v1718388750\/video_engagement_NextJS-blog\/video_engagement_NextJS-blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34549","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=34549"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34549\/revisions"}],"predecessor-version":[{"id":37258,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34549\/revisions\/37258"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/34557"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=34549"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=34549"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=34549"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}