Construct a personalised Picture Editor with Cloudinary + Auth0




Picture modifying is the artwork of altering digital images, conventional photo-chemical images, or illustrations to make them look extra like what you noticed together with your eyes. The fixed demand for picture modifying has introduced in regards to the invention of recent software program, jobs, and specialised personnel to assist enhance the standard of pictures.

On this publish, we’ll focus on the best way to construct a personalised picture editor utilizing Cloudinary, Auth0, and Next.js. We are able to consider this as a lighter model photoshop or afinity photo. On the finish of this tutorial, we might have learnt the best way to add picture modifying performance utilizing Cloudinary Media Editor and safe the web utility utilizing Auth0.

By the use of introduction, Cloudinary is a platform on which you’ll shortly and simply add, retailer, handle, remodel, and ship pictures and movies for web sites and apps. The platform additionally provides an unlimited assortment of SDKs for frontend frameworks and libraries.

Auth0 is a platform that gives techniques to quickly combine authentication and authorization for web, cellular, and legacy functions.

Subsequent.js is a React-based front-end development framework that permits functionalities like server-side rendering, static website era, file-system routing (without having to manually configure react-router-dom), and API endpoints for backend options.



Supply code

You’ll find the supply code of this challenge here.

The subsequent steps on this publish require JavaScript and React.js expertise. Expertise with Subsequent.js isn’t a requirement, nevertheless it’s good to have.

We additionally want the next:



Getting Began

We have to create a Subsequent.js starter challenge by navigating to the specified listing and operating the command under in our terminal

npx create-next-app media_editor && cd media_editor
Enter fullscreen mode

Exit fullscreen mode

This command creates a Subsequent.js challenge known as media_editor and navigates into the challenge listing.

We proceed to put in the required dependencies with:

npm set up react-helmet @auth0/nextjs-auth0
Enter fullscreen mode

Exit fullscreen mode

react-helmet is a library that takes plain HTML tags and outputs plain HTML tags. It’ll assist us keep away from the Reference error: Window just isn't Outlined error when utilizing client-side solely packages in Subsequent.js.

@auth0/nextjs-auth0 is a library for implementing person authentication in Subsequent.js functions.

Cloudinary supplies an interactive person interface offering a set of on a regular basis picture modifying actions that we are able to use on our web site or utility. The editor helps us scale inside operations by decreasing dependency on designers by permitting us to manually evaluation/repair media belongings when wanted. So as to add a media editor to our utility, we have to comply with these steps:

  • Add picture to Cloudinary utilizing Cloudinary Add Widget.
  • Cross the returned uploaded picture publicId to Cloudinary Media Editor.
  • Specify picture modifying steps:
    • resizeAndCrop to resize and crop pictures
    • textOverlays add textual content overlay on pictures
    • export to obtain edited pictures



Integrating Cloudinary

With the challenge dependencies put in, we are able to leverage Subsequent.js CSS Module assist to type our web page by changing the content material in Residence.module.css within the kinds folder with the gist under:

Residence.module.css

With that finished, we are able to replace the index.js file within the pages folder by importing the kinds created, configure Cloudinary Add Widget and Cloudinary Media Editor to add information to Cloudinary and edit uploaded pictures, respectively. We additionally embody states to deal with returned picture publicId and modifying state.

    import kinds from '../kinds/Residence.module.css';
    import { Helmet } from 'react-helmet';
    import { useState } from 'react';

    export default operate Residence() {
      const [id, setId] = useState(null);
      const [editing, setEditing] = useState(false);
      const openUpload = () => {
        window.cloudinary
          .createUploadWidget(
            {
              cloudName: 'dtgbzmpca',
              uploadPreset: 'tca2j0ee',
            },
            (error, consequence) => {
              if (!error && consequence && consequence.occasion === 'success') {
                setId(consequence.information.public_id);
                setEditing(true);
              }
            }
          )
          .open();
      };
      const openEditor = () => {
        const myEditor = cloudinary.mediaEditor();
        myEditor.replace({
          publicIds: [id],
          cloudName: 'dtgbzmpca',
          picture: {
            steps: ['resizeAndCrop', 'textOverlays', 'export'],
          },
        });
        myEditor.present();
        myEditor.on('export', operate (knowledge) {
          console.log(knowledge);
          setEditing(false);
        });
      };
      return (
        <div>
          <Helmet>
            <script src='https://media-editor.cloudinary.com/all.js' />
            <script src='https://upload-widget.cloudinary.com/international/all.js' />
          </Helmet>
          <primary className={kinds.information}>
            {/* remaining JSX comes right here */}
          </primary>
        </div>
      );
    }
Enter fullscreen mode

Exit fullscreen mode

The Cloudinary Add Widget and Cloudinary Media Widget additionally configures cloudName, uploadPreset, and publicIds , cloudName, picture, respectively. Lastly, we used react-helmet so as to add Cloudinary Add Widget and Cloudinary Media Widget CDNs to the appliance.

To create a brand new add preset, click on on the Settings Icon, choose the Add tab, navigate to the Add presets part, click on on the Add Add preset.

select preset

copy preset name, change to Unsigned and save

