{"id":28288,"date":"2022-03-23T22:01:28","date_gmt":"2022-03-23T22:01:28","guid":{"rendered":"http:\/\/Building-a-Youtube-Style-Post-Video-Overlay-CTA"},"modified":"2025-04-16T14:52:44","modified_gmt":"2025-04-16T21:52:44","slug":"building-a-youtube-style-post-video-overlay-cta","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","title":{"rendered":"Building a Youtube-Style Post-Video Overlay CTA"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>When you watch a YouTube video, at the end, some cards appear on the screen suggesting other videos to watch.\nThis article is going to walk through managing video events to create a similar experience for videos in React.js.<\/p>\n<h2>Sandbox<\/h2>\n<p>We completed this project in a <a href=\"https:\/\/codesandbox.io\/s\/building-youtube-style-post-video-overlay-cta-2ylnu\">Codesandbox<\/a> and it\u2019s also available on <a href=\"https:\/\/github.com\/folucode\/YouTube-post-video-overlay\/tree\/main\/\">GitHub<\/a>. Fork it to run the project or get started quickly.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    \n<\/code><\/span><\/pre>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/building-youtube-style-post-video-overlay-cta-2ylnu?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=\"Building YouTube-style post-video overlay CTA\"\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\n<div class=\"wp-block-cloudinary-markdown \"><pre class=\"js-syntax-highlighted\"><code>\nGitHub URL: https:\/\/github.com\/folucode\/YouTube-post-video-overlay\/tree\/main\/\n\n## Prerequisite\n\nTo follow through with this article, we need to have an understanding of JavaScript and React.js. \n\n\n## Project Setup\n\n[Node](https:\/\/nodejs.org\/en\/) and its package manager [npm](https:\/\/www.npmjs.com\/) are required to initialize a new project.\n\nUsing `npm` would require that we download the package to our computer before using it, but `npm` comes with an executor called `npx`.  You can [find more information on using npx here](https:\/\/docs.npmjs.com\/cli\/v7\/commands\/npx).\n\n`npx` stands for Node Package Execute. It allows us to execute any package that we want from the `npm` registry without installing it.\n\nTo install Node, we go to the [Node](https:\/\/nodejs.org\/en\/)[js](https:\/\/nodejs.org\/en\/) [website](https:\/\/nodejs.org\/en\/), download the Node version for our Operating system and follow the installation instructions. After we successfully installed the software, we should be able to verify Node.js by checking the installed version from the command line using the command below:\n \n```bash\n    node -v\n    v14.7.1\n<\/code><\/pre>\n<p>The result shows the version of Node.js we installed on our computer. In the above example, we have node at version 14.7.1.<\/p>\n<h2>Creating the application<\/h2>\n<p><code>create-react-app<\/code> is the package we would use to generate a new react application. It is the official node package for creating react applications.<\/p>\n<p>We use the command below to create a new application:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npx create-react-app youtube-overlay-app\n<\/code><\/span><\/pre>\n<p>The above command will create a new React.js application called youtube-overlay-app.<\/p>\n<h2>Installing Cloudinary<\/h2>\n<p><a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> provides a rich media management experience enabling users to upload, store, manage, manipulate, and deliver images and video for websites and applications.<\/p>\n<p>Due to the performance benefits of serving images from an optimized Content Delivery Network, we\u2019ll use images stored on Cloudinary.\nWe\u2019ll utilize the <a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">Cloudinary-react package<\/a> to render Cloudinary videos on a page. We Install the cloudinary-react package in the project using <code>npm<\/code> by running the following command in the project\u2019s root directory:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm i cloudinary-react\n<\/code><\/span><\/pre>\n<p>With installations completed, we\u2019ll start the react application using the command below:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm start\n<\/code><\/span><\/pre>\n<p>Once run, the command spins up a local development server which we can access on <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a>.<\/p>\n<h2>Rendering the parent video component<\/h2>\n<p>In the \u201cApp.js\u201d file in the \u201csrc\u201d folder, we clear all the boilerplate code and then replace it with the code below that renders a <a href=\"https:\/\/cloudinary.com\/products\/video\">Cloudinary video<\/a>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> { Video, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/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\">App<\/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\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"App\"<\/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\">\"video-area\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"chukwutosin\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span>\n                <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">\"samples\/elephants\"<\/span>\n                <span class=\"hljs-attr\">controls<\/span>\n                <span class=\"hljs-attr\">muted<\/span>\n                <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500px\"<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/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<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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<p>First, we imported the <code>Video<\/code> component that renders the video onto the page and <code>CloudinaryContext<\/code>. This component takes props of any data we want to make available to its child Cloudinary components.<\/p>\n<p>The <code>cloudName<\/code> prop is your Cloudinary cloud name which you can get from your Cloudinary dashboard once you create a <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Cloudinary Account<\/a>.<\/p>\n<blockquote>\n<p>Cloudinary offers a great free tier which is enough for all our development needs.<\/p>\n<\/blockquote>\n<p>We use the <code>Video<\/code> component to render a 500px wide video player\u200a, having controls, and is muted on playback. We then pass a prop called <code>publicId<\/code>, which is the public ID of the video you want to render. A public ID is a unique identifier for a media asset stored on Cloudinary.<\/p>\n<p>The rendered video should look 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_9AD052D357061232960D42E55EE9D4834E3096AFB0C279BC082E7F93E2A271CD_1623076094506_cloudinary-article-image.PNG\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"502\" height=\"322\"\/><\/p>\n<h2>Accessing the methods and properties of the video<\/h2>\n<p>We can seamlessly access the methods and properties of the video element using the <code>innerRef<\/code> prop provided by the <a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">cloudinary-react package<\/a>.<\/p>\n<p>By creating a reference using React\u2019s <code>useRef()<\/code> hook and assigning it to the <code>innerRef<\/code> property, we can utilize the properties and methods of the underlying video element. Subsequently, all the video element\u2019s available properties and methods will be on the <code>.current<\/code> property of the ref.<\/p>\n<p>We create a ref and assign it with:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> { Video, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { useRef } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>; <span class=\"hljs-comment\">\/\/ change 1<\/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\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-keyword\">const<\/span> videoRef = useRef(); <span class=\"hljs-comment\">\/\/ change 2<\/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\">\"App\"<\/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\">\"video-area\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"chukwutosin\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span>\n                <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">\"samples\/elephants\"<\/span>\n                <span class=\"hljs-attr\">controls<\/span>\n                <span class=\"hljs-attr\">muted<\/span>\n                <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500px\"<\/span>\n                <span class=\"hljs-attr\">innerRef<\/span>=<span class=\"hljs-string\">{videoRef}<\/span> \/\/ <span class=\"hljs-attr\">change<\/span> <span class=\"hljs-attr\">3<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/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<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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<h2>Managing video events<\/h2>\n<p>When the video playback starts and ends, we listen to both events and trigger specific actions.\nUsing React\u2019s <code>useEffect<\/code> hook, we\u2019ll update the state of the video player stored in the component\u2019s state.<\/p>\n<p>We create the state variable and the effects with:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> { Video, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { useRef, useEffect, useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/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\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-keyword\">const<\/span> &#91;videoEnded, setVideoEnded] = useState(<span class=\"hljs-literal\">false<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> videoRef = useRef();\n    \n      useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> video = videoRef.current;\n        video.onplay = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n          setVideoEnded(<span class=\"hljs-literal\">false<\/span>);\n        };\n    \n        video.onended = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n          setVideoEnded(<span class=\"hljs-literal\">true<\/span>);\n        };\n      }, &#91;]);\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"hljs-comment\">\/\/ render component here<\/span>\n      );\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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<p>First, we created a state variable to hold a value for when the video playback finishes.<\/p>\n<p>We listen for the <code>onended<\/code> and <code>onplay<\/code> events of the video In the <code>useEffect<\/code> hook. Next, we update the <code>videoEnded<\/code> variable to <code>true<\/code> if the video completes playing and false if it resumes playing.<\/p>\n<p>The <code>videoEnded<\/code> state variable will be used in a condition to render the <a href=\"https:\/\/cloudinary.com\/guides\/video-effects\/how-to-create-a-video-overlay-in-react\">video overlay<\/a>.<\/p>\n<h2>Applying the overlay effect<\/h2>\n<p>We start by creating a component to house the overlay that we would show. Next, we create a new file called \u2018Card.js\u2019 in <code>src<\/code> and paste it into the code below.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">const<\/span> data = &#91;\n      {\n        <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"bike\"<\/span>,\n        <span class=\"hljs-attr\">link<\/span>: <span class=\"hljs-string\">\"https:\/\/www.youtube.com\/watch?v=6uq3P7zeYyU\"<\/span>,\n        <span class=\"hljs-attr\">thumbnail<\/span>:\n          <span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/chukwutosin\/image\/upload\/v1590019494\/samples\/bike.jpg\"<\/span>\n      },\n      {\n        <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"sheep\"<\/span>,\n        <span class=\"hljs-attr\">link<\/span>: <span class=\"hljs-string\">\"https:\/\/www.youtube.com\/watch?v=7w8K8GHs5Aw\"<\/span>,\n        <span class=\"hljs-attr\">thumbnail<\/span>:\n          <span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/chukwutosin\/image\/upload\/v1590019492\/samples\/sheep.jpg\"<\/span>\n      },\n      {\n        <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"kitten-playing\"<\/span>,\n        <span class=\"hljs-attr\">link<\/span>: <span class=\"hljs-string\">\"https:\/\/www.youtube.com\/watch?v=4SnUsJOpw74\"<\/span>,\n        <span class=\"hljs-attr\">thumbnail<\/span>:\n          <span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/chukwutosin\/image\/upload\/v1590019500\/samples\/animals\/kitten-playing.gif\"<\/span>\n      },\n      {\n        <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"reindeer\"<\/span>,\n        <span class=\"hljs-attr\">link<\/span>: <span class=\"hljs-string\">\"https:\/\/www.youtube.com\/watch?v=ujxRTqqQODY\"<\/span>,\n        <span class=\"hljs-attr\">thumbnail<\/span>:\n          <span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/chukwutosin\/image\/upload\/v1590019491\/samples\/animals\/reindeer.jpg\"<\/span>\n      }\n    ];\n    \n    <span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/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\">\"card\"<\/span>&gt;<\/span>\n        {data.map((element, index) =&gt; (\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"column\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{index}<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{element.link}<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{element.alt}<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{element.thumbnail}<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span>\n        ))}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n    );\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Card;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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<p><code>data<\/code> is an array of Objects with information for each card we want to overlay on the video element. Then, we made a functional component where we looped through each object in the <code>data<\/code> array and rendered a thumbnail image wrapped in a link.<\/p>\n<p>We would need to add a stylesheet to customize the overlay on the video element. We do this by deleting the boilerplate styles in the index.css file and adding the following styles:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\">    <span class=\"hljs-selector-class\">.App<\/span> {\n      <span class=\"hljs-attribute\">font-family<\/span>: Cambria, Cochin, Georgia, Times, <span class=\"hljs-string\">\"Times New Roman\"<\/span>, serif;\n      <span class=\"hljs-attribute\">text-align<\/span>: center;\n      <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">width<\/span>: auto;\n      <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n    }\n    <span class=\"hljs-selector-tag\">h3<\/span> {\n      <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">46<\/span>, <span class=\"hljs-number\">44<\/span>, <span class=\"hljs-number\">44<\/span>);\n    }\n    <span class=\"hljs-selector-class\">.video-area<\/span> {\n      <span class=\"hljs-attribute\">position<\/span>: relative;\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">500px<\/span>;\n      <span class=\"hljs-attribute\">margin<\/span>: auto;\n      <span class=\"hljs-attribute\">left<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">50%<\/span> \u2014 <span class=\"hljs-number\">200px<\/span>);\n    }\n    <span class=\"hljs-selector-class\">.card<\/span> {\n      <span class=\"hljs-attribute\">left<\/span>: <span class=\"hljs-number\">50%<\/span>;\n      <span class=\"hljs-attribute\">margin-left<\/span>: -<span class=\"hljs-number\">250px<\/span>;\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">500px<\/span>;\n      <span class=\"hljs-attribute\">position<\/span>: absolute;\n      <span class=\"hljs-attribute\">z-index<\/span>: <span class=\"hljs-number\">1<\/span>;\n      <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">rgba<\/span>(<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">0.6<\/span>);\n    }\n    <span class=\"hljs-selector-class\">.column<\/span> {\n      <span class=\"hljs-attribute\">float<\/span>: left;\n      <span class=\"hljs-attribute\">text-align<\/span>: center;\n      <span class=\"hljs-attribute\">border<\/span>: solid <span class=\"hljs-number\">1px<\/span> <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">180<\/span>, <span class=\"hljs-number\">179<\/span>, <span class=\"hljs-number\">179<\/span>);\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">45%<\/span>;\n      <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">2.3%<\/span>;\n      <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">85px<\/span>;\n      <span class=\"hljs-attribute\">opacity<\/span>: <span class=\"hljs-number\">1<\/span>;\n    }\n    <span class=\"hljs-selector-tag\">img<\/span> {\n      <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100%<\/span>;\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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<p>After that, we import both files, \u2018Card.js\u2019 and \u2018index.css\u2019 into the \u2018App.js\u2019 file using:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\".\/index.css\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> Card <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/Card\"<\/span>;\n    \n    <span class=\"hljs-comment\">\/\/ the rest of the content goes here...<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>With the overlay cards completed, we will show the overlay or hide it depending on the state of the <code>videoEnded<\/code> variable, either true or false.<\/p>\n<p>In App.js, we include a conditional render block to show or hide the <code>&lt;Card\/&gt;<\/code> component.<\/p>\n<pre class=\"js-syntax-highlighted\" 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\">\/\/ code before return statement...<\/span>\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\">\"App\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Building YouTube-style post-video overlay CTA<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n            This is a demo of how to build a simple clone of the YouTube post video\n            overlay\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          {videoEnded &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/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\">\"video-area\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"chukwutosin\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span>\n                <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">\"samples\/elephants\"<\/span>\n                <span class=\"hljs-attr\">controls<\/span>\n                <span class=\"hljs-attr\">muted<\/span>\n                <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500px\"<\/span>\n                <span class=\"hljs-attr\">innerRef<\/span>=<span class=\"hljs-string\">{videoRef}<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/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<\/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<p>With this, once the video playback completes, the <code>videoEnded<\/code> variable is set to <code>true<\/code>, and the cards overlays on the video. Each card can link to a CTA of our choice. Here\u2019s what it looks like below.<\/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_9AD052D357061232960D42E55EE9D4834E3096AFB0C279BC082E7F93E2A271CD_1623094909306_cloudinary-article-image-grid.PNG\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"505\" height=\"282\"\/><\/p>\n<h1>Conclusion<\/h1>\n<p>This article addressed utilizing video events to create youtube-styled call-to-action cards on a video once playback ends. This technique is employed to increase conversion on a video\u2019s call to actions.<\/p>\n<!-- By far one of the easiest and most commonly media used feature, very great build. One suggestion is to add link for npx creation as lots of issues with npx at the moment in the community https:\/\/github.com\/facebook\/create-react-app -->\n<h1>Resources<\/h1>\n<p>You may find these resources helpful.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/www.w3schools.com\/tags\/ref_av_dom.asp\">HTML Audio\/Video DOM Reference<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\">Video Transformations<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/www.w3schools.com\/css\/css_positioning.asp\">CSS positioning<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28289,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,382,246,371,303],"class_list":["post-28288","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-player-video","tag-react","tag-under-review","tag-video"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Building a Youtube-Style Post-Video Overlay CTA<\/title>\n<meta name=\"description\" content=\"Learn to replicate the CTA options shown at the end of youtube videos\" \/>\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\/building-a-youtube-style-post-video-overlay-cta\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Youtube-Style Post-Video Overlay CTA\" \/>\n<meta property=\"og:description\" content=\"Learn to replicate the CTA options shown at the end of youtube videos\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-23T22:01:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-16T21:52:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"4306\" \/>\n\t<meta property=\"og:image:height\" content=\"2871\" \/>\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\/building-a-youtube-style-post-video-overlay-cta\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Building a Youtube-Style Post-Video Overlay CTA\",\"datePublished\":\"2022-03-23T22:01:28+00:00\",\"dateModified\":\"2025-04-16T21:52:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Player Video\",\"React\",\"Under Review\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\",\"name\":\"Building a Youtube-Style Post-Video Overlay CTA\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA\",\"datePublished\":\"2022-03-23T22:01:28+00:00\",\"dateModified\":\"2025-04-16T21:52:44+00:00\",\"description\":\"Learn to replicate the CTA options shown at the end of youtube videos\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA\",\"width\":4306,\"height\":2871},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Youtube-Style Post-Video Overlay 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":"Building a Youtube-Style Post-Video Overlay CTA","description":"Learn to replicate the CTA options shown at the end of youtube videos","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\/building-a-youtube-style-post-video-overlay-cta\/","og_locale":"en_US","og_type":"article","og_title":"Building a Youtube-Style Post-Video Overlay CTA","og_description":"Learn to replicate the CTA options shown at the end of youtube videos","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-23T22:01:28+00:00","article_modified_time":"2025-04-16T21:52:44+00:00","og_image":[{"width":4306,"height":2871,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b-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\/building-a-youtube-style-post-video-overlay-cta\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/"},"author":{"name":"","@id":""},"headline":"Building a Youtube-Style Post-Video Overlay CTA","datePublished":"2022-03-23T22:01:28+00:00","dateModified":"2025-04-16T21:52:44+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA","keywords":["Guest Post","Player Video","React","Under Review","Video"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","name":"Building a Youtube-Style Post-Video Overlay CTA","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA","datePublished":"2022-03-23T22:01:28+00:00","dateModified":"2025-04-16T21:52:44+00:00","description":"Learn to replicate the CTA options shown at the end of youtube videos","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA","width":4306,"height":2871},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Youtube-Style Post-Video Overlay 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":""}]}},"parsely":{"version":"1.1.0","canonical_url":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","smart_links":{"inbound":0,"outbound":0},"traffic_boost_suggestions_count":0,"meta":{"@context":"https:\/\/schema.org","@type":"NewsArticle","headline":"Building a Youtube-Style Post-Video Overlay CTA","url":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/","mainEntityOfPage":{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA&w=150&h=150&crop=1","image":{"@type":"ImageObject","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA"},"articleSection":"Uncategorized","author":[],"creator":[],"publisher":{"@type":"Organization","name":"Cloudinary Blog","logo":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA"},"keywords":["guest post","player video","react","under review","video"],"dateCreated":"2022-03-23T22:01:28Z","datePublished":"2022-03-23T22:01:28Z","dateModified":"2025-04-16T21:52:44Z"},"rendered":"<meta name=\"parsely-title\" content=\"Building a Youtube-Style Post-Video Overlay CTA\" \/>\n<meta name=\"parsely-link\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/building-a-youtube-style-post-video-overlay-cta\/\" \/>\n<meta name=\"parsely-type\" content=\"post\" \/>\n<meta name=\"parsely-image-url\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA&w=150&amp;h=150&amp;crop=1\" \/>\n<meta name=\"parsely-pub-date\" content=\"2022-03-23T22:01:28Z\" \/>\n<meta name=\"parsely-section\" content=\"Uncategorized\" \/>\n<meta name=\"parsely-tags\" content=\"guest post,player video,react,under review,video\" \/>","tracker_url":"https:\/\/cdn.parsely.com\/keys\/cloudinary.com\/p.js"},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924917\/Web_Assets\/blog\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b\/a136a0c4a107f91483c3a76366eea1597b0459e3-4306x2871-1_282896b70b.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28288","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=28288"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28288\/revisions"}],"predecessor-version":[{"id":37461,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28288\/revisions\/37461"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28289"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}