{"id":28498,"date":"2022-03-23T22:06:15","date_gmt":"2022-03-23T22:06:15","guid":{"rendered":"http:\/\/How-to-implement-YouTube-Style-Post-Video-Completion-CTA-in-NuxtJS"},"modified":"2022-03-23T22:06:15","modified_gmt":"2022-03-23T22:06:15","slug":"how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/","title":{"rendered":"Create a YouTube-Style Post-Video Completion CTA"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>YouTube has been and continues to be an essential piece in popular culture. With the addition of post-video completion call-to-action(CTA), users can dive in and find amazing video recommendations similar to what they have been watching.<\/p>\n<p>This post will discuss implementing YouTube-style post-video completion call-to-action(CTA) using Cloudinary and Nuxt.js. At the end of this tutorial, we will learn to use callback functions to handle HTML5 video events.<\/p>\n<h2>What we will be building<\/h2>\n<p>Similar to YouTube on devices, when a video is done playing, the video player display portion is replaced by a grid of 4 cards, with each of these cards linking to a different video.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_65670D9D217508C9428E03806E2653FD73AB70D6346B18A1FA20C25A8553A247_1643283609153_post-video-completion.PNG\" alt=\"Youtube post-video completion CTA\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"572\" height=\"528\"\/><\/p>\n<p>Although the grid of cards covers the video display portion, the video player controls are still in view so that once the original video is played back, the card\u2019s grid is hidden.<\/p>\n<h3>CodeSandbox<\/h3>\n<p>This project was completed in a Codesandbox. To get started quickly, fork the <a href=\"https:\/\/codesandbox.io\/s\/youtube-style-post-completion-e4mrf\">codesandbox<\/a> or run the project.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/youtube-style-post-completion-e4mrf?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"youtube-style-post-completion\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><p>GitHub Repository<\/p>\n<p><a href=\"https:\/\/github.com\/Iheanacho-ai\/YouTube-Style-Post-video-Completion\">https:\/\/github.com\/Iheanacho-ai\/YouTube-Style-Post-video-Completion<\/a><\/p>\n<h2>Prerequisities<\/h2>\n<p>To get the most out of this article it is important that we have the following:<\/p>\n<ul>\n<li>A basic understanding of CSS, JavaScript and Vue.js<\/li>\n<li>Node and its package manager, <code>npm<\/code>. Run the command <code>node -v<\/code> &amp;&amp; <code>npm -v<\/code> to verify we have them installed, or install them from <a href=\"https:\/\/nodejs.org\/en\/\">here<\/a>. It is recommended that we have the latest version. Alternatively, we can use another package manager, <a href=\"https:\/\/yarnpkg.com\/\">Yarn<\/a>.<\/li>\n<li>Understanding Nuxtjs would help us follow through with this tutorial quicker, but it is not entirely required.<\/li>\n<li>A Cloudinary account, if you don\u2019t have one, you can create one <a href=\"https:\/\/cloudinary.com\/\">here<\/a>.<\/li>\n<\/ul>\n<h2>Setting up our Nuxtjs app<\/h2>\n<p><a href=\"https:\/\/nuxtjs.org\/\">Nuxtjs<\/a> is an open-source vue.js frontend development framework that allows us to create universal web applications without stress, render statically Vue.js applications without having a server, and enables functionalities like server-side rendering, etc. in our project.<\/p>\n<p>To create a nuxtjs app, we go to our terminal and run the command below.<\/p>\n<p><strong>NOTE: If you are on windows and using Git Bash you might have issues with the arrows, so it is advisable that you use the Powershell terminal instead.<\/strong><\/p>\n<pre class=\"js-syntax-highlighted\"><code>    npm init nuxt-app &lt;project-name&gt;\n    \n    #or\n    \n    npx create-nuxt-app &lt;project-name&gt;\n    \n    #or\n    \n    yarn create nuxt-app &lt;project-name&gt;\n\n<\/code><\/pre>\n<p>Running this command will trigger a set of question prompts. In the picture below this is the setup I used.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_F22DDC6F8A9E63BACED9FA7A7E011649B13CCD6D40585994C06044C0C3C992F2_1642624609920_questions-3.PNG\" alt=\"Nuxtjs setup prompts\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"727\" height=\"211\"\/><\/p>\n<p>Next we run these commands<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    cd &lt;project name&gt;\n    \n    npm run dev\n    \n    #or\n    \n    yarn dev\n<\/code><\/pre>\n<p>This would change the directory to the project we just created and run it on our browser, to see our app go to <a href=\"http:\/\/localhost:3000\/\">http:\/\/localhost:3000\/<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_F22DDC6F8A9E63BACED9FA7A7E011649B13CCD6D40585994C06044C0C3C992F2_1642624646362_nuxtjs-index.PNG\" alt=\"Nuxtjs setup page\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1600\" height=\"738\"\/><\/p>\n<h2>Installing the Cloudinary dependency<\/h2>\n<p><strong>Cloudinary<\/strong><\/p>\n<p><a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> is a cloud-based service that provides an end-to-end image and video management solution, including uploads, storage, and optimized delivery.<\/p>\n<p>It also allows developers to embed video players in their app that handles video events effectively.<\/p>\n<p>To enable our Nuxt.js app to use these Cloudinary features, we will add the video player assets in the <code>head<\/code> section of our <code>nuxt.config.js<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\n    \/\/ nuxt.config.js\n    \n    export  default  {\n        head:  {\n        ...\n          link: [\n            ...\n            { rel:  'stylesheet', href:  'https:\/\/unpkg.com\/cloudinary-video-player@1.5.9\/dist\/cld-video-player.min.css'  }\n          ],\n          script:  [\n            { src:  'https:\/\/unpkg.com\/cloudinary-core@latest\/cloudinary-core-shrinkwrap.min.js'  },\n            { src:  'https:\/\/unpkg.com\/cloudinary-video-player@1.5.9\/dist\/cld-video-player.min.js'  },\n          ],\n        },\n    \n    };\n\n<\/code><\/pre>\n<p>Next up, we create a <code>.env<\/code> at the root of our project.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    touch .env\n\n<\/code><\/pre>\n<p>After creating our <code>.env<\/code> file, we go to our <a href=\"https:\/\/cloudinary.com\/console\">Dashboard<\/a> on Cloudinary, in the Account Details section we can see our cloud name, copy it and paste it in our <code>.env<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\n    CLOUD_NAME = &lt;Cloudinary-cloud-name&gt;\n\n<\/code><\/pre>\n<h2>Creating our Video Player<\/h2>\n<p>In our <code>index.vue<\/code>  file, we embed the Cloudinary video player in our project, to do that, we use the HTML5 native <code>video<\/code> element.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    &lt;template&gt;\n      &lt;div&gt;\n        &lt;video \n        id= &quot;video-player&quot;\n        class=&quot;cld-video-player&quot;\n        &gt;\n        &lt;\/video&gt; \n      &lt;\/div&gt;\n    &lt;\/template&gt;\n\n<\/code><\/pre>\n<p>Now that we are done with that, in the <code>mounted<\/code> lifecycle hook of our <code>index.vue<\/code> file, we create a Cloudinary instance. Doing this in our mounted lifecycle hook allows the instance to be created once the app mounts.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    \/\/ pages\/index.vue\n    \n    &lt;script&gt;\n    \n    export default {\n      data(){\n        return{\n          cld: null,\n          player: null,\n          video: &quot;videoplayback_1_pr2hzi&quot;,\n        }\n      },\n      mounted(){\n        this.cld= cloudinary.Cloudinary.new({\n          cloud_name:  process.env.CLOUD_NAME,\n          secure:  true\n        })\n        this.player = this.cld.videoPlayer(\n          'video-player', {\n              controls: true\n          }\n        );\n        this.player.source(this.video);\n    }\n    \n    }\n    \n    \n    &lt;\/script&gt;\n\n<\/code><\/pre>\n<p>In the data object, we define four variables to start with:<\/p>\n<ul>\n<li>The <code>cld<\/code> variable holds the Cloudinary instance we will create.<\/li>\n<li>The <code>player<\/code> variable has the new Cloudinary video player we will instantiate on mount.<\/li>\n<li>The <code>video<\/code> variable holds the video\u2019s id we are looking to play. This video is stored on Cloudinary.<\/li>\n<li>The <code>controls<\/code> variable controls the native player controls.<\/li>\n<\/ul>\n<p>In our mounted lifecycle hook, we create a Cloudinary instance from the Cloudinary object by passing into it as an argument the cloud name we stored in our <code>.env<\/code> file and <code>secure: true.<\/code><\/p>\n<p>We then instantiate the Cloudinary video player by using the <code>videoPlayer<\/code> method and passing in two arguments:<\/p>\n<ul>\n<li>The video player\u2019s id or the video player element itself.<\/li>\n<li>An object which sets the controls on the video to true.<\/li>\n<\/ul>\n<p>Next, we add the video stored in our video variable as the source for the player.<\/p>\n<p>In the style section of our <code>index.vue<\/code> file, we add a bit of styling to our video player, we centre the div containing our video player with the native CSS <code>flex<\/code> property, we then give our video player a width of 500px and a height of 500px.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    &lt;style scoped&gt;\n     div{\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    .cld-video-player{\n      width: 500px;\n      height: 500px;\n    }\n    &lt;\/style&gt;\n    \n<\/code><\/pre>\n<p>With that we have embedded a Cloudinary video player in our project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_65670D9D217508C9428E03806E2653FD73AB70D6346B18A1FA20C25A8553A247_1643196937091_post-youtube-video-cta.gif\" alt=\"Cloudinary Video Player\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"480\" height=\"258\"\/><\/p>\n<h2>Creating the Overlay and Selectively rendering it.<\/h2>\n<p>Our overlay would contain four thumbnails that direct us to four different videos, to create this, we go into the <code>template<\/code> section of our <code>index.vue<\/code> file, using the HTML <code>div<\/code> element, we add a class of <code>overlay<\/code>.<\/p>\n<p>We then create a <code>card<\/code> container that would hold four <code>a<\/code> tags each of which contains a <code>div<\/code> with a background image.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    &lt;div class=&quot;overlay&quot; &gt;\n        &lt;div class=&quot;cards&quot;&gt;\n          &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=1wkPMUZ9vX4&quot;&gt;\n            &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/15286\/pexels-photo.jpg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n          &lt;\/a&gt;\n          &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=IUN664s7N-c&quot;&gt;\n            &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/3408744\/pexels-photo-3408744.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n          &lt;\/a&gt;\n          &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=Faow3SKIzq0&quot;&gt;\n            &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/572897\/pexels-photo-572897.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n          &lt;\/a&gt;\n          &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=7bOptq-NPJQ&quot;&gt;\n            &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/624015\/pexels-photo-624015.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n          &lt;\/a&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n\n<\/code><\/pre>\n<p>But our overlay is incomplete without the styling. We add these styles in the <code>style<\/code> section of our <code>index.vue<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\n    .overlay{\n      width: 500px;\n      height: 500px;\n      position: absolute;\n      background-color: rgba(0,0,0, 0.70);\n      \n    }\n    .cards{\n      width: 80%;\n      height: 80%;\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      grid-template-rows: 1fr 1fr;\n      gap: 20px;\n    }\n    .cards a{\n      width: 100%;\n      height: 100%;\n    }\n    .cards div{\n      width: 100%;\n      height: 100%;\n      background-size: cover;\n      background-repeat: no-repeat;\n    }\n\n<\/code><\/pre>\n<p>We give our overlay a width and height of 500px. It also has an absolute position to sit on our video player.<\/p>\n<p>The card\u2019s div has a width and height of 80 per cent of its parent element. Using the native CSS grid for our layout, we specify that we want our card\u2019s div to be divided into four equal parts (two per row and column).<\/p>\n<p>Finally, for each div in the cards container, we want our background image to cover our entire div and not repeat itself.<\/p>\n<p>Selectively rendering the overlay.<\/p>\n<p>For our overlay to show up after the video has ended, we create an <code>overlay<\/code> variable on the data object in our <code>index.vue<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    data(){\n      return{\n        ...\n        overlay: false\n      }\n    }\n\n<\/code><\/pre>\n<p>We then use this <code>overlay<\/code> variable to selectively render our overlay.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>     &lt;div class=&quot;overlay&quot;  v-if = 'overlay'&gt;\n      &lt;div class=&quot;cards&quot;&gt;\n        &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=1wkPMUZ9vX4&quot;&gt;\n          &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/15286\/pexels-photo.jpg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n        &lt;\/a&gt;\n        &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=IUN664s7N-c&quot;&gt;\n          &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/3408744\/pexels-photo-3408744.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n        &lt;\/a&gt;\n        &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=Faow3SKIzq0&quot;&gt;\n          &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/572897\/pexels-photo-572897.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n        &lt;\/a&gt;\n        &lt;a href=&quot;https:\/\/www.youtube.com\/watch?v=7bOptq-NPJQ&quot;&gt;\n          &lt;div :style=&quot;{ 'backgroundImage': 'url(https:\/\/images.pexels.com\/photos\/624015\/pexels-photo-624015.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=1&amp;w=500)' }&quot;&gt;&lt;\/div&gt;\n        &lt;\/a&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n\n<\/code><\/pre>\n<p>Next, using Cloudinary\u2019s <code>ended<\/code> and <code>play<\/code> callback  functions, we control the <code>overlay<\/code> variable.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>    \/\/ Controls the overlay\n    \n     this.player.on('ended', ()=&gt; {\n      this.overlay= true;\n    })\n    this.player.on('play', ()=&gt; {\n      this.overlay = false;\n    })\n\n<\/code><\/pre>\n<p>With that we have completed our project, we should have something like this.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_65670D9D217508C9428E03806E2653FD73AB70D6346B18A1FA20C25A8553A247_1643198536492_post-youtube-video-completion.gif\" alt=\"Youtube-Style Post Video Completion CTA\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"372\" height=\"200\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>This article discussed what Cloudinary is and how we can use it to handle player events to create a YouTube-style post-video completion CTA.<\/p>\n<h2>Resources<\/h2>\n<p>You may find the following resources useful.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/video_player_how_to_embed\">How to embed the Cloudinary Video Player<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/video_player_api_reference\">Cloudinary Video Player API Reference<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/css-tricks.com\/snippets\/css\/complete-guide-grid\/\">CSS Grid<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28499,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,175,372,371,303,315],"class_list":["post-28498","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-jamstack","tag-nuxtjs","tag-under-review","tag-video","tag-vue"],"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>Create a YouTube-Style Post-Video Completion CTA<\/title>\n<meta name=\"description\" content=\"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA\" \/>\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\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create a YouTube-Style Post-Video Completion CTA\" \/>\n<meta property=\"og:description\" content=\"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-23T22:06:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"6000\" \/>\n\t<meta property=\"og:image:height\" content=\"4000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\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\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Create a YouTube-Style Post-Video Completion CTA\",\"datePublished\":\"2022-03-23T22:06:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"JAMStack\",\"NuxtJS\",\"Under Review\",\"Video\",\"Vue\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\",\"name\":\"Create a YouTube-Style Post-Video Completion CTA\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA\",\"datePublished\":\"2022-03-23T22:06:15+00:00\",\"description\":\"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA\",\"width\":6000,\"height\":4000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create a YouTube-Style Post-Video Completion CTA\"}]},{\"@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\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Create a YouTube-Style Post-Video Completion CTA","description":"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA","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\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/","og_locale":"en_US","og_type":"article","og_title":"Create a YouTube-Style Post-Video Completion CTA","og_description":"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-23T22:06:15+00:00","og_image":[{"width":6000,"height":4000,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/"},"author":{"name":"","@id":""},"headline":"Create a YouTube-Style Post-Video Completion CTA","datePublished":"2022-03-23T22:06:15+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","keywords":["Guest Post","JAMStack","NuxtJS","Under Review","Video","Vue"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/","name":"Create a YouTube-Style Post-Video Completion CTA","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","datePublished":"2022-03-23T22:06:15+00:00","description":"Create a video player and handle player events like onEnded with Cloudinary to implement a YouTube-style post-video completion CTA","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","width":6000,"height":4000},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-implement-youtube-style-post-video-completion-cta-in-nuxtjs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create a YouTube-Style Post-Video Completion CTA"}]},{"@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":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924386\/Web_Assets\/blog\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7\/29290fc967d6836d395f6127709a28cbb01a84ad-6000x4000-1_28499812f7.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28498","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\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28498"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28498\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28499"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}