{"id":27880,"date":"2022-06-09T09:05:25","date_gmt":"2022-06-09T09:05:25","guid":{"rendered":"http:\/\/make-video-flash-cards-in-next"},"modified":"2022-06-09T09:05:25","modified_gmt":"2022-06-09T09:05:25","slug":"make-video-flash-cards-in-next","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/","title":{"rendered":"Make Video Flash Cards in Next.js"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>There will be short videos uploaded to Cloudinary on some educational topic and they\u2019ll be rendered in random order on flashcards in the app, along with explainer text<\/p>\n<h2>Initial setup<\/h2>\n<p>The first thing you need is a Cloudinary account. You can make one for free <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">here<\/a>. This is where you\u2019ll be able to upload your videos to study from. Go ahead and create a new folder in your Cloudinary console called <code>study-videos<\/code>. If you have any videos ready, upload them to this folder.<\/p>\n<h3>Set up the Next app<\/h3>\n<p>Now we can move on to setting up the Next app. Open a terminal and run the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ yarn create next-app --typescript\n<\/code><\/span><\/pre>\n<p>This will bootstrap the app for us. We\u2019ll be using Tailwind CSS for our styles so let\u2019s install that and a couple of other packages with the following commands:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ yarn add tailwindcss postcss autoprefixer\n$ npx tailwindcss init -p\n<\/code><\/span><\/pre>\n<p>You\u2019ll need to update the <code>tailwind.config.js<\/code> with the following snippet so that the Tailwind styles are applied correctly:<\/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-comment\">\/\/ tailwind.config.js<\/span>\n...\ncontent: &#91;\n    <span class=\"hljs-string\">\".\/pages\/**\/*.{js,ts,jsx,tsx}\"<\/span>,\n    <span class=\"hljs-string\">\".\/components\/**\/*.{js,ts,jsx,tsx}\"<\/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>The last bit of setup for Tailwind is adding the directives to your global styles. Go to the <code>styles<\/code> folder and delete everything out of <code>globals.css<\/code> and replace it with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-comment\">\/* globals.css *\/<\/span>\n<span class=\"hljs-keyword\">@tailwind<\/span> base;\n<span class=\"hljs-keyword\">@tailwind<\/span> components;\n<span class=\"hljs-keyword\">@tailwind<\/span> utilities;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Set up the .env file<\/h3>\n<p>We\u2019ll be working with the Cloudinary API to get all of the videos out of the <code>study-videos<\/code> folder we made earlier. At the root of the project, make a new file called <code>.env<\/code>. You\u2019ll need the three following values in order to make requests to the Cloudinary API. You can find them in your Cloudinary console.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>CLOUDINARY_API_KEY=your_jumble_of_numbers\nCLOUDINARY_API_SECRET=your_mix_of_characters\nCLOUDINARY_CLOUD_NAME=your_cloud_name\n<\/code><\/pre>\n<p>That\u2019s all for the setup! Now we can start building the UI for our flash cards.<\/p>\n<h2>Make the flashcard page<\/h2>\n<p>Go to the <code>pages<\/code> folder and open the <code>index.tsx<\/code> file and delete everything inside of it. This is where we\u2019re going to render the flashcard. Start by adding the following code to set up the component and a few types.<\/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-comment\">\/\/ index.tsx<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> type { NextPage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Head <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/head\"<\/span>;\n\ninterface Videos {\n  <span class=\"hljs-attr\">videos<\/span>: string&#91;];\n}\n\ninterface FlashcardData {\n  <span class=\"hljs-attr\">question<\/span>: string;\n  answer: string;\n  videoUrl: string;\n}\n\n<span class=\"hljs-keyword\">const<\/span> Flashcard: NextPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/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\">\"container mx-auto\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Study for this test<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span>\n          <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"description\"<\/span>\n          <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"It's time to get ready for some certification\"<\/span>\n        \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Flashcard;\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>Right now we\u2019ve just imported a few things and defined the <code>&lt;Head&gt;<\/code> for this page. Now let\u2019s get the data from Cloudinary so we can make the flashcards.<\/p>\n<h3>Fetching video data from Cloudinary<\/h3>\n<p>We\u2019ll use Cloudinary\u2019s search API to get all of the videos in the <code>study-videos<\/code> folder we made earlier. Since this is a Next app, we\u2019ll use the <code>getStaticProps<\/code> function because this data needs to be available before the user\u2019s request. Add this code just above the default export statement.<\/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-comment\">\/\/ index.tsx<\/span>\n\n...\nexport <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getStaticProps<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> params: any = {\n    <span class=\"hljs-attr\">expression<\/span>: <span class=\"hljs-string\">'folder:\"study-videos\"'<\/span>,\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> folderSearch = <span class=\"hljs-built_in\">Object<\/span>.keys(params)\n    .map(<span class=\"hljs-function\">(<span class=\"hljs-params\">key: string<\/span>) =&gt;<\/span> <span class=\"hljs-string\">`<span class=\"hljs-subst\">${key}<\/span>=<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">encodeURIComponent<\/span>(params&#91;key])}<\/span>`<\/span>)\n    .join(<span class=\"hljs-string\">\"&amp;\"<\/span>);\n\n  <span class=\"hljs-keyword\">const<\/span> results = <span class=\"hljs-keyword\">await<\/span> fetch(\n    <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v1_1\/<span class=\"hljs-subst\">${process.env.CLOUDINARY_CLOUD_NAME}<\/span>\/resources\/search?<span class=\"hljs-subst\">${folderSearch}<\/span>`<\/span>,\n    {\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${Buffer.<span class=\"hljs-keyword\">from<\/span>(\n          process.env.CLOUDINARY_API_KEY +\n            <span class=\"hljs-string\">\":\"<\/span> +\n            process.env.CLOUDINARY_API_SECRET\n        ).toString(<span class=\"hljs-string\">\"base64\"<\/span>)}<\/span>`<\/span>,\n      },\n    }\n  ).then(<span class=\"hljs-function\">(<span class=\"hljs-params\">r<\/span>) =&gt;<\/span> r.json());\n\n  <span class=\"hljs-keyword\">const<\/span> { resources } = results;\n\n  <span class=\"hljs-keyword\">const<\/span> videos: Videos = resources.map(\n    <span class=\"hljs-function\">(<span class=\"hljs-params\">resource: { secure_url: string }<\/span>) =&gt;<\/span> resource.secure_url\n  );\n\n  <span class=\"hljs-keyword\">return<\/span> {\n    <span class=\"hljs-attr\">props<\/span>: {\n      videos,\n    },\n  };\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Flashcard\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>First, we define the search parameter we need to target the correct folder. Then we encode the search so that it\u2019s in a URL-friendly format. You could expand this to use multiple search parameters. After that, we make the GET request with the search parameters and our authentication information in the headers and wait for the JSON response.<\/p>\n<p>Next, we parse out the video URLs we need for the flashcard data and pass it to the <code>Flashcard<\/code> component as a prop. So we\u2019ll need to do a quick update to the component declaration line.<\/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\">\/\/ index.tsx<\/span>\n\n...\nconst Flashcard: NextPage&lt;Videos&gt; = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ videos }<\/span>) =&gt;<\/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\">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>Now we can associate the videos with questions and answers.<\/p>\n<h3>Making the flashcard data<\/h3>\n<p>This is where you might pull in data from a different API to get the flashcard questions and answers, but we\u2019ll use some filler text for this example. Add the following code inside of the <code>Flashcard<\/code> component, above the current return statement.<\/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-comment\">\/\/ index.tsx<\/span>\n\n...\nconst &#91;flashcardData, setFlashcardData] = useState&lt;FlashcardData&#91;]&gt;(&#91;]);\n<span class=\"hljs-keyword\">const<\/span> &#91;flipCard, setFlipCard] = useState&lt;boolean&gt;(<span class=\"hljs-literal\">false<\/span>);\n<span class=\"hljs-keyword\">const<\/span> &#91;index, setIndex] = useState&lt;number&gt;(<span class=\"hljs-number\">0<\/span>);\n\nuseEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> questionsAnswers = &#91;\n    {\n      <span class=\"hljs-attr\">question<\/span>: <span class=\"hljs-string\">\"What was the name of the first computer invented?\"<\/span>,\n      <span class=\"hljs-attr\">answer<\/span>: <span class=\"hljs-string\">\"Electronic Numerical Integrator and Computer (ENIAC)\"<\/span>,\n    },\n    {\n      <span class=\"hljs-attr\">question<\/span>: <span class=\"hljs-string\">\"When was the first 1 GB disk drive released in the world?\"<\/span>,\n      <span class=\"hljs-attr\">answer<\/span>: <span class=\"hljs-string\">\"1980\"<\/span>,\n    },\n    {\n      <span class=\"hljs-attr\">question<\/span>: <span class=\"hljs-string\">\"What is the full form of UPS?\"<\/span>,\n      <span class=\"hljs-attr\">answer<\/span>: <span class=\"hljs-string\">\"Uninterruptible Power Supply\"<\/span>,\n    },\n    {\n      <span class=\"hljs-attr\">question<\/span>: <span class=\"hljs-string\">\"Difference between \u201c == \u201c and \u201c === \u201c operators.\"<\/span>,\n      <span class=\"hljs-attr\">answer<\/span>:\n        <span class=\"hljs-string\">\"\u201c==\u201d is used to compare values and \u201c === \u201c is used to compare both values and types\"<\/span>,\n    },\n    {\n      <span class=\"hljs-attr\">question<\/span>: <span class=\"hljs-string\">\"What are callbacks?\"<\/span>,\n      <span class=\"hljs-attr\">answer<\/span>:\n        <span class=\"hljs-string\">\"Functions that will be executed after another function gets executed\"<\/span>,\n    },\n  ];\n  <span class=\"hljs-keyword\">const<\/span> flashcardData = videos.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">video, i<\/span>) =&gt;<\/span> ({\n    <span class=\"hljs-attr\">question<\/span>: questionsAnswers&#91;i].question,\n    <span class=\"hljs-attr\">answer<\/span>: questionsAnswers&#91;i].answer,\n    <span class=\"hljs-attr\">videoUrl<\/span>: video,\n  }));\n\n  setFlashcardData(flashcardData);\n}, &#91;videos]);\n\n<span class=\"hljs-keyword\">if<\/span> (flashcardData.length === <span class=\"hljs-number\">0<\/span>) <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>Loading...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/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>This code sets some initial states for the flashcards and the way they will be rendered. Then we create the flashcard data and update it whenever there\u2019s a change to the <code>videos<\/code>. Next, we have a loading state that gets rendered while the flashcards are being created.<\/p>\n<p>All that\u2019s left now is actually rendering the flashcards in a user-friendly way.<\/p>\n<h3>Rendering the flashcards<\/h3>\n<p>We want to cycle through the cards a number of times to learn the right answers to questions. So we\u2019ll have the cards on a continuous loop that users can keep clicking through, regardless of the number of questions. Add the following code below the <code>&lt;Head&gt;<\/code> element.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\/\/ index.tsx\n\n...\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"my-24 p-6 rounded-md\tborder-4 border-indigo-200 border-l-indigo-500 h-fit\"<\/span>&gt;<\/span>\n  {!flipCard ? (\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-center flex flex-col space-y-16\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"font-bold text-3xl\"<\/span>&gt;<\/span>Topic: Tech Stuff<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>{flashcardData&#91;index].question}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n        <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"rounded-full bg-emerald-400 py-2 px-4 text-stone-100 w-1\/2 mx-auto\"<\/span>\n        <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setFlipCard(true)}\n      &gt;\n        Get answer and watch video\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/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> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-center flex flex-col space-y-4\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span>\n        <span class=\"hljs-attr\">controls<\/span>\n        <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{flashcardData&#91;index].videoUrl}<\/span>\n        <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"80%\"<\/span>\n        <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"mx-auto\"<\/span>\n      &gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>{flashcardData&#91;index].question}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{flashcardData&#91;index].answer}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n        <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"rounded-full bg-violet-400 py-2 px-4 text-stone-100 w-1\/2 mx-auto\"<\/span>\n        <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n          const updatedIndex =\n            index + 1 &gt; flashcardData.length - 1 ? 0 : index + 1;\n          setFlipCard(false);\n          setIndex(updatedIndex);\n          console.log(index);\n        }}\n      &gt;\n        Next question\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/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\">main<\/span>&gt;<\/span>\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\">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>This code represents the two sides of a flashcard. One side will just have the question and a button to go to the video and answer. If you run you app with <code>yarn dev<\/code> at this point, you should see something like this.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1654278555\/e-603fc55d218a650069f5228b\/ryjk86oyoeyvwygkfxp5.png\" alt=\"front side of flashcard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"856\"\/><\/p>\n<p>The other side will have the video and the answer to the question.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1654278627\/e-603fc55d218a650069f5228b\/unwcowdksxnzpebiyinu.png\" alt=\"back side of flashcard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1189\"\/><\/p>\n<p>That\u2019s it! Now you have an app that will let you make flashcards quickly and it can be expanded to include a number of other features.<\/p>\n<h2>Finished code<\/h2>\n<p>You can find the complete code for this in <a href=\"https:\/\/github.com\/flippedcoder\/media-projects\/tree\/main\/video-flashcards\">the <code>video-flashcards<\/code> folder of this repo<\/a> or you can check it out in <a href=\"https:\/\/codesandbox.io\/s\/using-tailwind-with-next-js-forked-r1lyfr\">this Code Sandbox<\/a>.<\/p>\n<p>&lt;CodeSandBox\ntitle=\u201cusing-tailwind-with-next-js-forked-r1lyfr\u201d\nid=\u201cusing-tailwind-with-next-js-forked-r1lyfr\u201d\n\/&gt;<\/p>\n<h2>Conclusion<\/h2>\n<p>Using videos as a part of any study routine can help make the information stick. With this app, you can include short videos from lectures or classes you\u2019re taking to get a quick review of everything that you need to know for a particular topic.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27881,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,212,371],"class_list":["post-27880","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-next-js","tag-under-review"],"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>Make Video Flash Cards in Next.js<\/title>\n<meta name=\"description\" content=\"Sometimes studying can be difficult when you have to keep cross-referencing videos. That&#039;s why we&#039;re making an app that lets you add videos to digital flashcards in this Next app.\" \/>\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\/make-video-flash-cards-in-next\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Make Video Flash Cards in Next.js\" \/>\n<meta property=\"og:description\" content=\"Sometimes studying can be difficult when you have to keep cross-referencing videos. That&#039;s why we&#039;re making an app that lets you add videos to digital flashcards in this Next app.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-09T09:05:25+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Make Video Flash Cards in Next.js\",\"datePublished\":\"2022-06-09T09:05:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Next.js\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\",\"name\":\"Make Video Flash Cards in Next.js\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA\",\"datePublished\":\"2022-06-09T09:05:25+00:00\",\"description\":\"Sometimes studying can be difficult when you have to keep cross-referencing videos. That's why we're making an app that lets you add videos to digital flashcards in this Next app.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA\",\"width\":4023,\"height\":6000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Make Video Flash Cards in Next.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Make Video Flash Cards in Next.js","description":"Sometimes studying can be difficult when you have to keep cross-referencing videos. That's why we're making an app that lets you add videos to digital flashcards in this Next app.","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\/make-video-flash-cards-in-next\/","og_locale":"en_US","og_type":"article","og_title":"Make Video Flash Cards in Next.js","og_description":"Sometimes studying can be difficult when you have to keep cross-referencing videos. That's why we're making an app that lets you add videos to digital flashcards in this Next app.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-06-09T09:05:25+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/"},"author":{"name":"","@id":""},"headline":"Make Video Flash Cards in Next.js","datePublished":"2022-06-09T09:05:25+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","keywords":["Guest Post","Image","Next.js","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/","name":"Make Video Flash Cards in Next.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","datePublished":"2022-06-09T09:05:25+00:00","description":"Sometimes studying can be difficult when you have to keep cross-referencing videos. That's why we're making an app that lets you add videos to digital flashcards in this Next app.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","width":4023,"height":6000},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/make-video-flash-cards-in-next\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Make Video Flash Cards in Next.js"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926012\/Web_Assets\/blog\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b\/cd51d7b47c0a6a132d05725aa76c1de68b7a0bde-4023x6000-1_278815fd1b.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27880","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=27880"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27880\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27881"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27880"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27880"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27880"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}