{"id":28280,"date":"2023-07-21T07:00:00","date_gmt":"2023-07-21T14:00:00","guid":{"rendered":"http:\/\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs"},"modified":"2025-02-09T06:18:37","modified_gmt":"2025-02-09T14:18:37","slug":"create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","title":{"rendered":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Video previews have become a standard feature on most media platforms and applications. <a href=\"https:\/\/www.youtube.com\/\">YouTube<\/a> provides a perfect example where a user is presented with a video preview when the mouse pointer hovers over the thumbnail.<\/p>\n<p>A <strong>thumbnail<\/strong> is an image preview of the actual video, as shown in the image 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_FF2E708BB1CF9130EA9AA143519BE5E1F2A90F6C372E2DCFEDDE853C69388617_1646648517957_cloudinary_video_thumbnails.png\" alt=\"Video Thumbnails as seen on YouTube\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1091\" height=\"467\"\/><\/p>\n<p>This post discusses creating video thumbnail previews on hover using <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> and <a href=\"https:\/\/nextjs.org\/\">NextJS<\/a>. At the end of this tutorial, we\u2019ll learn how to use Cloudinary\u2019s video functionality in a website to create a preview on the hover feature and add videos to our pages.<\/p>\n<h2>Demo and Source Code<\/h2>\n<p>We completed this project in a <a href=\"https:\/\/codesandbox.io\/s\/boring-vaughan-iqfrhw\">CodeSandbox<\/a>, and you can fork it to run the code.<\/p>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/agitated-leaf-q4v7x8?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=\"Video preview on hover\"\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 \"><p>GitHub link <a href=\"https:\/\/github.com\/achingachris\/video-thumbnail-preview-cloudinary-nextjs\">here<\/a>.<\/p>\n<br \/>\n<p><video src='https:\/\/cloudinary-marketing-res.cloudinary.com\/video\/upload\/f_auto,q_auto\/v1696261353\/cloudinary_preview.mp4' controls><\/video><\/p>\n<h2>Prerequisites<\/h2>\n<p>Before we start, make sure you have:<\/p>\n<ul>\n<li>A Cloudinary account. Create a free account <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">here<\/a>.<\/li>\n<li>Knowledge of React.js and NextjS.<\/li>\n<li>NodeJS version 12+.<\/li>\n<\/ul>\n<h2>Getting Started<\/h2>\n<p>To create a NextJS application, run the terminal command below:<\/p>\n<pre><code>npx creat-next-app thumbnail-preview &amp;&amp; cd thumbnail-preview\n<\/code><\/pre>\n<p>To confirm that NextJS installed successfully, start a local development server in the project\u2019s directory using the command:<\/p>\n<pre><code>npm run dev\n<\/code><\/pre>\n<p>The local development server for NextJS runs on port 3000, i.e., localhost:3000 on a web browser.<\/p>\n<p>We\u2019ll use <a href=\"https:\/\/getbootstrap.com\/\">Bootstrap CSS<\/a> to style the app\u2019s pages, as it provides ready-to-use CSS classes. To install Bootstrap, we\u2019ll run the command:<\/p>\n<pre><code>npm install bootstrap\n<\/code><\/pre>\n<p>After installation, we\u2019ll import Bootstrap into our project by adding the following line at the top of <code>pages\/_app.js<\/code>.<\/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> <span class=\"hljs-string\">'bootstrap\/dist\/css\/bootstrap.css'<\/span>\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<h2>Uploading Media to Cloudinary<\/h2>\n<p>After signing in to Cloudinary, navigate to the <a href=\"https:\/\/cloudinary.com\/console\/media_library\">Media Library<\/a> to upload videos.<\/p>\n<p>The quickest way to upload videos to Cloudinary is by dragging and dropping the file to the <a href=\"https:\/\/cloudinary.com\/users\/login?RelayState=%2Fconsole%2Fmedia_library\">Media Library Dashboard<\/a>. The other way is by using the upload button on the top right of the webpage.<\/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_FF2E708BB1CF9130EA9AA143519BE5E1F2A90F6C372E2DCFEDDE853C69388617_1646718158227_screenshot.png\" alt=\"Uploading Media Files through the Upload button\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"824\" height=\"582\"\/><\/p>\n<p>After the video is uploaded, use the link icon on the top right of the video card to copy its URL.<\/p>\n<h2>Creating the Video Player<\/h2>\n<p>In the <code>Home<\/code>  component of <code>pages\/index.js<\/code>, we\u2019ll create an array with the video URLs and their titles.<\/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\">const<\/span> Home = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> media_urls = &#91;\n        {\n          <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-number\">1<\/span>,\n          <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">'Video One'<\/span>,\n          <span class=\"hljs-attr\">video_url<\/span>:\n            <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/chris101\/video\/upload\/v1645684691\/video_1.mp4'<\/span>,\n        },\n        {\n          <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-number\">2<\/span>,\n          <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">'Video Two'<\/span>,\n          <span class=\"hljs-attr\">video_url<\/span>:\n            <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/chris101\/video\/upload\/v1645684672\/video_2.mp4'<\/span>,\n        },\n        {\n          <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-number\">3<\/span>,\n          <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">'Video Three'<\/span>,\n          <span class=\"hljs-attr\">video_url<\/span>:\n            <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/chris101\/video\/upload\/v1645684663\/video_3.mp4'<\/span>,\n        },\n      ]\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'text-center'<\/span>&gt;<\/span>Cloudinary Video Show<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/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\">'container'<\/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\">'row'<\/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\">'container'<\/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>\n        <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span>\n      )\n    }\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Home\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<p>We\u2019ll render each video using the native HTML <code>video<\/code> element.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">'320'<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">'240'<\/span> <span class=\"hljs-attr\">controls<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{media.video_url}<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">'video\/mp4'<\/span> \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the <code>Home<\/code> component, we\u2019ll loop through the array with video info and render each video.<\/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> Home = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> media_urls = &#91;\n        <span class=\"hljs-comment\">\/\/ media URLs here<\/span>\n      ]\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'text-center'<\/span>&gt;<\/span>Cloudinary Video Show<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/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\">'container'<\/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\">'row'<\/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\">'container'<\/span>&gt;<\/span>\n                {media_urls.map((media) =&gt; (\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{media.id}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'col-lg-4 col-md-4'<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>{media.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">'320'<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">'240'<\/span> <span class=\"hljs-attr\">controls<\/span>&gt;<\/span>\n                      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{media.video_url}<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">'video\/mp4'<\/span> \/&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                ))}\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>\n        <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span>\n      )\n    }\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Home\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><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_FF2E708BB1CF9130EA9AA143519BE5E1F2A90F6C372E2DCFEDDE853C69388617_1646802604531_video_display_1.png\" alt=\"Display videos from Cloudinary\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"516\" height=\"467\"\/><\/p>\n<h2>Creating Event Handlers<\/h2>\n<p>The next step, we\u2019ll create event handlers to trigger a preview on hover over the thumbnails. We\u2019ll use the <a href=\"https:\/\/reactjs.org\/docs\/events.html#mouse-events\">mouse<\/a> events.<\/p>\n<p>Next, we\u2019ll use the <code>onMouseEnter<\/code> and <code>onMouseLeave<\/code> events. From the react documentation, the events are triggered when a pointer is over the targeted element(<code>onMouseEnter<\/code>) and immediately the pointer leaves the targeted element(<code>onMouseLeave<\/code>).<\/p>\n<p>In our home page component, we\u2019ll create two functions to handle the two events:\n<code>handleMouseEnter()<\/code> and <code>handleMouseLeave()<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ handle mouse enter<\/span>\n<span class=\"hljs-keyword\">const<\/span> handleMouseEnter = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {}\n<span class=\"hljs-comment\">\/\/ handle mouse leave<\/span>\n<span class=\"hljs-keyword\">const<\/span> handleMouseLeave = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {}\n<\/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<p>To start the video preview on hover, we\u2019ll modify the <code>handleMouseEnter()<\/code> to:<\/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\">const<\/span> handleMouseEnter = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> vid = e.target\n   vid.muted = <span class=\"hljs-literal\">true<\/span>\n   vid.play()\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above function grabs the <code>&lt;video&gt;&lt;\/video&gt;<\/code>, and we\u2019ll use one of the element\u2019s built-in events. <code>vid.muted<\/code> is set to true, which means sound is disabled, and <code>vid.play()<\/code> starts playing the video.<\/p>\n<p>To stop the video playback and return it to its original state, we modify the <code>handleMouseLeave()<\/code> function to:<\/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-keyword\">const<\/span> handleMouseLeave = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> vid = e.target\n    vid.muted = <span class=\"hljs-literal\">false<\/span>\n    vid.currentTime = <span class=\"hljs-number\">0<\/span>\n    vid.pause()\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<h2>Triggering the Events<\/h2>\n<p>We\u2019ll need to trigger the two mouse events,<code>onMouseEnter<\/code> and <code>onMouseLeave<\/code>, to enable the preview. Modify the video element to:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span>\n    <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">'320'<\/span>\n    <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">'240'<\/span>\n    <span class=\"hljs-attr\">controls<\/span>\n    <span class=\"hljs-attr\">onMouseEnter<\/span>=<span class=\"hljs-string\">{handleMouseEnter}<\/span>\n    <span class=\"hljs-attr\">onMouseLeave<\/span>=<span class=\"hljs-string\">{handleMouseLeave}<\/span>\n  &gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{media.video_url}<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">'video\/mp4'<\/span> \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The complete code in the <code>Home<\/code> component is shown below:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/115717b9474676deff93e54f236caf70\">https:\/\/gist.github.com\/Chuloo\/115717b9474676deff93e54f236caf70<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/115717b9474676deff93e54f236caf70\">https:\/\/gist.github.com\/Chuloo\/115717b9474676deff93e54f236caf70<\/a><\/p>\n<p><a href=\"https:\/\/www.dropbox.com\/s\/zdi1nn58f787foi\/localhost_3000%20%281%29.mp4?dl=0\">https:\/\/www.dropbox.com\/s\/zdi1nn58f787foi\/localhost_3000%20%281%29.mp4?dl=0<\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>We walked through uploading video files to our Cloudinary account, rendered the videos on a web page, and finally implemented an autoplay preview when hovering on the video.<\/p>\n<p>Want to discuss this tutorial? Join us in the <a href=\"https:\/\/discord.gg\/cloudinary\">Cloudinary Community Discord server<\/a>.<\/p>\n<h2>Resources<\/h2>\n<ul>\n<li>\n<a href=\"https:\/\/getbootstrap.com\/\">Bootstrap<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/video\">HTML Video Element<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":87,"featured_media":30487,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,212,303],"class_list":["post-28280","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-next-js","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>Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-07-21T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-09T14:18:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs-png?_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\/png\" \/>\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\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary\",\"datePublished\":\"2023-07-21T14:00:00+00:00\",\"dateModified\":\"2025-02-09T14:18:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\"},\"wordCount\":12,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Next.js\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2023\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\",\"url\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\",\"name\":\"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA\",\"datePublished\":\"2023-07-21T14:00:00+00:00\",\"dateModified\":\"2025-02-09T14:18:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary\"}]},{\"@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":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary","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\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","og_locale":"en_US","og_type":"article","og_title":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary","og_url":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","og_site_name":"Cloudinary Blog","article_published_time":"2023-07-21T14:00:00+00:00","article_modified_time":"2025-02-09T14:18:37+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs-png?_i=AA","type":"image\/png"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary","datePublished":"2023-07-21T14:00:00+00:00","dateModified":"2025-02-09T14:18:37+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs"},"wordCount":12,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA","keywords":["Guest Post","Next.js","Video"],"inLanguage":"en-US","copyrightYear":"2023","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","url":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs","name":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA","datePublished":"2023-07-21T14:00:00+00:00","dateModified":"2025-02-09T14:18:37+00:00","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/create-a-video-thumbnail-with-a-preview-on-hover-in-nextjs#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Video Thumbnail With a Preview on Hover Using Next.js and Cloudinary"}]},{"@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\/v1688152741\/Blog-video-thumbnails-nextjs\/Blog-video-thumbnails-nextjs.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28280","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=28280"}],"version-history":[{"count":12,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28280\/revisions"}],"predecessor-version":[{"id":36774,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28280\/revisions\/36774"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/30487"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}