Getting started

Integration & migration

Image & video API

DAM user guide

API overview

Account

Next.js

Real-time image & video resizing, automatic optimization, and file uploading in Next.js using ImageKit.io.


This quick start guide demonstrates how to integrate ImageKit into a Next.js application. For the scope of this integration, we will focus on the app routers in Next.js. Please refer to here for page router. The code samples provided are available on GitHub: https://github.com/imagekit-samples/quickstart/tree/master/next.

This guide covers the following topics:

Setup ImageKit Next.js SDK

For this tutorial, let's create a dummy Next.js app, as shown below.

Create a Next.js app:

Let's use the create-next-app CLI utility provided by Next.js to build a new project:

Copy
npx create-next-app@latest imagekit-next-app

We will be using the below configuration for the dummy app.

Copy
✔ Would you like to use TypeScript?  No
✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? No
✔ Would you like to use `src/` directory? No
✔ Would you like to use App Router? (recommended) Yes
✔ Would you like to customize the default import alias (@/*)? No

Navigate to the project directory:

Copy
cd imagekit-next-app/

Open up the project in your preferred text editor, and navigate to app/page.js. This is where we will focus our efforts. The file should look like this:

Copy
import Image from "next/image";
import styles from "./page.module.css";

export default function Home() {
  return (
    <main className={styles.main}>
      <div className={styles.description}>
        <p>
          Get started by editing&nbsp;
          <code className={styles.code}>app/page.js</code>
        </p>
        <div>
          <a
            href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            By <Image src="/vercel.svg" alt="Vercel Logo" className={styles.vercelLogo} width={100} height={24} priority />
          </a>
        </div>
      </div>
      <div className={styles.center}>
        <Image className={styles.logo} src="/next.svg" alt="Next.js Logo" width={180} height={37} priority />
      </div>
      ...
    </main>
  );
}

Now run the App:

Copy
npm run dev

In your web browser, navigate to http://localhost:3000/

You should now see the dummy app created by the Next.js CLI. We can begin our work from here. It should look like this.

Install the ImageKit Next.js SDK:

Installing the ImageKit Next.js SDK in our App is pretty simple:

Copy
npm install imagekitio-next

Initialize the Next.js SDK:

Before the SDK can be used, let's learn about and obtain the requisite initialization parameters:

  • urlEndpoint is a required parameter. This can be obtained from the URL-endpoint section or the developer section on your ImageKit dashboard.
  • publicKey and authenticator parameters are optional and only needed if you want to use the SDK for client-side file upload. publicKey can be obtained from the Developer section on your ImageKit dashboard.
  • authenticator expects an asynchronous function that resolves with an object containing the necessary security parameters i.e signature, token, and expire.

Now, let's create a .env.local file and add the following initialization parameters:

Copy
NEXT_PUBLIC_PUBLIC_KEY="<YOUR_IMAGEKIT_PUBLIC_KEY>"
NEXT_PUBLIC_URL_ENDPOINT="<YOUR_IMAGEKIT_URL_ENDPOINT>"
PRIVATE_KEY="<YOUR_IMAGEKIT_PRIVATE_KEY>"

Note: Do not include your API private key in any client-side code, including this SDK or its initialization. If you pass the privateKey parameter while initializing this SDK, it will throw an error.

ImageKit Components:

This SDK provides six components:

  • IKImage for image rendering. This utilizes next/image and renders an <img> tag.
  • IKVideo for video resizing. This renders a <video> tag.
  • IKUpload for file uploading. The output is a <input type="file"> tag.
  • ImageKitProvider is used to define options such as urlEndpoint, publicKey, or authenticator for all child components. It does not render any UI elements.
  • ImageKitClient exposes methods from ImageKit javascript SDK like url and upload.
  • ImageKitContext is a context used to provide access to options such as urlEndpoint, publicKey, ikClient or authenticator to child components within ImageKitProvider. It does not render any UI elements.

You can import components individually:

Copy
import { IKImage, IKVideo, ImageKitProvider, IKUpload, ImageKitContext } from "imagekitio-next";

Configure the App for ImageKit:

Let's remove the existing dummy code in the app/page.js file, then add the urlEndpoint:

Copy
"use client";
import React from "react";

const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;

export default function Home() {
  return <div className="App"></div>;
}

In the code above, we add "use client" at the top of the component to designate it as a Client Component.

Go to app/globals.css, remove the existing code, and replace it with the following code:

Copy
.App {
  padding: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.relative {
  position: relative;
}

.dimension {
  height: 200px;
  width: 200px;
}

.large-dimension {
  height: 300px;
  width: 300px;
}

Rendering images

The IKImage component acts as a wrapper around the Next.js Image component. This allows you to access all the built-in features of the Next.js Image component.

Before using external images, we need to add a configuration. This ensures that only external images from ik.imagekit.io can be served using Next.js Image Optimization.

Navigate to next.config.mjs and update it with the following code.

Copy
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "ik.imagekit.io",
        port: "",
      },
    ],
  },
};

export default nextConfig;

Loading image from relative path:

We will use an image that can be accessed at the following URL:

Copy
https://ik.imagekit.io/<YOUR_IMAGEKIT_ID>/default-image.jpg

Let's fetch and display it! For this, we will use the IKImage component.

Import IKImage from the SDK:

Copy
import { IKImage } from "imagekitio-next";

Now let's add it to our page.js. Along with the image path prop, it also needs the prop for urlEndpoint:

Copy
<IKImage urlEndpoint={urlEndpoint} path="default-image.jpg" width={400} height={400} alt="Alt text" />

Rendered HTML element:

Copy
<img alt="Alt text" loading="eager" width="400" height="400" decoding="async" data-nimg="1" src="https://ik.imagekit.io/your_imagekit_id/tr:h-400,w-400/default-image.jpg" style="color: transparent;">

The page.js file should look like this now:

Copy
"use client";
import React from "react";
import { IKImage } from "imagekitio-next";

const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;

export default function Home() {
  return (
    <div className="App">
      <h1>ImageKit Next.js quick start</h1>
      <IKImage urlEndpoint={urlEndpoint} path="default-image.jpg" width={400} height={400} alt="Alt text" />
    </div>
  );
}

This is how the output should look now:

Loading image from an absolute path:

If you have an absolute image path coming from the backend API e.g. https://www.custom-domain.com/default-image.jpg then you can use src prop to load the image.

For example:

Copy
<IKImage urlEndpoint={urlEndpoint} src="https://ik.imagekit.io/demo/default-image.jpg" width="400" height="400" alt="Alt text" />

The output looks like this:

Setting ImageKit context for the SDK

It is not necessary to specify the urlEndpoint in every instance of IKImage. This can be managed much more easily with the ImageKitProvider component.

ImageKitProvider is a wrapper that can be configured with your SDK initialization parameters. Pass your urlEndpoint to it as a prop, and you're good to go!

Let's go ahead and import it within the Page.js file:

Copy
import { ImageKitProvider, IKImage } from "imagekitio-next";

Now add the ImageKitProvider component to the function:

Copy
<ImageKitProvider urlEndpoint={urlEndpoint}></ImageKitProvider>

Let's nest our IKImage components within it so that those can access the urlEndpoint from the context wrapper.

Copy
"use client";
import React from "react";
import { IKImage, ImageKitProvider } from "imagekitio-next";

const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;

export default function Home() {
  return (
    <div className="App">
      <ImageKitProvider urlEndpoint={urlEndpoint}>
        <h1>ImageKit Next.js quick start</h1>
        <IKImage path="default-image.jpg" width={400} height={400} alt="Alt text" />
        <h2>Loading image from an absolute path</h2>
        <IKImage src="https://ik.imagekit.io/demo/default-image.jpg" width="400" height="400" alt="Alt text" />
      </ImageKitProvider>
    </div>
  );
}

Basic image manipulation

Let’s now learn how to manipulate images using transformations.

The Next.js SDK gives a name to each transformation parameter, e.g. height for h and width for the w parameter. It makes your code more readable. If the property does not match any of the available options, it is added as it is. See the full list of supported transformations in Next.js SDK on Github.

You can also use h and w parameters instead of height and width.

In addition to these, you can use all the options supported by next/image except for loading and src.

The height and width properties are ignored if they are included in the transformation parameter passed to IKImage, and fill={true} is applied.

In such cases, where the transformation contains height or width, a bounding element with appropriate dimensions should be provided, and its position should be set to one of absolute, fixed, or relative.

If height, width, or quality is specified only as a prop and not in the transformation, it is automatically applied in the transformation. Please refer to the example below.

Copy
<div style={{ position: "relative", width: "200", height: "200" }}>
  <IKImage path={path} transformation={[{ height: "200", width: "200" }]} alt="test-image" />
</div>

Height and width manipulation

‌To resize an image along with its height or width, we need to pass the transformation object as a prop to IKImage.

Let’s resize the default image to 200px height and width:

Copy
<h2>Height and width manipulation</h2>
<div className="relative dimension">
  <IKImage
    path="default-image.jpg"
    transformation={[
      {
        height: 200,
        width: 200,
      },
    ]}
    alt="Alt text"
  />
</div>

Rendered HTML element:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/your_imagekit_id/tr:h-200,w-200/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Refresh your browser to get the resized image.

Quality manipulation

You can use the quality parameter to change image quality like this:

Copy
<h2>Quality manipulation</h2>
<IKImage path="default-image.jpg" transformation={[{ quality: 10 }]} width="400" height="400" alt="Alt text" />

Rendered HTML:

Copy
<img alt="Alt text" loading="eager" width="400" height="400" decoding="async" data-nimg="1" src="https://ik.imagekit.io/your_imagekit_id/tr:q-10:h-400,w-400/default-image.jpg" style="color: transparent;">

Crop mode

Let’s now see how cropping works. We will try the extract crop strategy. In this strategy, instead of resizing the whole image, we extract out a region of the requested dimension from the original image.

Copy
<h2>Crop mode</h2>
<div className="relative dimension">
  <IKImage
    path="default-image.jpg"
    transformation={[
      {
        height: 300,
        width: 200,
        cropMode: "extract",
      },
    ]}
    alt="Alt text"
  />
</div>

Rendered HTML element:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-200,cm-extract/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Chained transformation

Chained transformations provide a simple way to control the sequence in which transformations are applied.

Let’s try it out by resizing an image and then rotating it:

Copy
<h3>Step 1: Resized and cropped</h3>
<div className="relative large-dimension">
  <IKImage
    path="default-image.jpg"
    transformation={[
      {
        height: 300,
        width: 200,
      },
    ]}
    alt="Alt text"
  />
</div>

Transformation URL:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-200/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Now, rotate the image by 90 degrees.

Copy
<h3>Step 2: Resized and cropped, then rotated</h3>
<div className="relative large-dimension">
  <IKImage
    path="default-image.jpg"
    transformation={[
      {
        height: 300,
        width: 200,
      },
      {
        rt: 90,
      },
    ]}
    alt="Alt text"
  />
</div>

Chained Transformation URL:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-200:rt-90/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Let’s flip the order of transformation and see what happens.

Copy
<h3>Step 3: Rotated, then resized and cropped</h3>
<div className="relative large-dimension">
  <IKImage
    path="default-image.jpg"
    transformation={[
      {
        rt: 90,
      },
      {
        height: 300,
        width: 200,
      },
    ]}
    alt="Alt text"
  />
</div>

Chained Transformation URL:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/your_imagekit_id/tr:rt-90:h-300,w-200/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Adding overlays

ImageKit.io enables you to apply overlays to images and videos using the raw parameter with the concept of layers. The raw parameter facilitates incorporating transformations directly in the URL. A layer is a distinct type of transformation that allows you to define an asset to serve as an overlay, along with its positioning and additional transformations.

Text as overlays

You can add any text string over a base video or image using a text layer (l-text).

For example:

Copy
<IKImage
  path="/default-image.jpg"
  transformation={[{ width: 400, height: 300 }, { raw: "l-text,i-Imagekit,fs-50,l-end" }]}
  alt="Alt text"
/>

Sample Result URL

Copy
https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-300,l-text,i-Imagekit,rt-90,co-0651D5,fs-50,l-end/default-image.jpg

Output Image:

Image as overlays

You can add an image over a base video or image using an image layer (l-image).

For example:

Copy
<IKImage
  path="/default-image.jpg"
  transformation={[{ width: 400, height: 300 }, { raw: "l-image,i-default-image.jpg,w-100,b-10_CDDC39,l-end" }]}
  alt="Alt text"
/>

Sample Result URL

Copy
https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-400,l-image,i-default-image.jpg,w-100,b-10_CDDC39,l-end/default-image.jpg

Output Image:

Solid color blocks as overlays

You can add solid color blocks over a base video or image using an image layer (l-image).

For example:

Copy
<IKVideo
  path="/img/sample-video.mp4"
  transformation={[{ width: 400, height: 300 }, { raw: "l-image,i-ik_canvas,bg-FF0000,w-300,h-100,l-end" }]}
  alt="Alt text"
/>

Sample Result URL

Copy
https://ik.imagekit.io/your_imagekit_id/tr:h-300,w-400,l-image,i-ik_canvas,bg-FF0000,w-300,h-100,l-end/img/sample-video.mp4

Output Image:

Lazy-loading images in Next.js

You can lazy load images using the loading prop in the IKImage component when you use loading="lazy", all images that are immediately viewable without scrolling load normally. Those that are far below the device viewport are only fetched when the user scrolls near them.

The SDK uses a fixed threshold based on the effective connection type to ensure that images are loaded early enough so that they have finished loading once the user scrolls near them.

You should always set the height and width of the image element to avoid layout shift when lazy-loading images.

Copy
<h2>Lazy loading images</h2>
<div className="relative large-dimension">
  <IKImage path="default-image.jpg" transformation={[{ height: 300, width: 400 }]} loading="lazy" alt="Alt text" />
</div>

Rendered HTML element:

Copy
<img alt="Alt text" loading="eager" decoding="async" data-nimg="fill" src="https://ik.imagekit.io/igi7ywjzdi/tr:h-300,w-400/default-image.jpg" style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;">

Blurred image placeholder

To improve user experience, you can use a low-quality blurred variant of the original image as a placeholder while the original image is being loaded in the background. Once the loading of the original image is finished, the placeholder is replaced with the original image.

Copy
// Loading a blurred low, quality image placeholder
// while the original image is being loaded
<h2>Blurred image placeholder</h2>
<IKImage path="default-image.jpg" lqip={{ active: true, quality: 20 }} width="400" height="400" alt="Alt text" />

Combining lazy loading with low-quality placeholders

You have the option to lazy-load the original image only when the user scrolls near them. Until then, only a low-quality placeholder is loaded. This saves a lot of network bandwidth if the user never scrolls further down.

Copy
// Loading a blurred low quality image placeholder
// and lazy-loading original when the user scrolls near them
<h3>Combining lazy loading with low-quality placeholders</h3>
<div className="relative large-dimension">
  <IKImage path="default-image.jpg" transformation={[{ height: 300, width: 400 }]} lqip={{ active: true }} loading="lazy" alt="Alt text" />
</div>

Uploading files in Next.js

Let's now learn how to upload an image to our media library.

Next.js SDK provides an IKUpload component, which renders an input type="file" tag that you can use to upload files to the ImageKit media library directly from the client side.

To implement this functionality, a backend server is needed to authenticate the request using your API private key.

Setup the backend app

For this quickstart guide, we will use Next.js Route Handlers, which will provide an authentication endpoint at http://localhost:3000/api/auth.

The backend SDK requires your API public key, private key, and URL endpoint. You can obtain them from Developer Options and URL endpoint pages, respectively.

Now, create the app/api/auth/route.js file and add the below code. Replace<YOUR_IMAGEKIT_PRIVATE_KEY> with the actual value:

Copy
import { NextResponse } from 'next/server';
import crypto from 'crypto';

const privateKey = process.env.PRIVATE_KEY;

export async function GET(request) {
  const { searchParams } = new URL(request.url);
  const token = searchParams.get('token') || crypto.randomUUID();
  const expire = searchParams.get('expire') || (Math.floor(Date.now() / 1000) + 2400).toString();
  const privateAPIKey = privateKey;
  const signature = crypto.createHmac('sha1', privateAPIKey).update(token + expire).digest('hex');

  return NextResponse.json({
    token,
    expire,
    signature
  });
}

Let's now create app/api/route.js and add below code:

Copy
import { NextResponse } from 'next/server';

export async function GET() {
  return new NextResponse(null, { status: 200 });
}

Let's run our App. If you GET http://localhost:3000/api/auth, you should see a JSON response like this. Actual values will vary.

Copy
{
    token: "5dd0e211-8d67-452e-9acd-954c0bd53a1f",
    expire: 1601047259,
    signature: "dcb8e72e2b6e98186ec56c62c9e62886f40eaa96"
}

Configure authentication in the frontend app

Now that we have our authentication server up and running let's configure the publicKey and authenticator in the frontend Next.js app:

Add the following to app/page.js file to initialize the SDK with auth params:

Copy
const publicKey = process.env.NEXT_PUBLIC_PUBLIC_KEY;
const authenticator = async () => {
  try {
    const response = await fetch("http://localhost:3000/api/auth");

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Request failed with status ${response.status}: ${errorText}`);
    }

    const data = await response.json();
    const { signature, expire, token } = data;
    return { signature, expire, token };
  } catch (error) {
    throw new Error(`Authentication request failed: ${error.message}`);
  }
};

Now, pass these values as props into a new ImageKitProvider instance, which will hold our upload component:

Copy
<ImageKitProvider publicKey={publicKey} urlEndpoint={urlEndpoint} authenticator={authenticator}>
  {/* ...child components */}
