{"id":27753,"date":"2022-06-08T07:34:04","date_gmt":"2022-06-08T07:34:04","guid":{"rendered":"http:\/\/track-image-impressions-in-gatsby.js-with-supabase"},"modified":"2022-06-08T07:34:04","modified_gmt":"2022-06-08T07:34:04","slug":"track-image-impressions-in-gatsby-js-with-supabase","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/","title":{"rendered":"Track Image Impressions in Gatsby.js with Supabase"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>How can we know if our efforts are worth the time and resources if we don\u2019t measure the most crucial digital analytics metrics? Understanding and tracking the correct metrics is critical in ensuring that marketing activities are effective.<\/p>\n<p>Impression as a form of metric refers to the number of times a web content was displayed to users. This metric vastly differs from reach, which only measures the number of people that have viewed your content. It is important not to confuse an impression with an engagement.<\/p>\n<p>This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.<\/p>\n<h3>CodeSandbox and GitHub<\/h3>\n<p>We completed this project in <a href=\"https:\/\/codesandbox.io\/s\/serverless-dew-qqhk2y\">CodeSandbox<\/a>. Fork it to get started quickly.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/serverless-dew-qqhk2y?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"Track image impressions in Gatsby.js with Supabase\"\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 \"><p>The source code is on <a href=\"https:\/\/github.com\/ugwutotheeshoes\/gatsby-supabase\">GitHub<\/a>.<\/p>\n<h3>Prerequisites<\/h3>\n<p>To get the most out of this article, the following requirements apply:<\/p>\n<ul>\n<li>Basic understanding of <a href=\"https:\/\/www.gatsbyjs.com\/\">Gatsby.js<\/a>\n<\/li>\n<li>Supabase account (sign up <a href=\"https:\/\/app.supabase.io\/\">here<\/a>)<\/li>\n<li>Cloudinary account (sign up <a href=\"https:\/\/cloudinary.com\/homepage-2\">here<\/a>)<\/li>\n<\/ul>\n<h3>Project Setup and Installation<\/h3>\n<p>Create a Gatsby.js app in a new folder by running the following command in the terminal:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm init gatsby\n<\/code><\/span><\/pre>\n<p>It will request a project title and the directory name for the project. Continue to follow the prompts to select a preferred language (JavaScript or TypeScript), CMS, styling tools, and other features.\nThen Gatsby.js will ask to create a Gatsby site in the directory of the project:<\/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\">    Create a <span class=\"hljs-keyword\">new<\/span> Gatsby site <span class=\"hljs-keyword\">in<\/span> the folder &lt;project-name&gt;\n    Shall we <span class=\"hljs-keyword\">do<\/span> <span class=\"hljs-keyword\">this<\/span>? <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Y<\/span>\/<span class=\"hljs-attr\">n<\/span>&gt;<\/span><\/span> : Yes\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>Navigate into the project directory and install Cloudinary React SDK, Supabase, and <code>react-intersection-observer<\/code> dependencies.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" 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-name<\/span>&gt;<\/span>\n    npm install cloudinary-react @supabase\/supabase-js react-intersection-observer\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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>Running <code>npm run develop<\/code> starts the project on the local development server at <a href=\"https:\/\/localhost:8000\">https:\/\/localhost:8000<\/a> in our browser.<\/p>\n<h3>Setting up a Supabase Project<\/h3>\n<h3>What is Supabase?<\/h3>\n<p><a href=\"https:\/\/app.supabase.io\/\">Supabase <\/a>is an open-source <a href=\"https:\/\/firebase.google.com\/\">Firebase <\/a>alternative made up of tools that help developers build projects faster by handling backend functions.<\/p>\n<p>Behind the scenes, Supabase uses the <a href=\"https:\/\/www.postgresql.org\/\">PostgreSQL <\/a>database and it is regarded widely as one of the best tools based on Postgres &#8211; a highly scalable relational database. The platform develops a REST API from the database\u2019s tables and columns. Its autogenerated APIs include built-in features like filtering and sorting.<\/p>\n<p>To get started, create an account in Supabase <a href=\"https:\/\/app.supabase.io\/\">here<\/a>. We\u2019ll also need a GitHub account; click <a href=\"http:\/\/github.com\/\">here <\/a>to create one.<\/p>\n<p>After logging in, we\u2019ll be redirected to the Supabase dashboard, as shown below, where we\u2019ll create a new Supabase project for the demo application.<\/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_sanity\/e6d7faf3f81fa9328ee523d325e1700316278bea-1349x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1349\" height=\"663\"\/><\/p>\n<p>Set a name and password for the new project and click on the \u201cNew project\u201d button to create the project as shown below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams_sanity\/e6d7faf3f81fa9328ee523d325e1700316278bea-1349x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1349\" height=\"663\"\/><\/p>\n<p>As the project is being built, we\u2019ll create the database for the image impressions by clicking on the database icon shown on the sidebar. After that, click on the \u201cNew\u201d button at the top right of the screen to create a table for the database.<\/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_sanity\/e9e844c19ce2c2e2935a1837dec8ec52fa3ee441-1349x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1349\" height=\"663\"\/><\/p>\n<p>We created multiple columns for the database table in the above image. The created columns represent the following:<\/p>\n<ul>\n<li>\n<code>id<\/code> &#8211; key value to access the database<\/li>\n<li>\n<code>name<\/code> &#8211; name of the database<\/li>\n<li>\n<code>created_at<\/code> &#8211; time stamp for creating the database<\/li>\n<li>\n<code>views<\/code> &#8211; number of image impressions<\/li>\n<\/ul>\n<p>After creating these columns, we\u2019ll access the Table editor by clicking the Table icon shown on the sidebar to add a default value for our table. Click on \u201cinsert row\u201d and add the default values below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams_sanity\/bff4e26f888a963ac31101bd5b9ea0f61b1a4e65-1349x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1349\" height=\"663\"\/><\/p>\n<p>Navigate to the SQL editor and create a query tab to add a stored procedure to our database. A stored procedure allows us to add or extend functionality to the database.<\/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_sanity\/b566c451a07618374a612ab60b5ca19a09612339-1366x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1366\" height=\"663\"\/><\/p>\n<p>Add the code snippet below to the new query to create the stored procedure for our database:<\/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\">    create <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">increment<\/span> (<span class=\"hljs-params\">row_id int<\/span>)\n    <span class=\"hljs-title\">returns<\/span> <span class=\"hljs-title\">void<\/span> <span class=\"hljs-title\">as<\/span>\n    <span class=\"hljs-title\">$$<\/span>\n      <span class=\"hljs-title\">update<\/span> <span class=\"hljs-title\">pages<\/span>\n      <span class=\"hljs-title\">set<\/span> <span class=\"hljs-title\">views<\/span> = <span class=\"hljs-title\">views<\/span> + 1\n      <span class=\"hljs-title\">where<\/span> <span class=\"hljs-title\">id<\/span> = <span class=\"hljs-title\">row_id<\/span>;\n    <span class=\"hljs-title\">$$<\/span> \n    <span class=\"hljs-title\">language<\/span> <span class=\"hljs-title\">sql<\/span> <span class=\"hljs-title\">volatile<\/span>;\n\n<\/span><\/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>Let\u2019s break down the query above:<\/p>\n<ul>\n<li>Creates an increment function, with the row <code>id<\/code> as an argument<\/li>\n<li>\n<code>set views = views + 1<\/code> updates\/increases the image impressions value called <code>views<\/code> in the database table by 1<\/li>\n<\/ul>\n<p>Then, click the \u201cRUN\u201d button to create the function. Later we\u2019ll utilize the function to update the image impressions.<\/p>\n<h3>Setting up an Image in Cloudinary<\/h3>\n<p>Cloudinary is a cloud-based picture and video management service that includes uploads, storage, manipulations, optimizations, and distribution. It also enables developers to include video players in their apps that properly handle video events.<\/p>\n<p>After successfully creating an account, Cloudinary will redirect us to our account\u2019s dashboard page, where we can upload the demo image.<\/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_sanity\/ca12e2566505bca21a1ca28b447c266bfcd06f6e-1366x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1366\" height=\"663\"\/><\/p>\n<p>Click on the \u201cUpload\u201d button as shown above and select the image file to be uploaded.<\/p>\n<h3>Implementing the Cloudinary Image<\/h3>\n<p>In the <code>index.js<\/code> file, we\u2019ll import the required components from Cloudinary React SDK and integrate the Cloudinary image, as shown below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/pages\/components\/index.js<\/span>\n    \n    <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> { Image, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    \n    <span class=\"hljs-keyword\">const<\/span> IndexPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">return<\/span>(\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloud_name<\/span>=<span class=\"hljs-string\">\"OUR-CLOUD-NAME\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"image-container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span>\n         <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">\"OUR-IMAGE-NAME\"<\/span>\n         <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"300px\"<\/span>\n         <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"400px\"<\/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\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n    )};\n    \n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> IndexPage;\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 code above, we do the following:<\/p>\n<ul>\n<li>Apply the Cloud name from our Cloudinary account details on the dashboard page<\/li>\n<li>Include the name of the image from Cloudinary in the Image component<\/li>\n<li>Give the image a width of 300px and a height of 400px<\/li>\n<\/ul>\n<p>Next, we\u2019ll loop through an array of dummy text to make the app look better:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">const<\/span> IndexPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">return<\/span>(\n     <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Track Image impressions in Gatsby.js with Supabase<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>tracking image impressions in gatsby.js with supabase<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n          {Array.from(Array(5).keys()).map((i) =&gt; (\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{i}<\/span>&gt;<\/span>\n              Irure pariatur velit est anim ipsum anim aliquip officia velit\n              consectetur. Duis sint ut consectetur ea anim. Sit proident culpa\n              velit officia do incididunt Lorem in deserunt non adipisicing occaecat\n              magna. Occaecat occaecat esse excepteur consequat occaecat cupidatat\n              aliquip labore esse ad ea. Laboris id excepteur nisi voluptate sunt\n              anim commodo amet reprehenderit.\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n          ))}\n    \n     \/\/ ... { Cloudinary Image }\n    \n      {Array.from(Array(8).keys()).map((i) =&gt; (\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{i}<\/span>&gt;<\/span>\n              Irure pariatur velit est anim ipsum anim aliquip officia velit\n              consectetur. Duis sint ut consectetur ea anim. Sit proident culpa\n              velit officia do incididunt Lorem in deserunt non adipisicing occaecat\n              magna. Occaecat occaecat esse excepteur consequat occaecat cupidatat\n              aliquip labore esse ad ea. Laboris id excepteur nisi voluptate sunt\n              anim commodo amet reprehenderit.\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n          ))}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/span>\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> IndexPage;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>After configuring the dummy text, the demo application will look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams_sanity\/9533f9a1f3a5d6ce58749926f6dccff8bdccae2e-600x338.gif\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"338\"\/><\/p>\n<p>Integrating <code>react-intersection-observer<\/code><\/p>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Intersection_Observer_API\"><code>react-intersection-observer<\/code><\/a> is the React implementation of the Intersection Observer API that indicates when an element enters or leaves the viewport. It contains a hook, renders props, and plain children implementation.<\/p>\n<p>It provides a <code>useInView<\/code> hook, which makes it easy to monitor the state of our components. We\u2019ll use the custom <code>InView<\/code> component, which will be called whenever the state changes, with a <code>ref<\/code> that should be assigned to the element root. The <code>InView<\/code> component uses a default state of true or false, so if the image enters the viewport, its state is true, and if it leaves the viewport, its state is false.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/index.js<\/span>\n\n<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> { Image, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> IndexPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<span class=\"hljs-keyword\">return<\/span>( \n\n<span class=\"hljs-comment\">\/\/array of dummy text<\/span>\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloud_name<\/span>=<span class=\"hljs-string\">\"OUR-CLOUD-NAME\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">InView<\/span>&gt;<\/span>\n          {({ ref }) =&gt; (\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"image-container\"<\/span> <span class=\"hljs-attr\">ref<\/span>=<span class=\"hljs-string\">{ref}<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span>\n                <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">\"OUR-IMAGE-NAME\"<\/span>\n                <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"300px\"<\/span>\n                <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"400px\"<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          )}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">InView<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n\n<span class=\"hljs-comment\">\/\/ array of dummy text<\/span>\n\n)};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> IndexPage;\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<h3>Updating the Image Impressions<\/h3>\n<p>We\u2019ll need to link our Supabase API URL and API Key to the demo application.\nFirst off, head to Supabase\u2019s settings, then go to the \u201cAPI\u201d section, where we can access our Supabase project\u2019s API URL and API Key as shown below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams_sanity\/58065e58dcb66f6efdb078d3dccb04cd15fe736e-1366x663.png\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1366\" height=\"663\"\/><\/p>\n<p>Then, create a <code>.env<\/code> file in the app\u2019s root directory to store the API URL and API Key:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">    <span class=\"hljs-comment\">#.env<\/span>\n    SUPABASE_URL= OUR_PUBLIC_SUPABASE_URL\n    SUPABASE_KEY= OUR_PUBLIC_SUPABASE_KEY\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, we\u2019ll add the API URL and API Key to the <code>index.js<\/code> file:<\/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-comment\">\/\/pages\/components\/index.js<\/span>\n    <span class=\"hljs-keyword\">import<\/span> { createClient } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@supabase\/supabase-js\"<\/span>;\n    \n    <span class=\"hljs-keyword\">const<\/span> IndexPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> supabase = createClient(\n      process.env.SUPABASE_URL,\n      process.env.SUPABASE_KEY\n    );\n     <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"hljs-comment\">\/\/ Cloudinary Image<\/span>\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>To update the Supabase database, we\u2019ll create the function, <code>endFunction<\/code>, which is triggered anytime the state of the <code>InView<\/code> component changes. The function uses a <a href=\"https:\/\/supabase.com\/docs\/reference\/javascript\/rpc\">Supabase Remote Procedure Call (RPC)<\/a> to increase the number of impressions at Supabase\u2019s database by 1:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/index.js<\/span>\n    <span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { Image, CloudinaryContext } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    \n    <span class=\"hljs-keyword\">const<\/span> IndexPage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> supabase = createClient(\n      process.env.SUPABASE_URL,\n      process.env.SUPABASE_KEY\n    );\n      <span class=\"hljs-keyword\">const<\/span> endFunction = <span class=\"hljs-keyword\">async<\/span> (inView) =&gt; {\n        <span class=\"hljs-keyword\">if<\/span> (inView) {\n          <span class=\"hljs-keyword\">const<\/span> { data, error } = <span class=\"hljs-keyword\">await<\/span> supabase.rpc(<span class=\"hljs-string\">\"increment\"<\/span>, { <span class=\"hljs-attr\">row_id<\/span>: <span class=\"hljs-number\">1<\/span> });\n        }\n      };\n     <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloud_name<\/span>=<span class=\"hljs-string\">\"OUR-CLOUD-NAME\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">InView<\/span> <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(inView)<\/span> =&gt;<\/span> endFunction(inView)}&gt;\n    \n              \/\/ .....\n    \n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">InView<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n    )};\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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>After testing the demo application, it should look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams_sanity\/77825576b992e8f2f01c3124cd9a81e5eec69241-600x338.gif\" alt=\"image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"338\"\/><\/p>\n<h3>Conclusion<\/h3>\n<p>This article discussed what Supabase is, the advantages of implementing it in applications, and, more importantly, how to integrate Supabase into web applications.<\/p>\n<h3>Resources<\/h3>\n<ul>\n<li>\n<a href=\"https:\/\/supabase.com\/docs\/guides\/with-nextjs\">Supabase Documentation for Next.js<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/react_quick_start\">Documentation for Cloudinary React JS SDK<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Intersection_Observer_API\"><code>react-intersection-observer<\/code> Documentation<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27754,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[332,378,379,134,370,380,371],"class_list":["post-27753","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-api","tag-gatsbyjs","tag-graphql","tag-guest-post","tag-image","tag-serverless","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Track Image Impressions in Gatsby.js with Supabase<\/title>\n<meta name=\"description\" content=\"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.\" \/>\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\/track-image-impressions-in-gatsby-js-with-supabase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Track Image Impressions in Gatsby.js with Supabase\" \/>\n<meta property=\"og:description\" content=\"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-08T07:34:04+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\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.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\/track-image-impressions-in-gatsby-js-with-supabase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Track Image Impressions in Gatsby.js with Supabase\",\"datePublished\":\"2022-06-08T07:34:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA\",\"keywords\":[\"API\",\"GatsbyJS\",\"GraphQL\",\"Guest Post\",\"Image\",\"Serverless\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\",\"name\":\"Track Image Impressions in Gatsby.js with Supabase\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA\",\"datePublished\":\"2022-06-08T07:34:04+00:00\",\"description\":\"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA\",\"width\":5766,\"height\":3964},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Track Image Impressions in Gatsby.js with Supabase\"}]},{\"@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":"Track Image Impressions in Gatsby.js with Supabase","description":"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.","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\/track-image-impressions-in-gatsby-js-with-supabase\/","og_locale":"en_US","og_type":"article","og_title":"Track Image Impressions in Gatsby.js with Supabase","og_description":"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-06-08T07:34:04+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/"},"author":{"name":"","@id":""},"headline":"Track Image Impressions in Gatsby.js with Supabase","datePublished":"2022-06-08T07:34:04+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","keywords":["API","GatsbyJS","GraphQL","Guest Post","Image","Serverless","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/","name":"Track Image Impressions in Gatsby.js with Supabase","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","datePublished":"2022-06-08T07:34:04+00:00","description":"This article demonstrates how to track image impressions using Gatsby.js and Supabase \u2014 a serverless database.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","width":5766,"height":3964},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/track-image-impressions-in-gatsby-js-with-supabase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Track Image Impressions in Gatsby.js with Supabase"}]},{"@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\/v1681926349\/Web_Assets\/blog\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464\/dce2d7f6a4cb33043a440c5b073f63d34a962af4-5766x3964-1_2775446464.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27753","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=27753"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27753\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27754"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27753"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27753"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27753"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}