Correct configuration of cloudinary library for Next.js server side code

nk9
nk9 Member Posts: 11
edited September 2023 in Developer APIs

I'm using Next.js. I call various cloudinary API methods in several different places, but always in either API or server side methods like getStaticProps. I want to avoid having to configure the library again and again, so I've followed the Next.js example which puts initialization and config in a separate file which you then import from in each place you need it.

So now I'm doing this when I want to use it:

import cloudinary from '/src/cloudinary'

function getStaticProps() {
   let folders = await cloudinary.v2.api.sub_folders(/* etc */)
}

However, I'm getting the Must supply api_key error when I do this. And indeed, when I echo process.env.CLOUDINARY_API_KEY at the point that the config() call happens it's undefined. This despite it definitely being defined in my `.env.local`. I think this is because the import is being resolved on the client side. (The error is in BOTH the client's console and the server spew.) Of course, the client doesn't have access to the server-side environment variables.

So what is the recommended way to init in a reusable way with cloudinary.config() when using API methods (search, api.sub_folders, etc) in Next.js server-side functions?

My other question is: is there a way to avoid having to put .v2 in front of every call? I was using the import {v2 as cloudinary} from 'cloudinary' import style before, which was a bit nicer. But using this separate file the way it's done there, I don't see an obvious way to import just the v2 functions.

Comments

  • nk9
    nk9 Member Posts: 11

    I have figured out the main problem, and it's pretty silly: the code I pasted in from the Next example used CLOUDINARY_API_KEY but my .env.local was declaring CLOUDINARY_KEY. So of course the environment variable was undefined!

    I am going to leave this open, though, because someone else might wonder how to configure Cloudinary in a separate file like I did. And also: is there some way I can avoid the .v2 part of the call?

  • Wissam
    Wissam Member, Cloudinary Staff Posts: 103

    Hi there,

    Thank you for your feedback.

    Indeed you will need to use the right variable.

    • To avoid having to put .v2 in front of every call, you can use the cloudinary-core package instead of the cloudinary package. This package does not have the versioning in the module name. For example:
    // cloudinary.js
    require('next-env')(); // load environment variables
    const cloudinary = require('cloudinary-core');
    

    Hope it helps.

    Regards,

    Wissam

  • nk9
    nk9 Member Posts: 11

    Hi, thanks for the reply Wissam. I tried this, but it didn't work:

    import cloudinary from 'cloudinary-core'
    
    cloudinary.config({
      cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
      api_key: process.env.CLOUDINARY_KEY,
      api_secret: process.env.CLOUDINARY_SECRET,
      secure: true,
    })
    
    export default cloudinary
    

    The error was:

    Error [TypeError]: cloudinary_core__WEBPACK_IMPORTED_MODULE_0___default(...).config is not a function
    

    Anyway, then I re-read the Node SDK documentation about importing the cloudinary library, and came up with this, which does work:

    import cloudinaryLib from 'cloudinary'
    
    const cloudinary = cloudinaryLib.v2
    
    cloudinary.config({
      cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
      api_key: process.env.CLOUDINARY_KEY,
      api_secret: process.env.CLOUDINARY_SECRET,
      secure: true,
    })
    
    export default cloudinary
    
  • Wissam
    Wissam Member, Cloudinary Staff Posts: 103

    Hi, That's good news.

    Thank you for sharing your input.

    Regards,

    Wissam