</ImageKitProvider>

This is how app/page.js should look now.

Copy
import React from "react";
import { ImageKitProvider, IKImage } from "imagekitio-next";

const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;
const publicKey = process.env.NEXT_PUBLIC_PUBLIC_KEY;
const authenticator = async () => {
  try {
    const response = await fetch("http://localhost:3000/api/auth");

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Request failed with status ${response.status}: ${errorText}`);
    }

    const data = await response.json();
    const { signature, expire, token } = data;
    return { signature, expire, token };
  } catch (error) {
    throw new Error(`Authentication request failed: ${error.message}`);
  }
};

export default function Home() {
  return (
    <div className="App">
      <ImageKitProvider urlEndpoint={urlEndpoint} publicKey={publicKey} authenticator={authenticator}>
        {/* ...client side upload component goes here */}
      </ImageKitProvider>
      {/* ...other SDK components added previously */}
    </div>
  );
}

Upload an image

For this, we will use the IKUpload component. Let's import it from the SDK into our Page.js file:

Copy
import { ImageKitProvider, IKImage, IKUpload } from "imagekitio-next";

Add the IKUpload component nested within ImageKitProvider, as well as a couple of event handlers for upload error and success, onError and onSuccess, respectively:

Copy
"use client";
import React from "react";
import { ImageKitProvider, IKImage, IKUpload } from "imagekitio-next";

const publicKey = process.env.NEXT_PUBLIC_PUBLIC_KEY;
const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;
const authenticator = async () => {
  try {
    const response = await fetch("http://localhost:3000/api/auth");

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Request failed with status ${response.status}: ${errorText}`);
    }

    const data = await response.json();
    const { signature, expire, token } = data;
    return { signature, expire, token };
  } catch (error) {
    throw new Error(`Authentication request failed: ${error.message}`);
  }
};

