{"id":28459,"date":"2022-07-20T08:42:38","date_gmt":"2022-07-20T08:42:38","guid":{"rendered":"http:\/\/automated-profile-avatar-creation-with-laravel"},"modified":"2025-02-23T13:17:50","modified_gmt":"2025-02-23T21:17:50","slug":"automated-profile-avatar-creation-with-laravel","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/","title":{"rendered":"Automated Profile Avatar Creation with Laravel"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><h2>Introduction<\/h2>\n<p>Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.<\/p>\n<h2>PHPSandbox and Github<\/h2>\n<p>With <a href=\"https:\/\/phpsandbox.io\/e\/x\/hxjvd?layout=EditorPreview&amp;defaultPath=%2F&amp;theme=dark&amp;showExplorer=no&amp;openedFiles=\">PHPSandbox<\/a> we will be able to run a live demo of this project. All the code will be available on my <a href=\"https:\/\/github.com\/musebe\/laravel-cloudinary-profile-image\">Github<\/a> repository for any references.<\/p>\n<h2>Prerequisites<\/h2>\n<p>To follow along, you need:<\/p>\n<ul>\n<li>Experience issuing commands through a terminal<\/li>\n<li>Version Control<\/li>\n<li>HTML\/CSS and JavaScript<\/li>\n<li>PHP specifically with the Laravel framework<\/li>\n<\/ul>\n<h2>Getting Started<\/h2>\n<p>Composer is the de facto package installer for most PHP projects. Follow the steps below keenly to install PHP and Composer.<\/p>\n<ol>\n<li>\n<p>Install <a href=\"https:\/\/getcomposer.org\/\">Composer<\/a> and <a href=\"https:\/\/www.php.net\/manual\/en\/install.php\">PHP<\/a> on\nyour machine. Be sure to follow the steps for your respective operating system.<\/p>\n<\/li>\n<li>\n<p>Laravel can be installed in two ways:<\/p>\n<ol>\n<li>\n<p>Via Composer:<\/p>\n<p><code>composer create-project --prefer-dist laravel\/laravel cloudinary-profile-image<\/code><\/p>\n<\/li>\n<li>\n<p>Via Laravel Installer (Recommended):<\/p>\n<p><code>composer global require laravel\/installer<\/code><\/p>\n<p><code>laravel new cloudinary-profile-image<\/code><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>If you follow either one of the steps above you should have a brand new Laravel application in the folder <code>cloudinary-profile-image<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>We need to run the server and test our application to ensure everything is okay. Fire it up by running the following commands:<\/p>\n<p><code>cd cloudinary-profile-image<\/code><\/p>\n<p><code>php artisan serve<\/code><\/p>\n<p>The Laravel server should be up and running and when you open <code>http:\/\/localhost:8000<\/code> on your browser, you should see the application default page shown in the image below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655887283\/watermark-api\/assets\/laravel-running_zqk8ol.png\" alt=\"Laravel Server Running\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1239\" height=\"638\"\/><\/p>\n<h2>Automated Profile Image\/Avatar<\/h2>\n<p>Cloudinary is a media management and manipulation platform which comes in handy in this scenario. We will use Cloudinary to automatically manipulate the profile image the users upload for consistent optimization and storage taking advantage of their global CDN for a faster performant application.<\/p>\n<p>We will start by, creating a <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Cloudinary account<\/a>, installing the <a href=\"https:\/\/github.com\/cloudinary-labs\/cloudinary-laravel#installation\">Cloudinary SDK<\/a> for Laravel and setting the Cloudinary credentials in our environmental file <code>.env<\/code>.<\/p>\n<ol>\n<li>\n<p>On your Cloudinary dashboard, get your Account details &#8211; the  Cloud Name, API Key, API Secret and the API Environment variable, we will need them later.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655976836\/assets\/cloudinary_dashboard.png\" alt=\"Cloudinary Dashboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"940\" height=\"441\"\/><\/p>\n<\/li>\n<li>\n<p>Install the Cloudinary SDK. Ensure you follow all the steps in the #Installation section from the Github repo of the SDK:<\/p>\n<p><code>composer require cloudinary-labs\/cloudinary-laravel<\/code><\/p>\n<\/li>\n<li>\n<p>Update your <code>.env<\/code> file with the Cloudinary credentials<\/p>\n<pre class=\"js-syntax-highlighted\"><code> \t\tCLOUDINARY_API_KEY=YOUR_CLOUDINARY_API_KEY\n \t\tCLOUDINARY_API_SECRET=YOUR_CLOUDINARY_API_SECRET\n \t\tCLOUDINARY_CLOUD_NAME=YOUR_CLOUDINARY_CLOUD_NAME\n \t\tCLOUDINARY_URL=YOUR_CLOUDINARY_ENVIRONMENT_VARIABLE\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<h2>User Interface<\/h2>\n<p>Our user interface will be a very simple implementation of a user profile with a form to set and submit the user image.<\/p>\n<p>We will use Bootstrap for our HTML\/CSS and Livewire for a little dynamic magic.<\/p>\n<ol>\n<li>\n<p>Install Laravel UI<\/p>\n<p><code>composer require laravel\/ui<\/code><\/p>\n<\/li>\n<li>\n<p>Install Bootstrap UI. This will install the necessary scaffolding for Laravel authentication.<\/p>\n<p><code>php artisan ui bootstrap<\/code>\n<code>php artisan ui bootstrap --auth<\/code><\/p>\n<\/li>\n<li>\n<p>Install the Livewire dependency:<\/p>\n<p><code>composer require livewire\/livewire<\/code><\/p>\n<\/li>\n<li>\n<p>Include Livewire scripts and styles on every page that will be using Livewire. In our case <code>app.blade.php<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">...\n    @livewireStyles\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n    ...\n  \n    @livewireScripts\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ol start=\"5\">\n<li>\n<p>We will then create a Livewire Component for our user profile:<\/p>\n<p><code>php artisan make:livewire UserProfile<\/code><\/p>\n<p>This creates two files, first <code>app\/Http\/Livewire\/UserProfile.php<\/code> and the other <code>resources\/views\/livewire\/user-profile.blade.php<\/code>.<\/p>\n<p>We can then use this component anywhere in our code using the following snippet:<\/p>\n<p><code>&lt;livewire:user-profile\/&gt;<\/code><\/p>\n<p>or<\/p>\n<p><code>@livewire('user-profile')<\/code><\/p>\n<\/li>\n<li>\n<p>Open <code>resources\/views\/layout\/app.blade.php<\/code> and add the following code within the <code>&lt;body&gt;&lt;\/body&gt;<\/code> tags as shown below:<\/p>\n<\/li>\n<\/ol>\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\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"antialiased\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t  ...\n\t  \n    @livewire('user-profile')\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/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\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This includes the Livewire component we created earlier in our <code>app.blade.php<\/code>.<\/p>\n<p><strong>Note:<\/strong> Please ensure you go through the <a href=\"https:\/\/laravel-livewire.com\/docs\/2.x\/quickstart\">Livewire documentation<\/a>, to learn more.<\/p>\n<ol start=\"3\">\n<li>Open the file <code>resources\/views\/livewire\/user-profile.blade.php<\/code> and populate it with the following code:<\/li>\n<\/ol>\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\">&lt;div <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span><\/span>=<span class=\"hljs-string\">\"flex h-screen justify-center items-center\"<\/span>&gt;\n\t<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"row w-100\"<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-12 p-6 text-center\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"w-100\"<\/span>&gt;<\/span>Welcome {{ $user-&gt;name }}!<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"mt-5 mb-3\"<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"img-fluid\"<\/span>\n\t\t\t\t     <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"{{ $user-&gt;profile_photo_path ?: 'https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/f_auto,q_auto,w_100,h_100,g_face,c_thumb\/v1657646841\/profile-image\/assets\/default_profile.png' }}\"<\/span>\n\t\t\t\t     <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"Profile Image\"<\/span>\/&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t@if(!$user-&gt;profile_photo_path)\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"mt-5 mb-5 flex align-items-center\"<\/span> <span class=\"hljs-attr\">wire:submit.prevent<\/span>=<span class=\"hljs-string\">\"setProfileImage\"<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"input-group ml-4\"<\/span>&gt;<\/span>\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"avatar\"<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control @error('avatar') is-invalid @enderror\"<\/span>\n\t\t\t\t\t       <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Choose profile photo...\"<\/span> <span class=\"hljs-attr\">wire:model<\/span>=<span class=\"hljs-string\">\"avatar\"<\/span>&gt;<\/span>\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-outline-primary\"<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span>&gt;<\/span>\n\t\t\t\t\t\tSet Profile Image\n\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"spinner-border spinner-border-sm ml-1 mt-1\"<\/span> <span class=\"hljs-attr\">wire:loading<\/span> <span class=\"hljs-attr\">wire:target<\/span>=<span class=\"hljs-string\">\"setProfileImage\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span>\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\t\t\t\t\t@error('avatar')\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"invalid-feedback\"<\/span>&gt;<\/span>{{ $message }}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t\t\t@enderror\n\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n\t\t\t@endif\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t<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<\/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>This will include a form that the user will use to update their profile image\/avatar when they log in. We are also getting user data from the DB to show user information like the name.<\/p>\n<p>The code also checks whether a profile image\/avatar exists in the DB, otherwise it displays a default profile image we had already uploaded to our Cloudinary media library.<\/p>\n<p>The code between the <code>@if() ...  @endif<\/code> statement displays the profile image upload form on condition the user does not have a profile image.<\/p>\n<h2>SQLite Database<\/h2>\n<p>We need to save our user data somewhere. We will use Laravel\u2019s SQLite integration which is suitable for small applications. We will make a few changes which will ensure we are able to connect.<\/p>\n<ol>\n<li>\n<p>Edit your <code>.env<\/code> file and change <code>DB_CONNECTION<\/code> to <code>sqlite<\/code><\/p>\n<\/li>\n<li>\n<p>Open your <code>config\/database.php<\/code> file and change the default to sqlite:<\/p>\n<p><code>'default' =&gt; env('DB_CONNECTION', 'sqlite'),<\/code><\/p>\n<\/li>\n<li>\n<p>In the connections array, change SQLite\u2019s database key-value pair as shown below and leave the rest as-is:<\/p>\n<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-string\">'connections'<\/span> =&gt; &#91;\n    <span class=\"hljs-string\">'sqlite'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'sqlite'<\/span>,\n        <span class=\"hljs-string\">'url'<\/span> =&gt; env(<span class=\"hljs-string\">'DATABASE_URL'<\/span>),\n        <span class=\"hljs-string\">'database'<\/span> =&gt; database_path(<span class=\"hljs-string\">'database.sqlite'<\/span>),\n        <span class=\"hljs-string\">'prefix'<\/span> =&gt; <span class=\"hljs-string\">''<\/span>,\n        <span class=\"hljs-string\">'foreign_key_constraints'<\/span> =&gt; env(<span class=\"hljs-string\">'DB_FOREIGN_KEYS'<\/span>, <span class=\"hljs-keyword\">true<\/span>),\n    ],  \n...\n];\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">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>Run the command <code>php artisan migrate:status<\/code> to test if you are connected, you should see the response <code>Migration table not found<\/code>.<\/p>\n<ol start=\"4\">\n<li>\n<p>We need to add a new column that will hold our profile images. Open the file <code>database\\migrations\\&lt;timestamp&gt;_create_users_table.php<\/code> and in the <code>up<\/code> function under <code>Schema:create<\/code> add the following code just before <code>timestamps<\/code>:<\/p>\n<p><code>$table-&gt;string('profile_photo_path', 2048)-&gt;nullable();<\/code><\/p>\n<p>Your implementations should be like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">...\n\n$table-&gt;string(<span class=\"hljs-string\">'profile_photo_path'<\/span>, <span class=\"hljs-number\">2048<\/span>)-&gt;nullable();\n$table-&gt;timestamps();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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>Once done run the command <code>php artisan migrate<\/code>, this will run migrations which will create the user\u2019s table among others.<\/p>\n<\/li>\n<\/ol>\n<h2>User Profile Component<\/h2>\n<p>The User Profile Component will contain all the logic to fetch user data from the DB on first render, upload the profile image\/avatar to Cloudinary and save the profile image URL we get back to the DB.<\/p>\n<p>Open the file <code>app\/Http\/Livewire\/UserProfile.php<\/code> and update it with the following code:<\/p>\n<ol>\n<li>\n<p>First, we use Livewire\u2019s <code>WithFileUploads<\/code> to help us with profile image uploads, then create the variables <code>$user<\/code> and <code>$avatar<\/code>. The user variable will contain user data which we will pass to the view and the avatar variable will contain the profile image URL we get back from Cloudinary.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">WithFileUploads<\/span>;  \n\n<span class=\"hljs-keyword\">public<\/span> $user;\n<span class=\"hljs-keyword\">public<\/span> $avatar;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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<\/li>\n<li>\n<p>Next, under the <code>mount()<\/code> function we will assign the currently logged-in user to the <code>$user<\/code> variable we created earlier.\n<code>$this-&gt;user = Auth::user();<\/code><\/p>\n<\/li>\n<li>\n<p>We will then create the <code>setProfileImage<\/code> function we will get the uploaded user profile image and upload it to Cloudinary with transformations to resize and optimize it for our application and with the <code>$user-&gt;id<\/code> as the <code>public_id<\/code>. This ensures that all images uploaded are unique, and we can dynamically recreate the profile image path in our view.<\/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-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">setProfileImage<\/span><span class=\"hljs-params\">()<\/span> <\/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\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<li>\n<p>Let\u2019s populate our method in step 2 above:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">setProfileImage<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n   <span class=\"hljs-keyword\">$this<\/span>-&gt;validate(&#91;\n     <span class=\"hljs-string\">'avatar'<\/span> =&gt; &#91;<span class=\"hljs-string\">'required'<\/span>, <span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-string\">'max:10240'<\/span>\n   ]);\n\n   $userAvatar = cloudinary()-&gt;upload(<span class=\"hljs-keyword\">$this<\/span>-&gt;avatar-&gt;getRealPath(), &#91;\n \t\t\t<span class=\"hljs-string\">'folder'<\/span>         =&gt; <span class=\"hljs-string\">'profile-image'<\/span>,\n \t\t\t<span class=\"hljs-string\">'public_id'<\/span>      =&gt; <span class=\"hljs-keyword\">$this<\/span>-&gt;user-&gt;id,\n \t\t\t<span class=\"hljs-string\">'format'<\/span>         =&gt; <span class=\"hljs-string\">'webp'<\/span>,\n \t\t\t<span class=\"hljs-string\">'transformation'<\/span> =&gt; &#91;\n \t\t\t\t<span class=\"hljs-string\">'format'<\/span>  =&gt; <span class=\"hljs-string\">'auto'<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'quality'<\/span> =&gt; <span class=\"hljs-string\">'auto'<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'crop'<\/span>    =&gt; <span class=\"hljs-string\">'thumb'<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'gravity'<\/span> =&gt; <span class=\"hljs-string\">'face'<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'radius'<\/span>  =&gt; <span class=\"hljs-string\">'max'<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'width'<\/span>   =&gt; <span class=\"hljs-number\">100<\/span>,\n \t\t\t\t<span class=\"hljs-string\">'height'<\/span>  =&gt; <span class=\"hljs-number\">100<\/span>,\n \t\t\t]\n   ])-&gt;getSecurePath();\n\n   <span class=\"hljs-keyword\">$this<\/span>-&gt;user-&gt;profile_photo_path = $userAvatar;\n   <span class=\"hljs-keyword\">$this<\/span>-&gt;user-&gt;save();\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\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<\/ol>\n<p>Let\u2019s talk about the code. The code validates the user uploaded profile and then sends an upload request to the Cloudinary upload API which returns a secure URL we assign to the variable <code>$userAvatar<\/code>.<\/p>\n<p>The transformations applied automatically format and manipulate the profile image for the best performance of our app. We also apply <code>gravity<\/code> to the face, round the image with <code>radius<\/code> and <code>crop<\/code> it to thumb mode which will give us a nice rounded image perfect for a profile image.<\/p>\n<p>The last steps of the code will update the <code>profile_photo_path<\/code> and save it to the database.<\/p>\n<p>With our code implementation complete, you should be able to see the following when you navigate to <code>http:\/\/localhost:8000<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_scale,w_940\/c_limit,w_2000\/f_auto\/q_auto\/v1657727044\/profile-image\/assets\/cloudinary_profile_image_bttk6x.png\" alt=\"Cloudinary Profile Image Demo\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"940\" height=\"464\"\/><\/p>\n<p>When you upload a profile image and hit the <em><strong>Set Profile Image<\/strong><\/em> button you should be able to see this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_scale,w_940\/c_limit,w_2000\/f_auto\/q_auto\/v1657727044\/profile-image\/assets\/cloudinary_profile_image_success_qyq5we.png\" alt=\"Cloudinary Profile Image Success\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"940\" height=\"464\"\/><\/p>\n<h2>What Next?<\/h2>\n<p>Congratulations are in order, we have automated the profile image\/avatar creation on our app. There is still much to be done, like adding an edit button or photo transformation effects to truly create unique profile photos that are consistent with your design language, but I will let you tinker with Laravel and Cloudinary.<\/p>\n<p>It\u2019s not too late to start with a <a href=\"https:\/\/cloudinary.com\/signup\">free<\/a> Cloudinary account.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28460,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,387,229,371],"class_list":["post-28459","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-laravel","tag-php","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>Automated Profile Avatar Creation with Laravel<\/title>\n<meta name=\"description\" content=\"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.\" \/>\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\/automated-profile-avatar-creation-with-laravel\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automated Profile Avatar Creation with Laravel\" \/>\n<meta property=\"og:description\" content=\"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-20T08:42:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-23T21:17:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"225\" \/>\n\t<meta property=\"og:image:height\" content=\"225\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\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\/automated-profile-avatar-creation-with-laravel\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Automated Profile Avatar Creation with Laravel\",\"datePublished\":\"2022-07-20T08:42:38+00:00\",\"dateModified\":\"2025-02-23T21:17:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Laravel\",\"PHP\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\",\"name\":\"Automated Profile Avatar Creation with Laravel\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA\",\"datePublished\":\"2022-07-20T08:42:38+00:00\",\"dateModified\":\"2025-02-23T21:17:50+00:00\",\"description\":\"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA\",\"width\":225,\"height\":225},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automated Profile Avatar Creation with Laravel\"}]},{\"@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":"Automated Profile Avatar Creation with Laravel","description":"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.","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\/automated-profile-avatar-creation-with-laravel\/","og_locale":"en_US","og_type":"article","og_title":"Automated Profile Avatar Creation with Laravel","og_description":"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-07-20T08:42:38+00:00","article_modified_time":"2025-02-23T21:17:50+00:00","og_image":[{"width":225,"height":225,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/"},"author":{"name":"","@id":""},"headline":"Automated Profile Avatar Creation with Laravel","datePublished":"2022-07-20T08:42:38+00:00","dateModified":"2025-02-23T21:17:50+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA","keywords":["Guest Post","Laravel","PHP","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/","name":"Automated Profile Avatar Creation with Laravel","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA","datePublished":"2022-07-20T08:42:38+00:00","dateModified":"2025-02-23T21:17:50+00:00","description":"Modern web and mobile applications allow users to upload images to be used for their profiles. Using Cloudinary we will upload, transform and optimize the image uploaded and return a profile image that is optimized and consistent throughout the web application.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA","width":225,"height":225},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automated-profile-avatar-creation-with-laravel\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Automated Profile Avatar Creation with Laravel"}]},{"@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\/v1681924258\/Web_Assets\/blog\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96\/12931906667f734bc421951c97a3dac875024532-225x225-1_284605cb96.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28459","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=28459"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28459\/revisions"}],"predecessor-version":[{"id":36974,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28459\/revisions\/36974"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28460"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}