Discover out extra about Cloudinary Add Widget here and Cloudinary Media Widget here.

Subsequent, we have to embody our markup to add and edit picture.

    //imports right here

    export default operate Residence() {
      //states right here

      const openUpload = () => {
        //add widget code
      };

      const openEditor = () => {
        //media widget code
      };

      return (
        <div>
          <Helmet>
            <script src='https://media-editor.cloudinary.com/all.js' />
            <script src='https://upload-widget.cloudinary.com/international/all.js' />
          </Helmet>
          <primary className={kinds.information}>
            <header className={kinds.header}>
              <a className={kinds.logout}>
                Log Out
              </a>
            </header>
            <p className={kinds.title}>Hello {person.title}</p>
            <div className={kinds.container}>
              <div className={kinds.buttonwrapper}>
                {!modifying && (
                  <button className={kinds.button} onClick={() => openUpload()}>
                    Add Picture
                  </button>
                )}
                {modifying && (
                  <>
                    <p>Picture uploaded efficiently!</p>
                    <button className={kinds.button} onClick={() => openEditor()}>
                      Open Editor
                    </button>
                  </>
                )}
              </div>
            </div>
          </primary>
        </div>
      );
    }
Enter fullscreen mode

Exit fullscreen mode

Lastly, we are able to begin a development server and check our utility:

npm run dev
Enter fullscreen mode

Exit fullscreen mode

Upload Image
Select image to upload
Start editing image

Editing uploaded image



Setup a Developer Account

To get began, we have to log into our Auth0 dashboard. Click on on Functions

Auth0 Dashboard

Within the utility web page, click on on the Create Software button, enter utility title auth0Cloudinary in our case, choose Common Web Software as the appliance sort and Create

Creating a new app

Click on on the Settings tab and replica the Area, Shopper ID, and Shopper Secret.

copy credentials

Then scroll all the way down to the Functions URIs part and fill within the particulars under for Allowed Callback URLs and Allowed Logout URLs, respectively.

  • Allowed Callback URLs
    • http://localhost:3000/api/auth/callback
  • Allowed Logout URLs
    • http://localhost:3000/
      URIs

Then scroll all the way down to the underside of the web page and click on on the Save Adjustments button*.*



Integrating Auth0 with Subsequent.js

To combine Auth0 in our utility, we have to create an .env.native file in our root listing and fill within the required parameters(Area, Shopper ID and Shopper Secret) as proven under:

AUTH0_SECRET='LONG_RANDOM_VALUE'
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0.com'
AUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID'
AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET'
Enter fullscreen mode

Exit fullscreen mode

We are able to run the snippet under on our terminal to generate a random secret for the AUTH0_SECRET

node -e "console.log(crypto.randomBytes(32).toString('hex'))"
Enter fullscreen mode

Exit fullscreen mode

Subsequent, we have to create a dynamic route file for our APIs. We have to navigate to the pages folder, inside this folder, navigate to the api folder, within the folder, create an auth folder, and inside this folder, create an […auth0].js file and add the snippet under:

    import { handleAuth } from '@auth0/nextjs-auth0';
    export default handleAuth();
Enter fullscreen mode

Exit fullscreen mode

The handleAuth() operate will generate APIs for:

  • Login
  • Logout
  • Fetch person knowledge
  • Redirect person on profitable login.

Subsequent, we have to replace _app.js file contained in the pages folder as proven under:

    import { UserProvider } from '@auth0/nextjs-auth0';
    export default operate App({ Element, pageProps }) {
      return (
        <UserProvider>
          <Element {...pageProps} />
        </UserProvider>
      );
    }
Enter fullscreen mode

Exit fullscreen mode

Lastly, we have to replace index.js as proven under

    //different imports right here
    import { withPageAuthRequired } from '@auth0/nextjs-auth0';

    export default operate Residence({ person }) { //replace this with destructure props
      //state goes right here

      //features goes right here

      return (
        <div>
          <Helmet>
            <script src='https://upload-widget.cloudinary.com/international/all.js' />
          </Helmet>
          <primary className={kinds.information}>
            <header className={kinds.header}>
              <a href='/api/auth/logout' className={kinds.logout}> {/* add href to this*/}
                Log Out
              </a>
            </header>
            <p className={kinds.title}>Hello {person.title}</p> {/*add this*/}
            {/*remaining code snippet goes right here*/}
          </primary>
        </div>
      );
    }
    export const getServerSideProps = withPageAuthRequired({
      returnTo: '/',
    });
Enter fullscreen mode

Exit fullscreen mode

Within the snippet above, we imported withPageAuthRequired and in addition modified the sign off hyperlink. We used Subsequent.js inbuilt technique getServerSideProps to name the withPageAuthRequired technique, specified the URL to redirect to after login, accessed the person props it returned after which displayed the person’s title.

Full index.js

This publish mentioned the best way to construct and safe an utility that helps importing, modifying, and downloading pictures.

It’s possible you’ll discover these assets helpful:

Content material created for the Hackmamba Jamstack Content material Hackathon.



Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.


Checkout extra Articles on Sayed.CYou

#Construct #personalised #Picture #Editor #Cloudinary #Auth0