const onError = (err) => {
  console.log("Error", err);
};

const onSuccess = (res) => {
  console.log("Success", res);
};

export default function Home() {
  return (
    <div className="App">
      <h1>ImageKit Next.js quick start</h1>
      <ImageKitProvider publicKey={publicKey} urlEndpoint={urlEndpoint} authenticator={authenticator}>
        <div>
          <h2>File upload</h2>
          <IKUpload fileName="test-upload.png" onError={onError} onSuccess={onSuccess} />
        </div>
      </ImageKitProvider>
      {/* ...other SDK components added previously */}
    </div>
  );
}

This is how it looks in the UI:

Direct file uploading from the browser

Let’s now upload an image by selecting a file from the file input.

When you choose a file, the file is immediately uploaded. You can pass optional onSuccess and onError callback functions as props like we have.

You can verify that the file was successfully uploaded by checking the browser console. In case of success, it should print a success message like this:

The response object would look similar to this (values may vary):

Copy
{
    "fileId": "666a7d5037b244ef542865f6",
    "name": "test-upload_IFWJqiWpS.png",
    "size": 333148,
    "versionInfo": {
        "id": "666a7d5037b244ef542865f6",
        "name": "Version 1"
    },
    "filePath": "/test-upload_IFWJqiWpS.png",
    "url": "https://ik.imagekit.io/your_imagekit_id/test-upload_IFWJqiWpS.png",
    "fileType": "image",
    "height": 1882,
    "width": 1506,
    "thumbnailUrl": "https://ik.imagekit.io/your_imagekit_id/tr:n-ik_ml_thumbnail/test-upload_IFWJqiWpS.png",
    "AITags": null
}

