{"id":22263,"date":"2021-01-12T17:30:58","date_gmt":"2021-01-12T17:30:58","guid":{"rendered":"http:\/\/amplify_your_jamstack_with_video"},"modified":"2022-09-23T09:58:58","modified_gmt":"2022-09-23T16:58:58","slug":"amplify_your_jamstack_with_video","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video","title":{"rendered":"Amplify Your Jamstack With Video"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>As defined by Amazon Web Services (AWS), Amplify is a set of products and tools with which mobile and front-end web developers can build and deploy AWS-powered, secure, and scalable full-stack apps. Also, you can efficiently configure their back ends, connect them to your app with just a few lines of code, and deploy static web apps in only three steps.\nHistorically, because of their performance issues, managing images and videos is a daunting challenge for developers. Even though you can easily load media to an S3 bucket with AWS Amplify, transforming, compressing, and responsively delivering them is labor intensive and time consuming.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/deploy_aws_app.png\" alt=\"Deploy AWS app\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"512\"\/><\/p>\n<p>Enter <a href=\"https:\/\/cloudinary.com\/video_api\">Cloudinary<\/a> as an effective cloud-based media-management platform, with which you can efficiently and seamlessly create, manage, and deliver satisfactory experiences to all browsers and devices, regardless of their bandwidth. Uploading media to Cloudinary is effortless, after which it dynamically transforms them on the fly, largely heading off infrastructure- and maintenance-related concerns. Furthermore, Cloudinary offers <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_sdks\">software development kits (SDKs)<\/a> for all popular programming languages.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/cloudinary_sdk_library.png\" alt=\"Cloudinary SDK library\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"240\"\/><\/p>\n<h2>Building the Demo App<\/h2>\n<p>This post shows you how to build a blog, host it with Amplify, and transform its videos with Cloudinary. The <a href=\"https:\/\/github.com\/CodingCatDev\/amplify-jamstack-cloudinary-video.git\">code repository<\/a> is on GitHub.<\/p>\n<h3>Creating a React App<\/h3>\n<p>As a prerequisite, <a href=\"https:\/\/aws.amazon.com\/premiumsupport\/knowledge-center\/create-and-activate-aws-account\/\">set up an AWS account<\/a>. For reference, see the <a href=\"https:\/\/docs.amplify.aws\/\">Amplify documentation<\/a> and this <a href=\"https:\/\/docs.amplify.aws\/start\/q\/integration\/react\">Amplify tutorial<\/a>.\nFollow the steps below:<\/p>\n<ol>\n<li>\n<p>Add Amplify to your terminal. Type:\n<code>npm install -g @aws-amplify\/cli<\/code><\/p>\n<\/li>\n<li>\n<p>Configure the new project. Type:\n<code>amplify configure<\/code><\/p>\n<\/li>\n<li>\n<p>Create a React app as a starting point for the project. Type:\n<code>npx create-react-app amplify-jamstack-cloudinary-video<\/code><\/p>\n<p>This step takes a while, after which you\u2019ll see output on the Yarn commands you can run from the project directory. For more details, see this <a href=\"https:\/\/reactjs.org\/docs\/create-a-new-react-app.html\">writeup on React toolchains<\/a>.<\/p>\n<\/li>\n<li>\n<p>Go to the project directory and start the React app. Type:<\/p>\n<p><code>cd amplify-jamstack-cloudinary-video<\/code>\n<code>yarn start<\/code><\/p>\n<\/li>\n<\/ol>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>To see the demo running, run the local server with the command <code>npm start<\/code>.<\/p><\/div>\n<p>When the app finishes running, React displays its rotating icon.<\/p>\n<video controls=\"controls\" muted poster=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/video\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/rotating_react_logo.jpg\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/video\/upload\/w_700,f_auto,q_auto\/Web_Assets\/blog\/rotating_react_logo.mp4\">\n<\/video>\n<h3>Adding AWS Amplify<\/h3>\n<p><strong>Tip:<\/strong> If you cannot connect to the correct instance, go to the <code>~\/.aws<\/code> directory and verify that the credentials you entered match those listed there. For more details, see the <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/userguide\/cli-configure-profiles.html\">AWS documentation on named profiles<\/a>.\nNow turn your React app into an AWS Amplify app. First, configure your AWS account with the connections required for your app. Type:\n<code>amplify init<\/code><\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>In case of no response from Amplify, type ctrl+c to ensure that you have exited your local server.<\/p><\/div>\n<p>Amplify then displays the following prompts. Respond to each of them by typing Enter to select the default as shown. Below are my responses for your reference.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>? Enter a name for the project amplifyjamstackcloud\n? Enter a name for the environment dev\n? Choose your default editor: Visual Studio Code\n? Choose the type of app that you're building javascript\nPlease tell us about your project\n? What javascript framework are you using react\n? Source Directory Path:  src\n? Distribution Directory Path: build\n? Build Command:  npm run-script build\n? Start Command: npm run-script start\nUsing default provider awscloudformation\n? Do you want to use an AWS profile? Yes\n? Please choose the profile you want to use (Use arrow keys)\n\u276f default\n<\/code><\/pre>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>If this is your first time you set up an AWS account profile, I suggest you pick the defaults for your settings. However, if you\u2019re on another AWS-related project that uses the AWS SDK, you might have a separate profile already. Ensure that you specify the correct one.<\/p><\/div>\n<p>Afterwards, AWS displays a confirmation:<\/p>\n<p><code>Adding backend environment dev to AWS Amplify Console app: d2hxdxps86f74m<\/code><\/p>\n<p>Go to <a href=\"https:\/\/console.aws.amazon.com\">AWS Amplify<\/a> and you\u2019ll see your new app amplifyjamstackcloud there, assuming that\u2019s the name you specified.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/aws_amplify_managemen_console.png\" alt=\"AWS Amplify\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"236\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_jamstack.png\" alt=\"Amplify Jamstack\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"438\"\/><\/p>\n<p>If you don\u2019t see your app, you might be in the wrong geographical region. To double-check, pull down the drop-down menu in the upper-left corner.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_app_name.png\" alt=\"app name\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"225\"\/><\/p>\n<p>Now that your app is in the cloud, click <strong>General<\/strong> in the left navigation and note these details:<\/p>\n<ul>\n<li>The app, called d2hxdxps86f74m, is identical to the one in the console.<\/li>\n<li>The back end of this project and its location are displayed under <strong>Backend environments<\/strong> (see the screenshot below). AWS Amplify leverages <a href=\"https:\/\/aws.amazon.com\/cloudformation\/\">AWS CloudFormation<\/a> under the hood, a technique known as back end as code (BaC).<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/amplify_dev_console_1.png\" alt=\"Dev console\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"293\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/amplify_dev_console_2.png\" alt=\"Dev Console\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"165\"\/><\/p>\n<h3>Setting Up the Front End<\/h3>\n<p><code>aws-amplify<\/code> is the main library that works with Amplify in apps. The <code>@aws-amplify\/ui-react<\/code> package contains React-specific UI components, which you\u2019ll leverage. Install it with this command:<\/p>\n<p><code>npm install aws-amplify @aws-amplify\/ui-react<\/code><\/p>\n<p>Next, have React import Amplify and configure it according to the settings created with Amplify\u2019s CLI tool, which is located in <code>.\/aws-exports<\/code>. Type the following commands:<\/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> awsExports <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/aws-exports\"<\/span>;\nAmplify.configure(awsExports);\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>Your app is now ready to call Amplify and, inherently, the AWS SDK.<\/p>\n<h3>Adding a Database Layer<\/h3>\n<p>I suggest adopting GraphQL, which sends real-time notifications, as the database layer for your app. Feel free to use the REST API instead if you prefer.<\/p>\n<p>To add a database layer, type:<\/p>\n<p><code>amplify add api<\/code>\nAmplify then displays several prompts. Below is my suggestion of the responses at the end of each of the prompts.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>To take this demo further later on, respond with multiple objects.<\/p><\/div>\n<pre class=\"js-syntax-highlighted\"><code>? Please select from one of the below mentioned services: GraphQL\n? Provide API name: amplifyjamstackcloud\n? Choose the default authorization type for the API API key\n? Enter a description for the API key: sample\n? After how many days from now the API key should expire (1-365): 365\n? Do you want to configure advanced settings for the GraphQL API No, I am done.\n? Do you have an annotated GraphQL schema? No\n? Choose a schema template: Single object with fields (e.g., \u201cTodo\u201d with ID, name, description)\n<\/code><\/pre>\n<p>When prompted \u201cDo you want to edit the schema now? (y\/n),\u201d typing <code>y<\/code> opens your default editor for the schema file. I typed <code>n<\/code> and ran the command below instead, opening all the project files in VSCode.<\/p>\n<p><code>code .<\/code><\/p>\n<p>The code for the back end you\u2019re creating resides in the <code>amplify<\/code> directory. The newly created schema, which is in <code>amplify\/backend\/api\/amplifyjamstackcloud\/schema.graphql<\/code>, reads like this:<\/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\">  id: ID!\n  name: <span class=\"hljs-built_in\">String<\/span>!\n  description: <span class=\"hljs-built_in\">String<\/span>\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>Replace <code>Todo<\/code> with <code>Video<\/code> and rename the file <code>Videos<\/code>.<\/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\">  id: ID!\n  name: <span class=\"hljs-built_in\">String<\/span>!\n  description: <span class=\"hljs-built_in\">String<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next,  \u201cpush\u201d the schema to the AWS cloud by typing this command:\n<code>amplify push<\/code><\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>This process contains numerous steps, many of which are reflected in the <code>amplify\/backend\/api\/amplifyjamstackcloud\/build<\/code> directory. Any questions, feel free to <a href=\"https:\/\/codingcat.dev\">contact me<\/a>.<\/p><\/div>\n<p>Amplify then prompts you to reply to the questions below. Respond with the default for each of them.<\/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\">\u2714 Successfully pulled backend environment dev <span class=\"hljs-keyword\">from<\/span> the cloud.\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>Current Environment: dev<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Category<\/th>\n<th>Resource name<\/th>\n<th>Operation<\/th>\n<th>Provider plugin<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Api<\/td>\n<td>amplifyjamstackcloud<\/td>\n<td>Create<\/td>\n<td>awscloudformation<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<pre class=\"js-syntax-highlighted\"><code>? Are you sure you want to continue? Yes\n\nThe following types do not have '@auth' enabled. Consider using @auth with @model\n         - Videos\nLearn more about @auth here: &lt;https:\/\/docs.amplify.aws\/cli\/graphql-transformer\/directives#auth&gt;\n\nGraphQL schema compiled successfully.\n\nEdit your schema at \/Users\/ajonp\/web\/amplify-jamstack-cloudinary-video\/amplify\/backend\/api\/amplifyjamstackcloud\/schema.graphql or place .graphql files in a directory at \/Users\/ajonp\/web\/amplify-jamstack-cloudinary-video\/amplify\/backend\/api\/amplifyjamstackcloud\/schema\n? Do you want to generate code for your newly created GraphQL API Yes\n? Choose the code generation language target javascript\n? Enter the file name pattern of graphql queries, mutations and subscriptions src\/graphql\/**\/*.js\n\n? Do you want to generate\/update all possible GraphQL operations - queries, mutations and subscriptions Yes\n? Enter maximum statement depth [increase from default if your schema is deeply nested] 2\n\u283c Updating resources in the cloud. This may take a few minutes . . .\n<\/code><\/pre>\n<p>After creating and executing <code>CloudFormation<\/code> in the cloud, the AWS Amplify CLI outputs two credentials and stores them in the <code>src\/aws-exports.js<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>GraphQL endpoint: https:\/\/&lt;example&gt;.appsync-api.us-east-1.amazonaws.com\/graphql\nGraphQL API KEY: &lt;example&gt;\n<\/code><\/pre>\n<p>Your React app can now connect with GraphQL with the endpoint and API key.<\/p>\n<h3>Connecting the Front End to the API<\/h3>\n<p>Now create a simple app, largely according to the procedure described in the Amplify tutorial <a href=\"https:\/\/docs.amplify.aws\/start\/getting-started\/data-model\/q\/integration\/react#deploying-the-api\"><em>Getting Started<\/em><\/a>. Type this command to start React in your browser:<\/p>\n<p><code>npm run start<\/code><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_video_1.png\" alt=\"Amplify video\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"353\"\/><\/p>\n<p>At the bottom of the form are the name and description you added, if any. To see the DynamoDB data and verify that the storage is local, <a href=\"https:\/\/console.aws.amazon.com\/dynamodb\/home\">log in to your AWS account<\/a> and click the table that is displayed for your video name and description.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/amplify_video_geographical_region.png\" alt=\"geographical region\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"148\"\/><\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>In case of no such display, verify that you\u2019re in the correct geographical region.<\/p><\/div>\n<h2>Uploading Video<\/h2>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>To set up video on demand or streaming, follow the procedure in the tutorial <a href=\"https:\/\/codingcat.dev\/tutorials\/aws-amplify-video\/\"><em>AWS Amplify Video<\/em><\/a>.<\/p><\/div>\n<p>Upload the video for this project with <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">Cloudinary\u2019s upload widget<\/a>. Adopt the signed approach to leverage additional AWS Amplify features and better secure your Cloudinary account.<\/p>\n<h3>Setting Up Cloudinary<\/h3>\n<p>Add an upload preset in Cloudinary by first clicking the gear icon in your console and then clicking the <strong>Upload<\/strong> tab near the top to go to\n<code>https:\/\/cloudinary.com\/console\/&lt;your console&gt;\/settings\/upload<\/code>.<\/p>\n<p>Scroll down to <strong>Upload presets<\/strong> and click <strong>Add upload preset<\/strong>. On the screen that is displayed:<\/p>\n<ol>\n<li>Choose <strong>Signed<\/strong> from the pull-down menu under <strong>Signing Mode<\/strong>.<\/li>\n<li>Specify a folder name (e.g., <code>example folder<\/code>) under <strong>Folder<\/strong>.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/cld_upload_preset.png\" alt=\"upload preset\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"420\" height=\"512\"\/><\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Note the name of the upload preset at the top and your cloud name in your Cloudinary dashboard for use later.<\/p><\/div>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_400,c_fill,f_auto,q_auto\/Web_Assets\/blog\/cld_dashboard.png\" alt=\"Dashboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"486\"\/><\/p>\n<h3>Adding the Upload Code<\/h3>\n<p>To add the upload code, edit your <code>public\/index.html<\/code> file, as follows:<\/p>\n<p><strong>1.<\/strong> Add <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">Cloudinary\u2019s upload widget<\/a> by adding this script to the header section:<\/p>\n<p><code>&lt;script src=&quot;&lt;https:\/\/widget.cloudinary.com\/v2.0\/global\/all.js&gt;&quot; type=&quot;text\/javascript&quot;&gt;&lt;\/script&gt;<\/code><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/cld_upload_script.png\" alt=\"Upload script\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"491\" height=\"512\"\/><\/p>\n<p><strong>2.<\/strong> Add the variable below for the upload widget. Be sure to replace <code>my_cloud_name<\/code> and <code>my_preset<\/code> with their values.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>const uploadWidget = window.cloudinary.createUploadWidget({\n    cloudName: 'my_cloud_name', \n    uploadPreset: 'my_preset'}, (error, result) =&gt; { \n      if (!error &amp;&amp; result &amp;&amp; result.event === &quot;success&quot;) { \n        console.log('Done! Here is the image info: ', result.info); \n      }\n    }\n  );\n<\/code><\/pre>\n<p><strong>3.<\/strong> Add the <code>&lt;button&gt;<\/code> tag anywhere in the file for opening the widget. I recommend placing that code above that for the Submit button.<\/p>\n<p><code>&lt;button style={styles.button} onClick={addVideo}&gt;Create Video&lt;\/button&gt;<\/code><\/p>\n<p><strong>4.<\/strong> Add the function below for opening the widget:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\">    <span class=\"hljs-selector-tag\">uploadWidget<\/span><span class=\"hljs-selector-class\">.open<\/span>();\n  }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>At this point, clicking the <strong>Upload Video<\/strong> button might trigger the error message below. That\u2019s because you must first sign this upload for security. See the next section for the procedure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/cld_upload_queue.png\" alt=\"error message\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"67\"\/><\/p>\n<h3>Creating a Lambda Datasource for Signing<\/h3>\n<p>To obtain a signature from Cloudinary, create an API call with AWS Amplify and a Lambda datasource to enable a return of the request.<\/p>\n<p>First, create a function by running this command:<\/p>\n<p><code>amplify add function<\/code><\/p>\n<p>In response to the top five questions of the nine that are displayed, specify the parameters of the Lambda function (serverless function):<\/p>\n<pre class=\"js-syntax-highlighted\"><code>`cloudinarysignature`\n`cloudinarysignature`\n`NodeJS`\n`Hello World`\n<\/code><\/pre>\n<p>Respond with No to the bottom four questions. See the screenshot below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/terminal.png\" alt=\"terminal\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"118\"\/><\/p>\n<p>Next, connect the Lamba datasource to your AppSync API by adding the line below to the <code>amplify\/backend\/api\/amplifyjamstackcloud\/schema.graphql<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>type Query {\n  cloudinarysignature(msg: String): String @function(name: &quot;cloudinarysignature-${env}&quot;)\n}\n<\/code><\/pre>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p><code>${env}<\/code> in the above code makes available your development environment for use, especially if you\u2019d like to test your code later in a staging or product environment.<\/p><\/div>\n<p>Now load the updates  to AWS with this command:<\/p>\n<p><code>amplify push<\/code><\/p>\n<p>AWS then displays the output below, showing the new function to be created and the GraphQL API to be updated.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/current_environment.png\" alt=\"graphQL api\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"238\"\/><\/p>\n<p>Type <code>Y<\/code> in response to all the prompts. The process that follows takes a few minutes.<\/p>\n<p><strong>Tip:<\/strong> Type <code>amplify push --y <\/code> to skip the above questions in the future.\nNote that your stack is displayed in both the AWS console and CloudFormation. Below is an example.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_backend.png\" alt=\"Backend\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"493\"\/><\/p>\n<p>For a lighter version (example below), go to Amplify, select your project, and choose <strong>backend<\/strong> &gt; <strong>dev<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/amplify_backend_light.png\" alt=\"Backend light\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"275\"\/><\/p>\n<h3>Testing the New Function<\/h3>\n<p>After performing a push, Amplify sends you a message with your GraphQL endpoint and API key, which is also a confirmation that Amplify has updated your code, including your GraphQL values, locally. A new query called <code>cloudinarysignature<\/code>, with which you call your Lambda function through AppSync, is now in your <code>src\/graphql\/queries.js<\/code> file.<\/p>\n<p>Add this code, which calls your GraphQL endpoint, to your <code>App.js<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\/\/ eslint-disable-next-line no-unused-vars\nasync function fetchCloudinarySignature(cb, params) {\n  try {\n    const cSign = await API.graphql(graphqlOperation(cloudinarysignature, { msg: JSON.stringify(params) }));\n    const data = JSON.parse(cSign.data.cloudinarysignature);\n    console.log(`Uploading using key ${data.body}`);\n    return data.body;\n  } catch (err) {\n    console.log(&quot;error fetching signature&quot;);\n  }\n}\n\nThen update showWidget to call this post before opening our dialog. You could put this anywhere but I thought this would be easy.\nconst showWidget = () =&gt; {\n    fetchCloudinarySignature();\n    uploadWidget.open();\n  }\n<\/code><\/pre>\n<p>Lambda then returns the \u201cHello from Lambda!\u201d response you requested.<\/p>\n<p><code>{&quot;data&quot;:{&quot;cloudinarysignature&quot;:&quot;{statusCode=200, body=\\\\&quot;Hello from Lambda!\\\\&quot;}&quot;}}<\/code><\/p>\n<h3>Updating the Function to Call Cloudinary<\/h3>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>For details on this topic, see the <a href=\"https:\/\/cloudinary.com\/documentation\/node_integration#overview\">documentation on Cloudinary\u2019s Node.js SDK<\/a>.<\/p><\/div>\n<p>To update the Lambda function to call Cloudinary, follow these steps:<\/p>\n<p><strong>1.<\/strong> Add the Cloudinary SDK by running <code>npm install cloudinary<\/code> in the directory <code>amplify\/backend\/function\/cloudinarysignature\/src<\/code>. Tip: If you are using VSCode, just type the command and you\u2019ll be taken to that directory.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/npm_install_cld.png\" alt=\"npm install\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"288\"\/><\/p>\n<p><strong>2.<\/strong> Add the following code to the <code>amplify\/backend\/function\/cloudinarysignature\/src\/index.js<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\/* eslint-disable no-unused-vars *\/\n\/* eslint-disable no-undef *\/\n\nconst cloudinary = require(&quot;cloudinary&quot;).v2;\n\nexports.handler = async (event) =&gt; {\n  console.log(event);\n  \n  const secret = process.env.CLOUDINARY_API_SECRET;\n  const response = {\n    statusCode: 400,\n    body: `Missing CLOUDINARY_API_SECRET`,\n  };\n  if (!secret) {\n    return response;\n  }\n\n  const timestamp = Math.round(new Date().getTime() \/ 1000);\n  const signature = await cloudinary.utils.api_sign_request(\n    JSON.parse(event.arguments.msg),\n    secret\n  );\n\n  response.body = signature;\n  return JSON.stringify(response);\n};\n<\/code><\/pre>\n<p>Clicking the <strong>Upload Video<\/strong> button now triggers the error message that your Cloudinary key is missing:\n<code>{&quot;data&quot;:{&quot;cloudinarysignature&quot;:&quot;{statusCode=400, body=Missing CLOUDINARY_API_SECRET}&quot;}}<\/code><\/p>\n<p><strong>3.<\/strong> Get the Cloudinary key from your Cloudinary dashboard, go to the AWS Console, and click <a href=\"https:\/\/console.aws.amazon.com\/lambda\/home?region=us-east-1#\/functions\"><strong>Lambda &gt; Functions<\/strong><\/a>.<\/p>\n<p><strong>4.<\/strong> Click the <code>cloudinarysignature-dev<\/code> function on the list. Scroll down to the <strong>Environment variables<\/strong> section and click <strong>Edit<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/environment_var.png\" alt=\"Environment variables\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"98\"\/><\/p>\n<p><strong>5.<\/strong> In the <strong>Edit environment variables<\/strong> screen (see below), fill in the <strong>CLOUDINARY_API_SECRET<\/strong> field with your API key and click <strong>Save<\/strong>.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Keep your API key confidential and do <strong>not<\/strong> put it in your code repository.<\/p><\/div>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/edit_environment_var.png\" alt=\"Edit Environment variables\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"329\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/api_key.png\" alt=\"API Key\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"509\"\/><\/p>\n<p>As a test, go to your React app at <code>http:\/\/localhost:3000\/<\/code> and click <strong>Upload Video<\/strong> to ensure that React returns your secret key.<\/p>\n<h2>Updating App.js for Secret<\/h2>\n<p>Now the call is ready for use with your <code>creatUploadWidget<\/code> function request. Below is the complete content of the <code>App.js<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\/* src\/App.js *\/\nimport React, { useEffect, useState } from &quot;react&quot;;\nimport Amplify, { API, graphqlOperation } from &quot;aws-amplify&quot;;\nimport { createVideo } from &quot;.\/graphql\/mutations&quot;;\nimport { listVideos, cloudinarysignature } from &quot;.\/graphql\/queries&quot;;\n\nimport awsExports from &quot;.\/aws-exports&quot;;\nAmplify.configure(awsExports);\n\nconst initialState = {\n  name: &quot;&quot;,\n  description: &quot;&quot;,\n  cloudinary: null,\n};\n\n\/\/ eslint-disable-next-line no-unused-vars\nasync function fetchCloudinarySignature(cb, params) {\n  try {\n    const cSign = await API.graphql(\n      graphqlOperation(cloudinarysignature, { msg: JSON.stringify(params) })\n    );\n    const data = JSON.parse(cSign.data.cloudinarysignature);\n    console.log(`Uploading using key ${data.body}`);\n    return data.body;\n  } catch (err) {\n    console.log(&quot;error fetching signature&quot;);\n  }\n}\n\nconst App = () =&gt; {\n  const [formState, setFormState] = useState(initialState);\n  const [videos, setVideos] = useState([]);\n\n  useEffect(() =&gt; {\n    fetchVideos();\n  }, []);\n\n  function setInput(key, value) {\n    setFormState({ ...formState, [key]: value });\n  }\n\n  const uploadWidget = window.cloudinary.createUploadWidget(\n    {\n      cloudName: &quot;ajonp&quot;,\n      uploadPreset: &quot;dxf42z9k&quot;,\n    },\n    (error, result) =&gt; {\n      if (!error &amp;&amp; result &amp;&amp; result.event === &quot;success&quot;) {\n        console.log(&quot;Done! Here is the video info: &quot;, result.info);\n        setInput(&quot;cloudinary&quot;, JSON.stringify(result.info));\n      }\n      if (error) {\n        console.log(error);\n      }\n    }\n  );\n  const showWidget = () =&gt; {\n    uploadWidget.open();\n  };\n\n  async function fetchVideos() {\n    try {\n      const videoData = await API.graphql(graphqlOperation(listVideos));\n      const videos = videoData.data.listVideos.items;\n      videos.map((video) =&gt; {\n        video.cloudinary = JSON.parse(video.cloudinary);\n      });\n      setVideos(videos);\n    } catch (err) {\n      console.log(&quot;error fetching videos&quot;);\n    }\n  }\n\n  async function addVideo() {\n    try {\n      if (!formState.name || !formState.description) return;\n      const video = { ...formState };\n      setVideos([...videos, video]);\n      setFormState(initialState);\n      await API.graphql(graphqlOperation(createVideo, { input: video }));\n    } catch (err) {\n      console.log(&quot;error creating video:&quot;, err);\n    }\n  }\n\n  return (\n    &lt;div style={styles.container}&gt;\n      &lt;h2&gt;Amplify Videos&lt;\/h2&gt;\n      &lt;button\n        style={styles.uploadButton}\n        className=&quot;cloudinary-button&quot;\n        onClick={showWidget}\n      &gt;\n        Upload Video\n      &lt;\/button&gt;\n      &lt;input\n        onChange={(event) =&gt; setInput(&quot;name&quot;, event.target.value)}\n        style={styles.input}\n        value={formState.name}\n        placeholder=&quot;Name&quot;\n        required\n      \/&gt;\n      &lt;input\n        onChange={(event) =&gt; setInput(&quot;description&quot;, event.target.value)}\n        style={styles.input}\n        value={formState.description}\n        placeholder=&quot;Description&quot;\n      \/&gt;\n\n      &lt;button style={styles.button} onClick={addVideo}&gt;\n        Add Video to List\n      &lt;\/button&gt;\n      {videos.map((video, index) =&gt; (\n        &lt;div key={video.id ? video.id : index} style={styles.video}&gt;\n          &lt;p style={styles.videoName}&gt;{video.name}&lt;\/p&gt;\n          &lt;p style={styles.videoDescription}&gt;{video.description}&lt;\/p&gt;\n          &lt;div style={styles.vids}&gt;\n            &lt;video controls muted width=&quot;320&quot; height=&quot;240&quot;&gt;\n              &lt;source\n                src={video.cloudinary.secure_url}\n                type=&quot;video\/mp4&quot;\n              &gt;&lt;\/source&gt;\n            &lt;\/video&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      ))}\n    &lt;\/div&gt;\n  );\n};\n\nconst styles = {\n  vids: {\n    maxWidth: &quot;800px&quot;,\n  },\n  container: {\n    width: 400,\n    margin: &quot;0 auto&quot;,\n    display: &quot;flex&quot;,\n    flexDirection: &quot;column&quot;,\n    justifyContent: &quot;center&quot;,\n    padding: 20,\n  },\n  video: { marginBottom: 15 },\n  input: {\n    border: &quot;none&quot;,\n    backgroundColor: &quot;#ddd&quot;,\n    marginBottom: 10,\n    padding: 8,\n    fontSize: 18,\n  },\n  videoName: { fontSize: 20, fontWeight: &quot;bold&quot; },\n  videoDescription: { marginBottom: 0 },\n  button: {\n    backgroundColor: &quot;black&quot;,\n    color: &quot;white&quot;,\n    outline: &quot;none&quot;,\n    fontSize: 18,\n    padding: &quot;12px 0px&quot;,\n  },\n  uploadButton: { margin: &quot;22px&quot; },\n};\n\nexport default App;\n<\/code><\/pre>\n<p>Be sure to update your GraphQL by adding Cloudinary\u2019s JSON:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>type Video @model {\n  id: ID!\n  name: String!\n  description: String\n  cloudinary: AWSJSON\n}\ntype Query {\n  cloudinarysignature(msg: String): String @function(name: &quot;cloudinarysignature-${env}&quot;)\n}\n<\/code><\/pre>\n<h2>Publishing to Amplify Web Hosting<\/h2>\n<p>Follow these three simple steps:<\/p>\n<p><strong>1.<\/strong> Build your app. Type:<\/p>\n<p><code>npm run build<\/code><\/p>\n<p><strong>2.<\/strong> Add the hosting capability. Type:<\/p>\n<p><code>amplify add hosting<\/code><\/p>\n<p>Respond to the two prompts that are displayed as follows:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_prompt-1.png\" alt=\"Prompt\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"120\"\/><\/p>\n<p><strong>3.<\/strong> Push the content to the web. Type:\n<code>amplify publish<\/code>\n<img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_current_env.png\" alt=\"Current environment\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"141\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_500,c_fill,f_auto,q_auto\/Web_Assets\/blog\/amplify_deployed_app.png\" alt=\"Deployed app\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"358\"\/><\/p>\n<p>That URL at the bottom, <code>https:\/\/dev.d2hxdxps86f74m.amplifyapp.com\/<\/code>, is your new app. Feel free to rename it with a custom domain.<\/p>\n<h2>Accessing the Demo and Amplify Tutorial<\/h2>\n<p>Here\u2019s a <a href=\"https:\/\/amplify-cloudinary.codingcat.dev\">demo<\/a> of the app. Also, the tutorial <a href=\"https:\/\/aws.amazon.com\/amplify\/getting-started\/?nc=sn&amp;loc=4\"><em>Getting Started With AWS Amplify<\/em><\/a> is a handy reference.<\/p>\n<h2>Enhancing the App<\/h2>\n<p>A few suggestions:<\/p>\n<ul>\n<li>Add the Cloudinary JavaScript loader to spotlight the actual video.<\/li>\n<li>Add an authentication process to restrict the publishing privilege to the authorized people only.<\/li>\n<li>Instead of uploading videos with the Cloudinary upload widget, upload to S3 and then update with the Cloudinary SDK from a Lambda trigger.<\/li>\n<li>For a real-time feel whenever changes occur, update the list through a subscription model.<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":22264,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[175,304],"class_list":["post-22263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-jamstack","tag-video-transformation"],"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>Amplify Your Jamstack With Cloudinary Video<\/title>\n<meta name=\"description\" content=\"Build an app in React, host it in AWS Amplify, and upload and transform the videos in Cloudinary.\" \/>\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\/amplify_your_jamstack_with_video\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Amplify Your Jamstack With Video\" \/>\n<meta property=\"og:description\" content=\"Build an app in React, host it in AWS Amplify, and upload and transform the videos in Cloudinary.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-12T17:30:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-09-23T16:58:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\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\/amplify_your_jamstack_with_video#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Amplify Your Jamstack With Video\",\"datePublished\":\"2021-01-12T17:30:58+00:00\",\"dateModified\":\"2022-09-23T16:58:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\"},\"wordCount\":5,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA\",\"keywords\":[\"JAMStack\",\"Video Transformation\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\",\"url\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\",\"name\":\"Amplify Your Jamstack With Cloudinary Video\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA\",\"datePublished\":\"2021-01-12T17:30:58+00:00\",\"dateModified\":\"2022-09-23T16:58:58+00:00\",\"description\":\"Build an app in React, host it in AWS Amplify, and upload and transform the videos in Cloudinary.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Amplify Your Jamstack With Video\"}]},{\"@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":"Amplify Your Jamstack With Cloudinary Video","description":"Build an app in React, host it in AWS Amplify, and upload and transform the videos in 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\/amplify_your_jamstack_with_video","og_locale":"en_US","og_type":"article","og_title":"Amplify Your Jamstack With Video","og_description":"Build an app in React, host it in AWS Amplify, and upload and transform the videos in Cloudinary.","og_url":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video","og_site_name":"Cloudinary Blog","article_published_time":"2021-01-12T17:30:58+00:00","article_modified_time":"2022-09-23T16:58:58+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b-png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video"},"author":{"name":"","@id":""},"headline":"Amplify Your Jamstack With Video","datePublished":"2021-01-12T17:30:58+00:00","dateModified":"2022-09-23T16:58:58+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video"},"wordCount":5,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA","keywords":["JAMStack","Video Transformation"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video","url":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video","name":"Amplify Your Jamstack With Cloudinary Video","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA","datePublished":"2021-01-12T17:30:58+00:00","dateModified":"2022-09-23T16:58:58+00:00","description":"Build an app in React, host it in AWS Amplify, and upload and transform the videos in Cloudinary.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/amplify_your_jamstack_with_video#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Amplify Your Jamstack With Video"}]},{"@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\/v1649719572\/Web_Assets\/blog\/AmplifyJamstack-blog_2226409f6b\/AmplifyJamstack-blog_2226409f6b.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22263","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=22263"}],"version-history":[{"count":4,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22263\/revisions"}],"predecessor-version":[{"id":25163,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22263\/revisions\/25163"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/22264"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=22263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=22263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=22263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}