{"id":28011,"date":"2022-03-23T22:26:22","date_gmt":"2022-03-23T22:26:22","guid":{"rendered":"http:\/\/Feedback-Form-Trigger-from-Video-Events-in-Gatsby.js"},"modified":"2022-03-23T22:26:22","modified_gmt":"2022-03-23T22:26:22","slug":"feedback-form-trigger-from-video-events-in-gatsby-js","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/","title":{"rendered":"Feedback Form Trigger from Video Events"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Modern web pages rely heavily on interactivity. These tasks include gathering data on user engagement, processing form submissions, and controlling media asset interactivity.\nIn this tutorial, we\u2019ll discuss how to utilize video event triggers to handle user interface changes in a Gatsby.js project.<\/p>\n<h2>Sandbox<\/h2>\n<p>This project was completed in a <a href=\"https:\/\/codesandbox.io\/s\/video-event-trigger-in-gatsbyjs-xyw7c?file=\/src\/pages\/index.js:0-939\">Codesandbox<\/a>. To get started quickly, fork the <a href=\"https:\/\/codesandbox.io\/s\/video-event-trigger-in-gatsbyjs-xyw7c?file=\/src\/pages\/index.js:0-939\">Codesandbox<\/a> or run the project.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/video-event-trigger-in-gatsbyjs-xyw7c?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=%2Fsrc%2Fpages%2Findex.js%3A0-939&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"Video event triggers in Gatsby.js pages\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><h1>Prerequisite<\/h1>\n<p>The knowledge of JavaScript and React.js is needed for this post. The knowledge of Gatsby.js is not required, but preferred.<\/p>\n<h1>Getting Started with Gatsby<\/h1>\n<p><a href=\"https:\/\/www.gatsbyjs.com\/docs\/quick-start\/\">Gatsby<\/a> is an open-source static site generator (SSG). Gatsby uses efficient pre-configuration for rapid page loads, code splitting, server-side rendering, intelligent image loading, asset optimization, and data prefetching.<\/p>\n<p>Gatsby uses <a href=\"https:\/\/webpack.js.org\/\">webpack<\/a>, <a href=\"https:\/\/graphql.org\/\">G<\/a><a href=\"https:\/\/graphql.org\/\">raphQL<\/a> and <a href=\"https:\/\/reactjs.org\/\">React.js<\/a> to build and render high-performance web apps. Gatsby can also be used to create progressive web apps that adhere to the most current web standards and are designed for speed and security.<\/p>\n<h1>Installation of a video event trigger with a feedback form<\/h1>\n<p>To create a new project, we use the <code>gatsby new &lt;project name&gt;<\/code> command to scaffold a new project.\nOnce the app is initialized and the dependencies automatically installed, we will see a message with instructions for navigating to our site and running it locally. We do this with the command<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">cd <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">name<\/span>&gt;<\/span> &amp;&amp; gatsby develop\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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>Gatsby will start a hot-reloading development environment accessible by default at<\/p>\n<p><code>http:\/\/localhost:8000<\/code><\/p>\n<p>The boilerplate project creates a landing page with CSS modules for styling.<\/p>\n<p>We\u2019ll use the <a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">Cloudinary-react package<\/a>, which ships components that help us render images and videos. We\u2019ll also use CloudinaryContext, which is the wrapper component to pass shared data to all child Cloudinary components.<\/p>\n<p>Cloudinary\u2019s robust transformation features can be used to modify the video, which is distributed through an integrated content delivery network (CDN).<\/p>\n<p>We install the cloudinary-react package using npm with:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm i cloudinary-react\n<\/code><\/span><\/pre>\n<p>We import and render the video player on the home page, whose component is specified in pages\/index.js:<\/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, Transformation } <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\">IndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    \n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Seo<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">\"Home\"<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Welcome to your new Gatsby site.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/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\">\"olanetsoft\"<\/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\/animals\/testvid\"<\/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\">Layout<\/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<p><code>CloudinaryContext<\/code> takes props of any data we want to make available to the Cloudinary components\u2019 children. For example, we sent our Cloudinary cloud name in this situation.<\/p>\n<p>You can get your cloud name from your Cloudinary dashboard by signing up for a <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Cloudinary Account<\/a>.<\/p>\n<p>We use the <code>Video<\/code> component to build a 500px(configurable) wide video player. The video\u2019s public ID, which is a unique identifier for a media asset stored on Cloudinary, was also used to reference the media asset.\nFinally, we included props that enable the video player to be controlled and muted once rendered.<\/p>\n<p>You should have something similar to the image below if you use the specified cloud name in the snippet.<\/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_AE8908F9432DC3828B06D0CE8E565FFE0F4118859F3B3A23BA295CE71BDC5239_1619868995284_gats.PNG\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1428\" height=\"1188\"\/><\/p>\n<p>How do we get access to the methods and properties of the underlying video element?\nThe <a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">cloudinary-react package<\/a> provides the <code>innerRef<\/code> prop, which makes access to underlying video element seamless.<\/p>\n<p>To reference the underlying HTML video element, we\u2019ll use React\u2019s useRef() hook.<\/p>\n<p>With useRef(), we are able to access the <code>onended<\/code> video event. We make a new ref and assign it to the video\u2019s <code>innerRef<\/code> prop with:<\/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\">    import { Video, CloudinaryContext, Transformation } from \"cloudinary-react\";\n    import { useRef } from \"react\";\n    \n     export default function IndexPage() {\n      const videoRef = useRef();\n      return (\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Seo<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">\"Home\"<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Welcome to your new Gatsby site.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/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\">\"olanetsoft\"<\/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\/animals\/testvid\"<\/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> \/&gt;<\/span>\n             \/&gt;\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/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\">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>With the ref in place, we\u2019ll manage user interface behavior corresponding to video events. When the video ends, we call a required action. This action is done in a <code>useEffect<\/code> hook, where you reveal to React the component that needs to accomplish an action after render.\nReact will call the function passed once the component loads and call it later when the DOM rerenders with the following code. We define the ref and useEffect sequence with:<\/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\">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\">IndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-keyword\">const<\/span> &#91;videoEnded, setVideoEnded] = useState(<span class=\"hljs-literal\">undefined<\/span>)\n        <span class=\"hljs-keyword\">const<\/span> videoRef = useRef()\n        useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n            <span class=\"hljs-keyword\">const<\/span> video = videoRef.current;\n    \n            video.onended = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n                setVideoEnded(<span class=\"hljs-literal\">true<\/span>)\n                <span class=\"hljs-comment\">\/\/ Our logic goes in here<\/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-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>In the imported <code>useEffect<\/code> hook we listen to the <code>onended<\/code> event of the video to carry out further action in a function.<\/p>\n<p>We store a <code>true<\/code> boolean value in the component\u2019s state when the video ends. With this state value, we handle several UI updates. These experiences include the following:<\/p>\n<ul>\n<li>Using Formik to show form for feedback<\/li>\n<li>Implementing modals to share vital information<\/li>\n<li>When a video ends, we render call to action buttons &#8211; Handle navigation on real video events<\/li>\n<li>Get or send info using an API<\/li>\n<\/ul>\n<p>For this project, we\u2019ll make a Formik component that renders when the video ends.\nFormik handles the tedious and inconvenient tasks, such as keeping track of values\/errors\/visited areas, orchestrating validation, and managing form submission.<\/p>\n<p>It means you can devote more time to your business logic than wiring-up state and <code>onChange<\/code> handlers when building a form.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm i formik\n<\/code><\/span><\/pre>\n<p>We create <code>form.css<\/code> and <code>form.js<\/code> files inside the component folder <code>src\/components<\/code>. Next, we add the snippets that handle formik in action, as well as styling for the form.<\/p>\n<p>In the <code>form.css<\/code> add the following snippet:<\/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\">    * {\n      <span class=\"hljs-attribute\">box-sizing<\/span>: border-box;\n    }\n    <span class=\"hljs-selector-tag\">input<\/span><span class=\"hljs-selector-attr\">&#91;type=<span class=\"hljs-string\">\"text\"<\/span>]<\/span> {\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">12px<\/span>;\n      <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-number\">#ccc<\/span>;\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">4px<\/span>;\n      <span class=\"hljs-attribute\">resize<\/span>: vertical;\n    }\n    <span class=\"hljs-selector-tag\">label<\/span> {\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">6px<\/span> <span class=\"hljs-number\">6px<\/span> <span class=\"hljs-number\">6px<\/span> <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">display<\/span>: inline-block;\n    }\n    <span class=\"hljs-selector-tag\">button<\/span><span class=\"hljs-selector-attr\">&#91;type=<span class=\"hljs-string\">\"submit\"<\/span>]<\/span> {\n      <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#4caf50<\/span>;\n      <span class=\"hljs-attribute\">color<\/span>: white;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">6px<\/span> <span class=\"hljs-number\">8px<\/span>;\n      <span class=\"hljs-attribute\">border<\/span>: none;\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">4px<\/span>;\n      <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n      <span class=\"hljs-attribute\">float<\/span>: left;\n      <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">10px<\/span>;\n    }\n    <span class=\"hljs-selector-tag\">button<\/span><span class=\"hljs-selector-attr\">&#91;type=<span class=\"hljs-string\">\"submit\"<\/span>]<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span> {\n      <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#45a049<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.container<\/span> {\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">10px<\/span>;\n      <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#f2f2f2<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">12px<\/span>;\n      <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">55%<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.col-30<\/span> {\n      <span class=\"hljs-attribute\">float<\/span>: left;\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">30%<\/span>;\n      <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">4px<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.col-60<\/span> {\n      <span class=\"hljs-attribute\">float<\/span>: left;\n      <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">70%<\/span>;\n      <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">4px<\/span>;\n    }\n    <span class=\"hljs-comment\">\/* Clear floats after the columns *\/<\/span>\n    <span class=\"hljs-selector-class\">.row<\/span><span class=\"hljs-selector-pseudo\">:after<\/span> {\n      <span class=\"hljs-attribute\">content<\/span>: <span class=\"hljs-string\">\"\"<\/span>;\n      <span class=\"hljs-attribute\">display<\/span>: table;\n      <span class=\"hljs-attribute\">clear<\/span>: both;\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>Heading over to the <code>form.js<\/code> file we created earlier which handles our form input, we add the following snippet to import the <code>Formik<\/code> module and <code>form.css<\/code><\/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> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> { Formik } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"formik\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\".\/form.css\"<\/span>\n    \n    <span class=\"hljs-keyword\">const<\/span> Form = <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>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Formik<\/span>\n              <span class=\"hljs-attr\">initialValues<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">name:<\/span> \"\", <span class=\"hljs-attr\">feedback:<\/span> \"\" }}\n              <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{(values,<\/span> { <span class=\"hljs-attr\">setSubmitting<\/span> }) =&gt;<\/span> {\n                setTimeout(() =&gt; {\n                  alert(JSON.stringify(values, null, 2))\n                  setSubmitting(false)\n                }, 400)\n              }}\n            &gt;\n              {({ values, handleChange, handleBlur, handleSubmit, isSubmitting }) =&gt; (\n    \n                \/\/ Our form to be rendered goes in here\n    \n              )}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Formik<\/span>&gt;<\/span>\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> Form\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>Let\u2019s Render the required input fields:<\/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\">            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{handleSubmit}<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/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\">class<\/span>=<span class=\"hljs-string\">\"col-30\"<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"name\"<\/span>&gt;<\/span>Name<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-70\"<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                      <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n                      <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"name\"<\/span>\n                      <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{handleChange}<\/span>\n                      <span class=\"hljs-attr\">onBlur<\/span>=<span class=\"hljs-string\">{handleBlur}<\/span>\n                      <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{values.name}<\/span>\n                    \/&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> <span class=\"hljs-attr\">class<\/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\">class<\/span>=<span class=\"hljs-string\">\"col-30\"<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"feedback\"<\/span>&gt;<\/span>Feedback<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-70\"<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                      <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n                      <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"feedback\"<\/span>\n                      <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{handleChange}<\/span>\n                      <span class=\"hljs-attr\">onBlur<\/span>=<span class=\"hljs-string\">{handleBlur}<\/span>\n                      <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{values.feedback}<\/span>\n                    \/&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> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"row\"<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{isSubmitting}<\/span>&gt;<\/span>\n                    Submit\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              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\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>We imported our custom CSS and <code>Formik<\/code> in the snippet above, then we added properties to capture user data and preview the data using an alert popup. Formik also handles a variety of validations and custom styling.<\/p>\n<p>We need to update the <code>index.js<\/code> file to include the created Form component. The form renders once the state value of videoEnded resolves to true<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" 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> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"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    <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\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/layout\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> Seo <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/seo\"<\/span>\n    <span class=\"hljs-keyword\">import<\/span> Form <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/form\"<\/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\">IndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-keyword\">const<\/span> &#91;videoEnded, setVideoEnded] = useState(<span class=\"hljs-literal\">undefined<\/span>)\n      <span class=\"hljs-keyword\">const<\/span> videoRef = useRef()\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.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=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Seo<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">\"Home\"<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Welcome to your new Gatsby site.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/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\">\"olanetsoft\"<\/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\/animals\/testvid\"<\/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            {videoEnded &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Form<\/span> \/&gt;<\/span>}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/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-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here\u2019s what the final video looks like with the Form Feedback on video events:<\/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_AE8908F9432DC3828B06D0CE8E565FFE0F4118859F3B3A23BA295CE71BDC5239_1620171996412_ezgif.com-gif-maker.gif\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"820\"\/><\/p>\n<h1>Conclusion<\/h1>\n<p>This article addressed using <code>useRef<\/code> to access the video element\u2019s native properties, events, and methods in a Gatsby project. With this, once a video is done playing, we render a feedback form to get user feedback.<\/p>\n<h1>Resources<\/h1>\n<p>You may find these resources useful.<\/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.npmjs.com\/package\/formik\">Formik<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28012,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[378,134,371,303],"class_list":["post-28011","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-gatsbyjs","tag-guest-post","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>Feedback Form Trigger from Video Events<\/title>\n<meta name=\"description\" content=\"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping\" \/>\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\/feedback-form-trigger-from-video-events-in-gatsby-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Feedback Form Trigger from Video Events\" \/>\n<meta property=\"og:description\" content=\"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-23T22:26:22+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\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.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\/feedback-form-trigger-from-video-events-in-gatsby-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Feedback Form Trigger from Video Events\",\"datePublished\":\"2022-03-23T22:26:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA\",\"keywords\":[\"GatsbyJS\",\"Guest Post\",\"Under Review\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\",\"name\":\"Feedback Form Trigger from Video Events\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA\",\"datePublished\":\"2022-03-23T22:26:22+00:00\",\"description\":\"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA\",\"width\":7360,\"height\":4912},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Feedback Form Trigger from Video Events\"}]},{\"@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":"Feedback Form Trigger from Video Events","description":"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping","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\/feedback-form-trigger-from-video-events-in-gatsby-js\/","og_locale":"en_US","og_type":"article","og_title":"Feedback Form Trigger from Video Events","og_description":"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-23T22:26:22+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/"},"author":{"name":"","@id":""},"headline":"Feedback Form Trigger from Video Events","datePublished":"2022-03-23T22:26:22+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","keywords":["GatsbyJS","Guest Post","Under Review","Video"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/","name":"Feedback Form Trigger from Video Events","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","datePublished":"2022-03-23T22:26:22+00:00","description":"In this post, we discussed how to trigger a form display once a vidnce a video is done playing.la eois done yping","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","width":7360,"height":4912},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/feedback-form-trigger-from-video-events-in-gatsby-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Feedback Form Trigger from Video Events"}]},{"@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\/v1681925679\/Web_Assets\/blog\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9\/87b8a1c5efb33e1077e166d02b25eedd2819ed7a-7360x4912-1_2801248cb9.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28011","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=28011"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28011\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28012"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28011"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28011"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}