After a successful upload, you should see the newly uploaded image in the Media Library section of your ImageKit dashboard.

If you don't see the image, check if there are any errors in the browser console log. Then verify whether the API private key has been configured correctly in the server app and if the server app is running.

Fetching uploaded file

Fetch the uploaded image and show it in UI using IKImage with the filePath returned in the upload response.

Copy
<IKImage path="/test-upload_IFWJqiWpS.png" width="200" height="200" alt="Alt text" />

The App should display your uploaded image correctly!

Advanced file upload

A more detailed example of how to use the file upload component (and an explanation of each advanced feature) is presented below:

Copy
"use client";
import React, { useRef } from "react";
import { ImageKitProvider, IKImage, IKUpload } from "imagekitio-next";

const publicKey = process.env.NEXT_PUBLIC_PUBLIC_KEY;
const urlEndpoint = process.env.NEXT_PUBLIC_URL_ENDPOINT;
const authenticator = async () => {
  try {
    const response = await fetch("http://localhost:3000/api/auth");

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Request failed with status ${response.status}: ${errorText}`);
    }

    const data = await response.json();
    const { signature, expire, token } = data;
    return { signature, expire, token };
  } catch (error) {
    throw new Error(`Authentication request failed: ${error.message}`);
  }
};

const onError = (err) => {
  console.log("Error", err);
};

const onSuccess = (res) => {
  console.log("Success", res);
};

const onUploadProgress = (progress) => {
  console.log("Progress", progress);
};

const onUploadStart = (evt) => {
  console.log("Start", evt);
};

export default function Home() {
  const ikUploadRefTest = useRef(null);
  return (
    <div className="App">
      <h1>ImageKit Next.js quick start</h1>
      <ImageKitProvider publicKey={publicKey} urlEndpoint={urlEndpoint} authenticator={authenticator}>
        <p>Upload an image with advanced options</p>
        <IKUpload
          fileName="test-upload.jpg"
          tags={["sample-tag1", "sample-tag2"]}
          customCoordinates={"10,10,10,10"}
          isPrivateFile={false}
          useUniqueFileName={true}
          responseFields={["tags"]}
          validateFile={(file) => file.size < 2000000}
          folder={"/sample-folder"}
          {/* extensions={[
            {
              name: "remove-bg",
              options: {
                add_shadow: true,
              },
            },
          ]} */}
          webhookUrl="https://www.example.com/imagekit-webhook" // replace with your webhookUrl
          overwriteFile={true}
          overwriteAITags={true}
          overwriteTags={true}
          overwriteCustomMetadata={true}
          {/* customMetadata={{
            "brand": "Nike",
            "color": "red",
          }} */}
          onError={onError}
          onSuccess={onSuccess}
          onUploadProgress={onUploadProgress}
          onUploadStart={onUploadStart}
          transformation={{
            pre: "l-text,i-Imagekit,fs-50,l-end",
            post: [
              {
                type: "transformation",
                value: "w-100",
              },
            ],
          }}
          style={{display: 'none'}} // hide the default input and use the custom upload button
          ref={ikUploadRefTest}
        />
        <p>Custom Upload Button</p>
        {ikUploadRefTest && <button onClick={() => ikUploadRefTest.current.click()}>Upload</button>}
        <p>Abort upload request</p>
        {ikUploadRefTest && <button onClick={() => ikUploadRefTest.current.abort()}>Abort request</button>}
      </ImageKitProvider>
      {/* ...other SDK components added previously */}
    </div>
  );
}

Custom Upload Button

We have created a ref to the input used inside the IKUpload component called ikUploadRefTest. The IKUpload component can be given styling via className or style (style={{display: 'none'}}) to hide the default file selector. Then, we can use the custom upload button as described above.

Abort uploads

We have created a ref to the IKUpload component called ikUploadRefTest. This ref can be used to call the abort method in the IKUpload component and can be used to abort the ongoing upload.

Upload start

The onUploadStart prop is called when the file upload starts. This can be used for common use cases like showing a spinner, progress bar, etc.

Show progress bar

The onUploadProgress prop can be passed like above, which will have a ProgressEvent. This can be used to show the percentage of upload progress to the end user.

Validate file before upload

Arbitrary validation (file type, file size, file name) and any other properties of File can be added using the validateFile prop. An example has been added above that shows how to prevent upload if the file size is bigger than 2 MB.

Additional options to the upload function

All the parameters supported by the ImageKit Upload API can be passed as shown above (e.g. extensions, webhookUrl, customMetadata, etc.)

Rendering videos

Rendering videos works similarly to rendering images in terms of usage of the urlEndpoint param (either directly or via ImageKitProvider).

Loading video from relative path: Import IKVideo from the SDK:

Copy
import { IKVideo } from "imagekitio-next";

Now, let's add it to our App. Along with the video path prop, it also needs the relevant urlEndpoint (either directly or via ImageKitProvider):

Copy
<ImageKitProvider urlEndpoint={process.env.NEXT_PUBLIC_URL_ENDPOINT}>
  <IKVideo
    path={videoPath}
    transformation={[{ height: 200, width: 200 }]}
    controls={true}
  />
</ImageKitProvider>

Here is how it appears in the UI:

A more complex example:

Copy
<ImageKitProvider urlEndpoint={process.env.NEXT_PUBLIC_URL_ENDPOINT}>
  <IKVideo
    path={videoPath}
    transformation={[{ height: 200, width: 600, b: '5_red', q: 95 }]}
    controls={true}
  />
</ImageKitProvider>

This is how it looks in the UI: