{"id":27995,"date":"2022-05-22T16:15:10","date_gmt":"2022-05-22T16:15:10","guid":{"rendered":"http:\/\/handling-data-storage-with-cloudinary-and-supabase"},"modified":"2023-07-09T03:15:08","modified_gmt":"2023-07-09T10:15:08","slug":"handling-data-storage-with-cloudinary-and-supabase","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/","title":{"rendered":"Handling Data Storage with Cloudinary and Supabase"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><h1>Handling data storage with Cloudinary and Supabase in NextJS<\/h1>\n<p>When building Jamstack applications, data storage is often a significant consideration. The popular choices are often CMSs and for good reason. However, In this post, we\u2019ll explore a different approach that combines Cloudinary and Supabase to store and retrieve user data upon registration.<\/p>\n<p>Users often provide their name, email, and avatar when signing up for online accounts. What if we can store the data in a database like <a href=\"https:\/\/supabase.io\/\">Supabase<\/a> and deliver the images via Cloudinary. This would allow us to have a central data store but also give us the ability to apply transformations and on-the-fly manipulations to our media assets.<\/p>\n<p>Let\u2019s dive in and find out how we can achieve that. First, here are the technologies we\u2019ll be using to demonstrate this approach.<\/p>\n<ul>\n<li>\n<p><a href=\"http:\/\/cloudinary.com\">Cloudinary<\/a> is a platform on which we can upload, store, manage, transform, and deliver images and videos for web and mobile applications.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/supabase.io\/\">Supabase<\/a> is the Open Source Firebase Alternative that makes it easy to create backend functionalities for our project in less than 2 minutes.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/nextjs.org\/\">Next.js<\/a> is a React-based frontend development framework that supports <a href=\"https:\/\/cloudinary.com\/glossary\/server-side-rendering\">server-side rendering<\/a> and static site generation.<\/p>\n<\/li>\n<\/ul>\n<h2>Sandbox<\/h2>\n<p>We completed this project in a <a href=\"https:\/\/codesandbox.io\/s\/cloudinary-supabase-demo-wpqj5g\">CodeSandbox<\/a>. Fork and run it to quickly get started.<\/p>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/cloudinary-supabase-demo-wpqj5g?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=\"handling data storage with Cloudinary and 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\n<div class=\"wp-block-cloudinary-markdown \"><p>View source code on <a href=\"https:\/\/github.com\/Kizmelvin\/data-handling-cloudinary-supabase-next.js\">GitHub<\/a>.<\/p>\n<h2>Prerequisites<\/h2>\n<p>This post requires the following:<\/p>\n<ul>\n<li>Experience with JavaScript and React.<\/li>\n<li>Installation of Node.js.<\/li>\n<li>Familiarity with Next.js.<\/li>\n<li>A Cloudinary account. <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Signup<\/a> is free!<\/li>\n<li>A Supabase account. <a href=\"https:\/\/supabase.io\/\">Signup<\/a> here.<\/li>\n<\/ul>\n<h2>Setting Up and Installations<\/h2>\n<p>First, create an unsigned upload preset on Cloudinary. This will make it possible for us to upload data to Cloudinary from a client.<\/p>\n<p>To do that, click on the <strong>Settings<\/strong> &gt;&gt; <strong>Uploads<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_0AF07072EB0876555EAE8C57076920570F12F08BC1E1B84589A1A8A729DC6F24_1651515068197_Screenshot+2022-05-02+at+6.42.17+PM.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1333\" height=\"646\"\/><\/p>\n<p>Now, scroll down to upload presets and click on \u201cAdd upload presets.\u201d<\/p>\n<ul>\n<li>Create an upload preset name.<\/li>\n<li>Set signing mode to unsigned.<\/li>\n<li>Create the desired folder to house the image uploads.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_0AF07072EB0876555EAE8C57076920570F12F08BC1E1B84589A1A8A729DC6F24_1651515439085_Screenshot+2022-05-02+at+6.50.58+PM.png\" alt=\"create upload preset in Cloudinary\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1333\" height=\"646\"\/><\/p>\n<p>Next, we\u2019ll <a href=\"https:\/\/app.supabase.io\/\">log in<\/a> to Supabase and create a new project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_814E86809ACCE4EE468A338DE473A613D06174BFA2B11C190B5FC8807D09A9B8_1652222872370_supab1.gif\" alt=\"Create new Supabase account\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1014\" height=\"622\"\/><\/p>\n<p>After creating the project in a new or an already existing organization, copy and save the <code>anon public key<\/code> and the <code>project URL<\/code>. We\u2019ll be using them later in this application.<\/p>\n<p>Next, let\u2019s create a Supabase Schema that will hold our data:<\/p>\n<ol>\n<li>Click on the table editor icon, and click on the <strong>Create a new table<\/strong> button.<\/li>\n<li>Give the table a name, add columns for the fields you want, and click the <strong>Save<\/strong> button.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_814E86809ACCE4EE468A338DE473A613D06174BFA2B11C190B5FC8807D09A9B8_1652226163341_supabase3.gif\" alt=\"Create a table in Supabase\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1010\" height=\"619\"\/><\/p>\n<h2>Setup a Next.js project<\/h2>\n<p>Create a new Next.js application named <strong>cloudinary-next-demo<\/strong> by running the following command in the terminal:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-next-app data-handling\n<\/code><\/span><\/pre>\n<p>This will create a <code>data-handling<\/code> application for you. After that, change directory into the <strong>data-handling<\/strong> project you created with the command:<\/p>\n<p>Next, run the following command in the terminal to create a new Next.js application:<\/p>\n<pre><code>npx create-next-app data-handling\n<\/code><\/pre>\n<p>The above command creates a starter next.js application in the project folder.<\/p>\n<p>Next, install <a href=\"https:\/\/react-bootstrap.github.io\/getting-started\/introduction\">the bootstrap library<\/a> for styling with the following command:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-comment\"># to navigate into the project directory<\/span>\ncd data-handling \n    \n<span class=\"hljs-comment\"># Install Bootstrap<\/span>\nnpm install react-bootstrap bootstrap\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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, import the Bootstrap CSS file into the <code>_app.js<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"bootstrap\/dist\/css\/bootstrap.min.css\"<\/span>;\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>Finally, run the following command to start our dev server:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">npm run dev <span class=\"hljs-comment\"># to run the dev server<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">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.js will start a live development server at <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a>.<\/p>\n<h2>Handling Data<\/h2>\n<p>When a user submits the registration form, we\u2019ll send their data to Supabase for storage. Consequently, we\u2019ll retrieve the submitted image of the user and host it on Cloudinary. From there, we can apply transformations and serve them to the client on request.<\/p>\n<p>First, let\u2019s set up our Supabase configurations locally.<\/p>\n<p>Create a <code>.env.local<\/code> file in the root directory and store our supabase credentials:<\/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\">\/\/.env.local<\/span>\n<span class=\"hljs-keyword\">const<\/span> SUPABASE_KEY = <span class=\"hljs-string\">\"PUBLIC_ANON_KEY\"<\/span>\n<span class=\"hljs-keyword\">const<\/span> SUPABASE_URL = <span class=\"hljs-string\">\"PROJECT_URL\"<\/span>\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>Next, create a <code>utils<\/code> folder in the project\u2019s root directory and add a <code>Utils.js<\/code> file with the following snippets in it to configure our Supabase instance:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/utils\/Utils.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> supabaseUrl = process.env.SUPABASE_URL;\n<span class=\"hljs-keyword\">const<\/span> supabaseKey = process.env.SUPABASE_KEY;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> supabase = createClient(supabaseUrl, supabaseKey);\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<h2>User Registration<\/h2>\n<p>To handle the user registration logic, we\u2019ll add a <code>components<\/code> folder in the root directory ofo our project and create a <code>RegisterUser.js<\/code> file within. Update the file with this snippet:<\/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\">\/\/ src\/components\/RegisterUser<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Form, Button } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-bootstrap\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { supabase } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/Utils\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> initialState = {\n  <span class=\"hljs-attr\">firstName<\/span>: <span class=\"hljs-string\">\"\"<\/span>,\n  <span class=\"hljs-attr\">lastName<\/span>: <span class=\"hljs-string\">\"\"<\/span>,\n  <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-string\">\"\"<\/span>,\n  <span class=\"hljs-attr\">avatar<\/span>: <span class=\"hljs-literal\">null<\/span>\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">RegisterUser<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;formData, setFormData] = useState(initialState);\n  <span class=\"hljs-keyword\">const<\/span> &#91;loading, setLoading] = useState(<span class=\"hljs-literal\">true<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;status, setStatus] = useState(<span class=\"hljs-literal\">false<\/span>);\n\n  <span class=\"hljs-keyword\">const<\/span> handleChange = <span class=\"hljs-keyword\">async<\/span> (e) =&gt; {\n    e.preventDefault();\n    setFormData({ ...formData, &#91;e.target.name]: e.target.value });\n  };\n  \n  <span class=\"hljs-comment\">\/\/ handleImage() logic here<\/span>\n  \n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container-fluid\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"fs-1 m-3\"<\/span>&gt;<\/span> Register User<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n      {status &amp;&amp; (\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"mt-3 mb-3 text-success\"<\/span>&gt;<\/span>\n          User registered successfully!\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      )}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">width:<\/span> \"<span class=\"hljs-attr\">400px<\/span>\" }}&gt;<\/span>\n       \/\/render form here\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the snippet above, we:<\/p>\n<ul>\n<li>Import the packages we\u2019ll need to add the necessary logic and styling to our registration form.<\/li>\n<li>Initialized the <code>initialState<\/code> object and added some properties to it.<\/li>\n<li>Created <code>formData<\/code> state and passed <code>initialState<\/code> to it.<\/li>\n<li>Created the <code>loading<\/code> state to disable the Register button when uploading media assets to Cloudinary.<\/li>\n<li>Initialized a <code>status<\/code> state to conditionally render the status of the supabase user registration.<\/li>\n<li>Created the <code>handleChange<\/code> function to handle changes in our form input fields.<\/li>\n<\/ul>\n<p>Next, let\u2019s define a function to handle the image upload to Cloudinary:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ src\/components\/RegisterUser<\/span>\n<span class=\"hljs-comment\">\/\/ import statements here<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">RegisterUser<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-comment\">\/\/ state definitions here<\/span>\n  \n    <span class=\"hljs-keyword\">const<\/span> handleImage = <span class=\"hljs-keyword\">async<\/span> (e) =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n    reader.onloadend = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n      setLoading(<span class=\"hljs-literal\">true<\/span>);\n    };\n    <span class=\"hljs-keyword\">const<\/span> files = e.target.files&#91;<span class=\"hljs-number\">0<\/span>];\n    <span class=\"hljs-keyword\">if<\/span> (!files) <span class=\"hljs-keyword\">return<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">new<\/span> FormData();\n    data.append(<span class=\"hljs-string\">\"file\"<\/span>, files);\n    data.append(<span class=\"hljs-string\">\"upload_preset\"<\/span>, <span class=\"hljs-string\">\"c_tags\"<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> fetch(\n      <span class=\"hljs-string\">\"CLOUDINARY_UPLOAD_URL\"<\/span>,\n      {\n        <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n        <span class=\"hljs-attr\">body<\/span>: data\n      }\n    );\n    <span class=\"hljs-keyword\">const<\/span> file = <span class=\"hljs-keyword\">await<\/span> res.json();\n    setFormData({ ...formData, <span class=\"hljs-attr\">avatar<\/span>: file.secure_url });\n    setLoading(<span class=\"hljs-literal\">false<\/span>);\n  };\n  \n  <span class=\"hljs-keyword\">return<\/span> ();\n}\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here, we defined the <code>handleImage()<\/code> function to upload the selected image asset from the computer to Cloudinary. Then we used a callback to return the image URL to the client for rendering.<\/p>\n<p>Finally, let\u2019s define a  <code>createUser()<\/code> function that will get the user inputs from the form fields along with the image URL from Cloudinary and store them in our Supabase database.<\/p>\n<p>When this is successful, we\u2019ll set the <code>status<\/code> to be true if there are no errors, and also clear the form fields:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> createUser = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> supabase.from(<span class=\"hljs-string\">\"profiles\"<\/span>).insert(&#91;\n      {\n        <span class=\"hljs-attr\">first_name<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${formData.firstName}<\/span>`<\/span>,\n        <span class=\"hljs-attr\">last_name<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${formData.lastName}<\/span>`<\/span>,\n        <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${formData.email}<\/span>`<\/span>,\n        <span class=\"hljs-attr\">avatar<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${formData.avatar}<\/span>`<\/span>\n      }\n    ]);\n    <span class=\"hljs-keyword\">if<\/span> (res.error === <span class=\"hljs-literal\">null<\/span> &amp;&amp; res.status === <span class=\"hljs-number\">201<\/span>) {\n      setStatus(<span class=\"hljs-literal\">true<\/span>);\n      setFormData(initialState);\n      setTimeout(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        setStatus(<span class=\"hljs-literal\">false<\/span>);\n      }, <span class=\"hljs-number\">5000<\/span>);\n    }\n  };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The complete code snippets for the <code>RegisterUser.js<\/code> component is available in this Github gist if you\u2019d like to copy it from a single place:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/kenny-io\/b029df5525d4d331b8a079c9a1bb35df\">https:\/\/gist.github.com\/kenny-io\/b029df5525d4d331b8a079c9a1bb35df<\/a><\/p>\n<p>Next, let\u2019s import <code>RegisterUser.js<\/code> inside our <code>index.js<\/code> and render it like this:<\/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\">\/\/pages\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> RegisterUser <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/RegisterUser\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">IndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container-fluid\"<\/span> &gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">RegisterUser<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-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>Now in the browser, we can choose an image, fill out the form and click on the Register button to successfully register a user in our supabase project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_814E86809ACCE4EE468A338DE473A613D06174BFA2B11C190B5FC8807D09A9B8_1653033037766_user.gif\" alt=\"registering a user\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1018\" height=\"612\"\/><\/p>\n<h2>Retrieve users from Supabase<\/h2>\n<p>To get all the users we\u2019ve saved to our Supabase database, create a <code>getUsers.js<\/code> file in the components folder and update it with the following snippet:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ components\/GetUsers.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> React, { useState, useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Button, Card, ListGroup, ListGroupItem } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-bootstrap\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { supabase } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/Utils\"<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">GetUsers<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;users, setUsers] = useState();\n  <span class=\"hljs-keyword\">const<\/span> &#91;showUsers, setShowUsers] = useState(<span class=\"hljs-literal\">false<\/span>);\n\n  <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getUsers<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> supabase.from(<span class=\"hljs-string\">\"profiles\"<\/span>).select();\n    setUsers(res.data);\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Button<\/span>\n        <span class=\"hljs-attr\">variant<\/span>=<span class=\"hljs-string\">\"success\"<\/span>\n        <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n          getUsers();\n          setShowUsers(!showUsers);\n        }}\n      &gt;\n        {!showUsers ? \"Show registered users\" : \"Hide registered users\"}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Button<\/span>&gt;<\/span>\n      {showUsers &amp;&amp;\n        users &amp;&amp;\n        users.map((user) =&gt; (\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{user.id}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"mt-3 mb-3\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">width:<\/span> \"<span class=\"hljs-attr\">15rem<\/span>\" }}&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card.Img<\/span> <span class=\"hljs-attr\">variant<\/span>=<span class=\"hljs-string\">\"top\"<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{user.avatar}<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card.Body<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card.Title<\/span>&gt;<\/span>{user.first_name + \" \" + user.last_name}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Card.Title<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Card.Body<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ListGroup<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"list-group-flush\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ListGroupItem<\/span>&gt;<\/span> Email: {user.email}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ListGroupItem<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ListGroup<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Card<\/span>&gt;<\/span>\n        ))}\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> GetUsers;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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 snippets above, we:<\/p>\n<ul>\n<li>Import necessary packages from Bootstrap and Supabase.<\/li>\n<li>Define state variables for <code>users<\/code> and <code>showUsers<\/code> to conditionally show the users.<\/li>\n<li>Create the <code>getUsers<\/code> function to fetch the <code>users<\/code> in our Supabase project and update the users variable in state.<\/li>\n<li>Render a button that will show the registered <code>users<\/code>.<\/li>\n<li>Loop through the <code>users<\/code> data to display all users.<\/li>\n<\/ul>\n<p>Next, let\u2019s import the <code>GetUsers.js<\/code> component and render it inside <code>index.js<\/code>. When we click the show registered user button in the browser, we will see all the users registered in the supabase project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_814E86809ACCE4EE468A338DE473A613D06174BFA2B11C190B5FC8807D09A9B8_1653034146260_all-users.gif\" alt=\"shhow users\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1180\" height=\"634\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>In this post, we went over the process of storing user data to Supabase and serving images from Cloudinary when reading user data. This helps consolidate our data without restricting the functionalities that Cloudinary provides to help us manage assets. Feel free to fork the <a href=\"https:\/\/codesandbox.io\/s\/cloudinary-supabase-demo-wpqj5g\">CodeSandbox<\/a> here and extend the project as you see fit.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27996,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,212,371],"class_list":["post-27995","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-next-js","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Handling Data Storage with Cloudinary and Supabase<\/title>\n<meta name=\"description\" content=\"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let&#039;s take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.\" \/>\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\/handling-data-storage-with-cloudinary-and-supabase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Handling Data Storage with Cloudinary and Supabase\" \/>\n<meta property=\"og:description\" content=\"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let&#039;s take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-22T16:15:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-09T10:15:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1440\" \/>\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\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Handling Data Storage with Cloudinary and Supabase\",\"datePublished\":\"2022-05-22T16:15:10+00:00\",\"dateModified\":\"2023-07-09T10:15:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Next.js\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\",\"name\":\"Handling Data Storage with Cloudinary and Supabase\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA\",\"datePublished\":\"2022-05-22T16:15:10+00:00\",\"dateModified\":\"2023-07-09T10:15:08+00:00\",\"description\":\"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let's take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA\",\"width\":2560,\"height\":1440},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Handling Data Storage with Cloudinary and 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":"Handling Data Storage with Cloudinary and Supabase","description":"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let's take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.","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\/handling-data-storage-with-cloudinary-and-supabase\/","og_locale":"en_US","og_type":"article","og_title":"Handling Data Storage with Cloudinary and Supabase","og_description":"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let's take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-05-22T16:15:10+00:00","article_modified_time":"2023-07-09T10:15:08+00:00","og_image":[{"width":2560,"height":1440,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61-png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/"},"author":{"name":"","@id":""},"headline":"Handling Data Storage with Cloudinary and Supabase","datePublished":"2022-05-22T16:15:10+00:00","dateModified":"2023-07-09T10:15:08+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA","keywords":["Guest Post","Next.js","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/","name":"Handling Data Storage with Cloudinary and Supabase","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA","datePublished":"2022-05-22T16:15:10+00:00","dateModified":"2023-07-09T10:15:08+00:00","description":"Working with storage in client-side applications can be challenging. The choice of where and how are usually the first questions we are faced with. Let's take a look at a new approach that combines Cloudinary and Supabase to store and deliver user data in record time.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA","width":2560,"height":1440},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/handling-data-storage-with-cloudinary-and-supabase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Handling Data Storage with Cloudinary and 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\/v1681923997\/Web_Assets\/blog\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61\/5c86523e679a91962a3b47c02465e0db92ef30ac-2560x1440-1_279961fb61.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27995","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=27995"}],"version-history":[{"count":2,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27995\/revisions"}],"predecessor-version":[{"id":30278,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27995\/revisions\/30278"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27996"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27995"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}