<![CDATA[ImageKit.io Blog]]>https://imagekit.io/blog/https://imagekit.io/blog/favicon.pngImageKit.io Bloghttps://imagekit.io/blog/Ghost 4.48Mon, 12 May 2025 11:12:40 GMT60<![CDATA[Adding video player in React Native]]>https://imagekit.io/blog/react-native-video-player/67c59b1147ef7900014b86afTue, 08 Apr 2025 07:21:20 GMT

Introduction

Adding video player in React Native

This blog post will guide you through adding a video player to your React Native app. We will cover basics of React Native, how to build an Android app, and how to integrate a video player. Additionally, we will explore the benefits of Adaptive Bitrate Streaming (ABS) protocols such as HLS and DASH.

What you will learn

What is React Native?

React Native lets you create native apps for Android, iOS, and more using React.

Adding video player in React Native

Why developers choose React Native?

  • Cross-Platform Speed: Write code once in JavaScript/React, ship to Android and iOS with minimal tweaks.
  • Native-Like Performance: Renders via actual native components, so apps feel fast and responsive.
  • Vibrant Ecosystem: Backed by Meta, widely adopted by major companies (e.g., Instagram), and bolstered by an active open-source community.
  • Easy to Learn: If you know React for web, transitioning to mobile is straightforward.
  • Future-Proof: Regular updates, flexible native module support, and proven large-scale production apps make it a stable, long-term solution.

Now let’s learn how to create video experiences in a React Native app.

Creating a React Native App

Prerequisite

In this blog, we will create an Android app that plays videos with custom controls. To follow along with the line-by-line coding, you need to set up a React Native environment.

Depending on your operating system, you can follow the instructions provided here for Android development.

This would install the following if they aren’t already present:

  • Node: For this tutorial, a stable Node version of 18.20.6 or above is needed.

  • Watchman: Version as mentioned.

  • Java Development Kit (JDK): Version as mentioned.

  • Android Studio: Version as mentioned.

Running Android Emulator

  1. Create a new project named SampleVideoPlayer with No Activity or Empty Activity.
Adding video player in React Native

2.  Click on the Device Manager located inside the Tools window.

Adding video player in React Native

3.  The device manager dialog box opens on the right side of Android Studio. Click on Create virtual device to create a new virtual device.

Adding video player in React Native

Once the virtual device is created, verify it in the terminal by the following command:

adb devices

It would list a device you created.

Adding video player in React Native

Running React Native App

To create a project, run the following command in the terminal of a text editor of your choice.

It will install a specific version of React Native that is compatible with the Node version mentioned above.

npx @react-native-community/cli@15.0.1 init sampleVideoPlayer --version 0.77.0

Choose yes to install @react-native-community/cli at a specific version.

When prompted to install CocoaPods, select No. This is required for Xcode in iOS development, but this blog focuses on Android development.

Navigate to the project directory.

cd sampleVideoPlayer/

We will find the boilerplate code below:

Adding video player in React Native

Start the Metro server by running the command in the terminal.

npm run start

To run the app on the Android simulator, run the below command in another terminal.

npm run android

After successfully running the command, the React Native App will be seen on the Android virtual device.

Adding video player in React Native
💡
If you encounter the following error Error: SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
Create a file local.properties file under the android directory in the text editor and add your Android SDK path as explained here.

Change the code in App.tsx with the basic Hello World code. The app will update itself by hot reloading.

import React from 'react';
import { SafeAreaView, Text, StyleSheet } from 'react-native';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.text}>Our First React Native App</Text>
      <Text style={styles.text}>Hello World</Text>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 20,
  },
});

export default App;
Adding video player in React Native

Picking the right video player library for React Native

Before implementing the video player, we must choose the correct library tailored to our use case. There are many video libraries, but we will use react-native-video-player, a wrapper with better Controls UI over a hugely popular video library react-native-video. The same group maintains both libraries.

Since react-native-video-player is built on top of react-native-video, it accepts all properties and methods of the react-native-video library. It also emits all the react-native-video events, along with some additional properties as mentioned here.

  1. Better Controls UI
    The react-native-video-player has a better UI for controls than react-native-video and exposes basic properties like mute, loop, and autoplay in a straightforward manner.

  2. Open-source and feature-rich
    The react-native-video-player is an open-source library built on react-native-video. It enhances the video playback functionality in React Native and offers a streamlined and user-friendly API for incorporating video playback into iOS and Android apps. This library supports various video formats and includes features like playback control, track selection, volume adjustment, and fullscreen viewing options.

  3. Advanced Features
    All advanced features from react-native-video, such as subtitle support, DRM support, and Picture-in-Picture,are naturally extend to react-native-video-player.

  4. ABS Support
    The library supports Adaptive Bitrate Streaming(ABS) out-of-box, making implementation straightforward and hassle-free.

Integrating video player

First, we need to install both the video player and its type declarations.

npm install --save react-native-video-player react-native-video
npm install --save-dev @types/react-native-video-player

Replace the code in App.tsx with the following code to initialize the video player.

import React, { useState } from 'react';
import { SafeAreaView, StyleSheet, TouchableOpacity } from 'react-native';
import VideoPlayer, { type VideoPlayerRef } from 'react-native-video-player';

const App = () => {
  // State to store video duration
  const [duration, setDuration] = useState(0);

  // Reference to the VideoPlayer component
  const videoRef = React.useRef<VideoPlayerRef>(null);
  
  // Reference to track current playback time
  const progressRef = React.useRef<number>(0);

  return (
    // Safe area container for proper layout on devices
    <SafeAreaView style={styles.container}>
      
      {/* VideoPlayer component with source and event handlers */}
      <VideoPlayer
        ref={videoRef} // Reference to access VideoPlayer methods
        source={{ uri: 'https://ik.imagekit.io/ikmedia/example_video.mp4' }} // Video URL
        onError={(error) => console.error('Video Error:', error)} // Handle playback errors
        onLoad={(data) => {
          console.log('Video Loaded:', data); // Log load data
          setDuration(data?.duration); // Set video duration state
        }}
        onBuffer={(data) => console.log('Buffering:', data)} // Log buffering status
        onProgress={(data) => {
          console.log('Video Progress:', data); // Log progress data
          progressRef.current = data.currentTime; // Update current playback time
        }}
      >
      </VideoPlayer>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'yellow', // Set background color to yellow
  },
});

export default App;
Adding video player in React Native
The app gets updated with the video player
💡
If you run into some sort of RCTVideo error, re-build the app by running npm run android.

Resizing video

The video player exposes three different properties to control the resizing of the video.

  • resizeMode - It can take four different values: none, cover, stretch, and contain, as explained here.

  • videoHeight - Used along with videoWidth to calculate the new aspect ratio.

  • videoWidth - Used along with videoHeight to calculate the new aspect ratio.

The original video has an aspect ratio of 16:9 and dimensions 3840 * 2160; resizing it to 200 * 200 results in an aspect ratio of 1:1 with the below results with different resize modes.

Adding video player in React Native
Contain
Adding video player in React Native
Stretch
Adding video player in React Native
Cover

However, this resizing is just for display purposes, and the video player still needs to download the original large video despite reducing its dimensions, which wastes bandwidth. Later, we will see how to use Imagekit to reduce the video size significantly by server-side encoding.

To resize it into cover mode. Add the following code in App.tsx.

.....
import { ResizeMode } from 'react-native-video'; // import ResizeMode enum
.....

<VideoPlayer
        ref={videoRef} // Reference to access VideoPlayer methods
        source={{ uri: 'https://ik.imagekit.io/ikmedia/example_video.mp4' }} // Video URL
        resizeMode={ResizeMode.COVER} // Video resize mode
        videoHeight={200} // Video height
        videoWidth={200} // Video width
        onError={(error) => console.error('Video Error:', error)} // Handle playback errors
        onLoad={(data) => {
          console.log('Video Loaded:', data); // Log load data
          setDuration(data?.duration); // Set video duration state
        }}
        onBuffer={(data) => console.log('Buffering:', data)} // Log buffering status
        onProgress={(data) => {
          console.log('Video Progress:', data); // Log progress data
          progressRef.current = data.currentTime; // Update current playback time
        }}
      >
      </VideoPlayer>
...

Custom Controls

To show the duration currently being played, set the property showDuration to true.

There is no such flag indicating fast-forward or rewind options. Therefore, we will implement these features using the event handlers from react-native-video and react-native-video-player.

First, we need to install react-native-vector-icons to use the required icons.

npm i --save react-native-vector-icons
npm i --save-dev @types/react-native-vector-icons
💡
To use the icon library, you need to edit android/app/build.gradle file and add apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
After this, rebuild the app by running npm run android.

Update the code in App.tsx as below:

import React, { useState } from 'react';
import { SafeAreaView, StyleSheet, TouchableOpacity } from 'react-native';
import { ResizeMode } from 'react-native-video'; // import ResizeMode enum
import VideoPlayer, { type VideoPlayerRef } from 'react-native-video-player';
import AntDesign from 'react-native-vector-icons/AntDesign';

const App = () => {
  // State to store video duration
  const [duration, setDuration] = useState(0);
  // state to store control visibility
  const [isControlVisible, setIsControlVisible] = useState(false);

  // Reference to the VideoPlayer component
  const videoRef = React.useRef<VideoPlayerRef>(null);
  // Reference to track current playback time
  const progressRef = React.useRef<number>(0);

  return (
    // Safe area container for proper layout on devices
    <SafeAreaView style={styles.container}>

      {/* VideoPlayer component with source and event handlers */}
      <VideoPlayer
        ref={videoRef} // Reference to access VideoPlayer methods
        source={{ uri: 'https://ik.imagekit.io/ikmedia/example_video.mp4' }} // Video URL
        resizeMode={ResizeMode.COVER} // Video resize mode
        videoHeight={200} // Video height
        videoWidth={200} // Video width
        showDuration={true} // Show video duration
        onError={(error) => console.error('Video Error:', error)} // Handle playback errors
        onLoad={(data) => {
          console.log('Video Loaded:', data); // Log load data
          setDuration(data?.duration); // Set video duration state
        }}
        onBuffer={(data) => console.log('Buffering:', data)} // Log buffering status
        onProgress={(data) => {
          console.log('Video Progress:', data); // Log progress data
          progressRef.current = data.currentTime; // Update current playback time
        }}
        onSeek={async (data) => { // Handle seek event
          console.log('Seek:', data, videoRef?.current)
          await videoRef?.current?.resume()
        }}
        onShowControls={() => { // Handle control visibility
          setIsControlVisible(true)
        }}
        onHideControls={() => { // Handle control visibility
          setIsControlVisible(false)
        }}
      >
      </VideoPlayer>
      {isControlVisible && (
        <>
          <TouchableOpacity style={styles.forwardIcon} onPress={async () => {
            try {
              videoRef?.current?.seek(Math.min(progressRef.current + 5, duration))
            } catch (error) {
              console.error('Error:', error)
            }
          }}
          >
            <AntDesign name={'fastforward'} size={30} color="#fff" />
          </TouchableOpacity>
          <TouchableOpacity style={styles.backwardIcon} onPress={async () => {
            try {
              videoRef?.current?.seek(Math.max(progressRef.current - 5, 0))
            } catch (error) {
              console.error('Error:', error)
            }
          }}
          >
            <AntDesign name={'fastbackward'} size={30} color="#fff" />
          </TouchableOpacity>
        </>
      )}
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'yellow', // Set background color to yellow
  },
  forwardIcon: {
    position: 'absolute',
    top: '50%',
    left: '33%',
  },
  backwardIcon: {
    position: 'absolute',
    top: '50%',
    right: '33%',
  },
});

export default App;
Adding video player in React Native
Custom controls

Autoplay, Loop, and Mute

To autoplay the video, set the autoplay property to true. It is recommended to mute the video to ensure autoplay works on every platform smoothly. To mute the video, set the defaultMuted property to true.

To repeat the video, set the repeat property to true.

The VideoPlayer code would look like this:

 <VideoPlayer
        ref={videoRef} // Reference to access VideoPlayer methods
        source={{ uri: 'https://ik.imagekit.io/ikmedia/example_video.mp4' }} // Video URL
        resizeMode={ResizeMode.COVER} // Video resize mode
        videoHeight={200} // Video height
        videoWidth={200} // Video width
        showDuration={true} // Show video duration
        autoplay={true} // Auto play video
        defaultMuted={true} // muted state
        repeat={true} // Repeat video
        onError={(error) => console.error('Video Error:', error)} // Handle playback errors
        onLoad={(data) => {
          console.log('Video Loaded:', data); // Log load data
          setDuration(data?.duration); // Set video duration state
        }}
        onBuffer={(data) => console.log('Buffering:', data)} // Log buffering status
        onProgress={(data) => {
          console.log('Video Progress:', data); // Log progress data
          progressRef.current = data.currentTime; // Update current playback time
        }}
        onSeek={async (data) => { // Handle seek event
          console.log('Seek:', data, videoRef?.current)
          await videoRef?.current?.resume()
        }}
        onShowControls={() => { // Handle control visibility
          setIsControlVisible(true)
        }}
        onHideControls={() => { // Handle control visibility
          setIsControlVisible(false)
        }}
      >
      </VideoPlayer>

Adaptive Bitrate Streaming

Before proceeding further, let's understand ABS a bit. ABS dynamically adjusts the quality of video content based on the viewer’s network conditions. The video is encoded at different bitrates, resulting in different qualities and file sizes.

Subsequently, a manifest file, similar to a text file, is prepared. This file contains information about segments of the video at varying bit rates. During playback, the video player loads the manifest file and chooses an appropriate segment, usually starting from the lowest bit rate stream to speed up initial playback. If network throughput is greater than the bit rate of the downloaded segment, it requests a higher bit rate segment. Hence, video player continues to adapt to changes in network throughput to ensure a smooth playback experience. This process is known as Adaptive Bitrate Streaming (ABS).

Currently, there are two major protocols for ABS, which lead to two different types of manifest files.

  1. HTTP Live Streaming (HLS) - The manifest file is denoted with m3u8 extension.
  2. Dynamic Adaptive Streaming over HTTP (MPEG-DASH) - The manifest file is denoted with mpd extension.

Creating these manifest files yourself can be tricky. To streamline this, you can utilize a video API platform like ImageKit. ImageKit offers a straightforward URL-based parameter for generating a manifest file in the protocol of your choice.

Support in react-native-video-player

The video library offers out-of-the-box support for the ABS. We simply need to provide the ABS URL, and it will play the required video quality based on the available bandwidth.

To play the HLS stream, we would use the following URL:

https://ik.imagekit.io/ikmedia/sample-video.mp4/ik-master.m3u8?tr=sr-240_360_480_720
💡
If you're wondering, the above URL to a manifest file contains pointers to multiple video streams, each corresponding to a bitrate, as described in the query parameter. So, in this case, we have a single source video file that is converted into multiple video files based on the required bitrates, i.e. 240p, 360p, 480p, 720p, and 1080p, and stored in an encoded manifest.

Later in this tutorial, we'll be talking about how we can use ImageKit's Video API to generate such .m3u8 or .mpd manifests.
...
    <VideoPlayer
    ref={videoRef} // Reference to access VideoPlayer methods
    source={{ uri: 'https://ik.imagekit.io/ikmedia/sample-video.mp4/ik-master.m3u8?tr=sr-240_360_480_720' }} // Video URL
    ....
    >
    </VideoPlayer>
...

ImageKit.io for Video Transformations and Optimisation

Video files, when transferred over a network to a user's device, can significantly impact user experience if not optimized. Implementing best practices for transformation and optimisation before delivery, hence, becomes vital. The techniques include, but are not limited to:

  • Resizing to proper dimensions with server-side encoding.
  • Encoding to next-generation formats with improved compression while ensuring compatibility.
  • Creating multiple bitrate versions for Adaptive Bitrate Streaming (ABS) for users on slower networks.

Media delivery and management for high-growth teams | ImageKit.io is a powerful platform that offers real-time image and video optimization. It serves as a comprehensive solution for end-to-end media management, optimization, and delivery while supporting various transformations such as resizing, cropping, format conversion, quality adjustment, and many more. The platform also offers a generous free tier to get you started.

Let’s look at some use cases in which ImageKit’s Video API can help deliver better video playback experiences for your users, optimize your video delivery, and save on your network costs.

Resizing the video

In the resizing approaches we’ve seen earlier in this tutorial, we have been resizing the player’s container dimensions. Although this works well to fit the player well within the UI, is the video size optimized? The answer is no, and here’s why.

When you’re using a 4k raw video file with dimensions 3840x2160 and trying to load it over the network to fit the video inside a player of dimensions 200x200, there’s a huge unnecessary network overhead for your system. And a network overhead comes with a cost - in this case, both in terms of money and user experience.

So, how do you solve this problem? A straightforward approach is creating multiple raw video files with different dimensions and calling for the most compatible one based on the player’s container size. And here, you introduce overhead storage costs and a good amount of complexity in your code.

With ImageKit’s Video Transformations, you can transform your raw video file into an appropriate size on the go while loading it within your player’s container with just a query parameter. Imagekit encodes the video on the server side, resulting in smaller size and faster downloads.

Adding video player in React Native

The original video file is ~ 37.7 MB

If we use the raw video file, we would transfer ~37.7 MB over the network. To resize the video file for a 200x200 container, we need to add a query parameter tr with the values w-200 and h-200.

Updated URL: https://ik.imagekit.io/ikmedia/example_video.mp4?tr=w-200,h-200

Adding video player in React Native

After resizing, we have reduced the network overhead to ~0.41 MB (a steep 98.9% reduction).

Let’s update our code to make use of this. In App.tsx.

...
    <VideoPlayer
    ref={videoRef} // Reference to access VideoPlayer methods
    source={{ uri: 'https://ik.imagekit.io/ikmedia/example_video.mp4?tr=w-200,h-200' }} // Video URL
    ....
    >
    </VideoPlayer>
...

To learn more about video resizing, you can check out the documentation here: Resize, crop, and other common video transformations | ImageKit.io Docs

Adaptive Bitrate Streaming (ABS)

With ImageKit Video API, generating ABS manifest is simple. Both DASH and HLS protocol are supported.

If you're new to Adaptive Bitrate Streaming (ABS), this article will help you learn more about it. It discusses ABS in depth and compares both protocols to help you choose the one that best suits you.

MPEG-DASH

To create an MPEG-DASH ABS playlist, you need to suffix the URL path with ik-master.mpd and use the tr query parameter with the sr value to specify the resolutions. Here’s an example:

https://ik.imagekit.io/ikmedia/example_video.mp4/ik-master.mpd?tr=sr-240_360_480_720_1080

HLS

To create an HLS ABS playlist, you need to suffix the URL path with ik-master.m3u8 and use the tr query parameter with the sr value to specify the resolutions. Here’s an example:

https://ik.imagekit.io/ikmedia/example_video.mp4/ik-master.m3u8?tr=sr-240_360_480_720_1080

Conclusion

The article begins by setting up a barebones Android app on a Virtual device with React Native. Then, we explored different video players in React Native and implemented the appropriate player according to our needs.

Later, we explored the various options the video player provides and implemented custom controls using its event handlers.

We also learned how the ImageKit video API can simplify various use cases, such as video resizing or generating ABS manifest files on the fly, which video players can use to stream video smoothly.

]]>
<![CDATA[Video player in Angular applications]]> tag, Video.js, and adaptive streaming. Optimize delivery with best practices.]]>https://imagekit.io/blog/video-player-in-angular/67bd92e947ef7900014b805bFri, 28 Feb 2025 06:49:48 GMT

This tutorial walks through embedding videos using the HTML5 <video> tag, customizing playback with Video.js, and implementing Adaptive Bitrate Streaming (ABS). We’ll also explore video optimization techniques with ImageKit, covering transformations, resizing, and format selection to enhance performance across different devices and networks.

Whether you're adding basic video playback or optimizing for a scalable, high-quality streaming experience, this guide provides practical implementations to help you get there.

Table of contents

Embed videos with the HTML5 <video> tag

The HTML5 <video> tag provides a straightforward way to embed videos directly into web pages. Here is a basic example:

<video src="your-video.mp4" width="640" height="360" controls>
  This text will be rendered if browser does not support the video tag.
</video>

In a <video> tag, the src attribute specifies the location of the video file, which can be a relative HTTP path within your website or a full HTTP URL. The width and height attributes define the dimensions of the video player. The controls attribute adds the default browser controls, such as play, pause, and volume.

Learn more about the <video> tag and its attributes: HTML Video Element.

Define multiple video sources using <source> tag

To ensure maximum compatibility across different browsers, it's a good idea to provide video sources in multiple formats. You can do so by using the <source> tag within the <video> element to provide video sources in multiple formats. This allows the browser to select a compatible format.

The order in which you list the <source> tags is crucial. The browser starts from the top and uses the first format it supports. Here is how you can do it:

<video width="640" height="360" controls>
  <source src="your-video.webm" type="video/webm">
  <source src="your-video.mp4" type="video/mp4">
</video>

In a <source> tag, the src attribute specifies the URL of the video file, and the type attribute specifies the MIME type of the video file.

Basic video player in Angular application

Let's start by creating an Angular app from scratch.

First, you need to install Angular CLI:

npm install -g @angular/cli

Next, create a new Angular project:

ng new my-video-app

Navigate to the project directory:

cd my-video-app

Now, let's create a reusable Angular component for embedding videos using the <video> tag. Run the following command to generate the component

ng generate component video-player --style none --skip-tests true --inline-template

This command will create a file at src/app/video-player/video-player.component.ts. Open this file and replace its content with the code below:

import { Component, Input } from "@angular/core";
import { NgFor } from "@angular/common";

@Component({
  selector: "app-video-player",
  imports: [NgFor],
  template: `
    <video
      [attr.src]="videoSourceList.length ? null : src"
      [attr.width]="width ?? 'auto'"
      [attr.height]="height ?? 'auto'"
      [attr.poster]="poster"
      [attr.controls]="controls"
      [attr.autoplay]="autoplay"
      [attr.playsInline]="autoplay"
    >
      <source
        *ngFor="let v of videoSourceList"
        [src]="v.src"
        [type]="v.mimeType"
      />
      Your browser does not support the video tag...
    </video>
  `,
})
export class VideoPlayerComponent {
  @Input() videoSourceList: { src: string; mimeType?: string }[] = [];
  @Input() src?: string;
  @Input() width?: number;
  @Input() height?: number;
  @Input() poster?: string;
  @Input() controls?: boolean;
  @Input() autoplay?: boolean;
}

Following are some additional HTML5 <video> tag attributes we used in our component:

  • poster Specifies an image to be displayed before the video starts playing.
  • controls Adds video controls like play, pause, and volume.
  • autoplay The video automatically starts playing when the page loads.
  • playsinline Ensures the video plays within the playback area. This is useful for Safari browser on mobile devices so video can play without moving to fullscreen playback mode. (Note: In Angular playsinline is mapped to playsInline in camelCase)

Now we can use this component in our Angular application. Check the examples below.

Adjust the video player’s width and height

<app-video-player
  src="https://ik.imagekit.io/ikmedia/example_video.mp4"
  [autoplay]="true"
  [width]="640"
  [height]="480"
></app-video-player>

The video player by default sets its dimensions to the video’s resolution. This can cause layout shifts in your web application as the video loads. To avoid layout shifts, we must define the width and height of the video player. In this case, we set it to 640X480.

Video player in Angular applications
Video player with defined width and height (640x480).
💡
The width and height attributes of the video tag only control the dimension of the video player’s playback area. While the source video (https://ik.imagekit.io/ikmedia/example_video.mp4) has a very high resolution of 3840x2160 (4K). This is much larger than our playback area of 640x480. By resizing the video to match the playback area, we can significantly reduce the file size and minimize buffering, leading to a smoother viewing experience. To resize videos you can use media encoding tools like ffmpeg or cloud-based services like Imagekit.io.

Video player with a poster image and controls for playback

<app-video-player
  src="https://ik.imagekit.io/ikmedia/example_video.mp4"
  poster="https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg"
  [controls]="true"
  [height]="360"
></app-video-player>
Video player in Angular applications
Video player with a poster image and playback controls enabled.

Video player with multiple sources for the browser to choose from

<app-video-player
  [videoSourceList]="[
    {
      src: 'https://ik.imagekit.io/ikmedia/example_video.mov?tr=f-webm',
      mimeType: 'video/webm',
    },
    {
      src: 'https://ik.imagekit.io/ikmedia/example_video.mov?tr=f-mp4',
      mimeType: 'video/mp4',
    },
  ]"
  [controls]="true"
  [width]="640"
  [height]="480"
></app-video-player>

In this example, we have defined multiple video sources within the videoSourceList attribute of the VideoPlayerComponent.

In the browser, it will render the following HTML:

Video player in Angular applications
Video player with multiple sources.

Crucially, browsers choose the first supported format they encounter in the source list.

To balance file size and browser compatibility, we provide the video in both WebM (15.4MB) and MP4 (20.5MB) formats. WebM offers superior compression, resulting in smaller file sizes, but it's not universally supported. By listing WebM first, we allow compatible browsers to use the smaller file, saving bandwidth. MP4 serves as a fallback, ensuring playback for browsers that don't support WebM.

We can test how this arrangement works on the Firefox browser, by enabling and disabling WebM. (navigate about:config, search for media.webm.enabled and toggle the boolean field)

When WebM is enabled, the browser loads the WebM source to play in the video player:

Video player in Angular applications
Enable media.webm in Firefox browser's config.
Video player in Angular applications

When WebM is disabled, the browser loads the MP4 source to play in the video player:

Video player in Angular applications
Disable media.webm in Firefox browser's config.
Video player in Angular applications
💡
ImageKit allows you to transform videos on the fly using URL queries. In this example, we use the tr=f-webm query to re-encode the video into WebM format and the tr=f-mp4 query to re-encode the video into MP4 format.

Advanced video playback using Video.js in Angular application


Video.js is a popular open-source HTML5 video player that offers a consistent UI across browsers and supports a variety of plugins for extended functionality.

In this section, we’ll explore how to integrate Video.js into an Angular application. We’ll also cover the fundamentals of adaptive bitrate streaming (ABS) and how to implement it using Video.js.

Setting up Video.js

First, let's set up Video.js in your Angular application.

Install Video.js:

npm install video.js

Install TypeScript Definitions for Video.js:

npm install --save-dev @types/video.js

Generate a new Angular component for the video player:

ng generate component video-js-player --style none --skip-tests true --inline-template

Open the generated component file at src/app/video-js-player/video-js-player.component.ts and replace its content with the code below:

import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import videojs from "video.js";

@Component({
  selector: "app-video-js-player",
  template: `
    <video
      #target
      class="video-js vjs-default-skin"
      controls
      preload="auto"
      [attr.width]="width"
      [attr.height]="height"
      [poster]="poster"
    ></video>
  `,
  standalone: true,
  encapsulation: ViewEncapsulation.None,
  styleUrls: ["../../../node_modules/video.js/dist/video-js.css"],
})
export class VideoJsPlayerComponent implements OnInit, OnDestroy {
  private player: any;

  @ViewChild("target", { static: true }) target!: ElementRef;
  @Input() src!: string;
  @Input() width?: number;
  @Input() height?: number;
  @Input() poster?: string;
  @Input() fluid: boolean = false;

  ngOnInit() {
    // Initialize the Video.js player
    this.player = videojs(this.target.nativeElement, {
      sources: [{ src: this.src }],
      width: this.width,
      height: this.height,
      poster: this.poster,
      fluid: this.fluid,
    });
  }

  ngOnDestroy() {
    // Clean up the Video.js player to avoid  memory leaks
    if (this.player) {
      this.player.dispose();
    }
  }
}

Now we can use this component in our Angular application. Here's an example with a poster and an MP4 source:

<app-video-js-player
  src="https://ik.imagekit.io/ikmedia/example_video.mp4"
  poster="https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg"
  [width]="640"
  [height]="360"
></app-video-js-player>
Video player in Angular applications
Video.js player integrated into an Angular component

Player for Adaptive Bitrate Streaming (ABS)


Adaptive Bitrate Streaming (ABS) is a technique used to improve video playback experience by dynamically adjusting between higher and lower quality video streams based on the user's network conditions. This ensures a smooth viewing experience with minimal buffering.

Understanding ABS Playlists

To implement ABS, we need an ABS playlist. This playlist contains a manifest file and video segments in multiple bitrates. The manifest files contain locations and directives to fetch the video segments, each segment corresponding to a specific duration and bitrate. During playback, the video player dynamically selects the appropriate segment based on the viewer's network conditions, device capabilities, and resolution preferences.

MPEG-DASH and HLS (HTTP Live Streaming) are the 2 most popular ABS protocols.

To generate an ABS playlist manually, you can follow this article on MDN. However, this process can be complicated and not scalable. Later in this article, we'll discuss an efficient and easy way to generate ABS playlists using Imagekit.

Implementing ABS in Angular with Video.js

ABS playlists don’t have native support in most browsers. Video.js allows us to implement ABS on all popular browsers, with ease.

All you need to do is set the video source to the playlist’s manifest file. Here is an example:

<app-video-js-player
  src="https://ik.imagekit.io/demo/sample-video.mp4/ik-master.mpd?tr=sr-240_360_480_720_1080"
  [fluid]="true"
></app-video-js-player>
Video player in Angular applications
Video player streaming an MPEG-DASH playlist
💡
If you are using Video.js version 7 or later, you do not need to install additional plugins for DASH or HLS support. However, if you are using an older version of Video.js, you might need to install videojs-contrib-dash and videojs-contrib-hls plugins to enable DASH and HLS playback.

Imagekit.io for effortless video delivery


What is Imagekit.io?

Imagekit.io is a powerful platform that offers real-time image and video optimization tools. It is an end-to-end solution for media management, optimization, and delivery. It provides features such as transformations, resizing, cropping, format conversion, quality adjustment, and more for media files.
Imagekit's Video API offers a comprehensive toolset engineered to equip you with everything necessary to deliver your users a first-class video playback experience. This service allows you to perform transformations and optimize videos dynamically. It also offers features like thumbnail generation and gif-to-video conversion.

Common use cases of Imagekit.io video API

Manually managing various video formats, resolutions, and encoding parameters can demand significant technical expertise and infrastructure. ImageKit's Video API steps in to handle the heavy lifting and simplifies the often complex world of video transformation, optimization, and delivery.

Resizing Videos to Appropriate Dimensions

When embedding videos in web applications, selecting an optimal resolution ensures that important details remain intact while reducing file size for efficient streaming across different platforms.

Let’s understand this with the example below:

<video
  width=400
  height=300
  src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4"
>
💡
Here we have used f-mp4 to ensure the delivered video is in mp4 format for clear comparision between video at different resolutions.
Video player in Angular applications
Video player with playing video at original 4K resolution

The video at the original resolution of 3840x2160 https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4 is of size about 20.5MB (too large).

Let’s try downscaling the video to a smaller resolution while preserving their original essence and minimizing any noticeable loss of detail.

ImageKit's video API lets you seamlessly transform videos. To resize the video, we add a transformation query tr=f-mp4,w-400,h-300,c-at_least. This will resize the video to at least 400x300 dimensions, potentially using a larger resolution if necessary to avoid any significant loss of detail and also maintain the original aspect ratio.

Let’s use the transformed video https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4,w-400,h-300,c-at_least in our example:

<video
  width=400
  height=300
  src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4,w-400,h-300,c-at_least"
>
Video player in Angular applications
Video player with playing optimised video at 400x300 resolution

The video on https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4,w-400,h-300,c-at_max is of size just 1MB. Despite a remarkable 95% reduction in file size, the downscaled video maintains virtually indistinguishable visual quality from the original.

Imagekit offers a variety of resizing & cropping strategies. Learn more: https://docs.imagekit.io/features/video-transformation/resize-crop-and-other-common-video-transformations

Deliver the most suitable video format

In the HTML <video> tag, we can provide multiple source URLs for loading the video, the browser will automatically choose the format it supports.

For example:

<video>
  <source
    src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-webm"
    type="video/webm"
  />
  <source
    src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-mp4"
    type="video/mp4"
  />
</video>

When specifying multiple sources, it is essential to arrange them in order of file size optimization, from smallest to largest. The browser prioritizes the first supported format, so strategically placing the most efficient source ensures that the most optimized video will be used. 😵‍💫

But when using imagekit.io, you don't need to worry about format selection or adding multiple sources. Using the same URL, ImageKit automatically detects the viewer’s device compatibility and delivers the most optimized format, ensuring seamless playback without additional configuration. 😎

So with imagekit.io, the above example will look like this:

<video src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=f-auto" />
So easy!

Add overlays over videos

You can add text, subtitles, images, or even video overlays directly to your videos using ImageKit's transformation parameters.

Here is an example to add text overlay:

https://ik.imagekit.io/ikmedia/example_video.mp4?tr=l-text,i-Skateboards%20makes%20me%20happy,fs-100,co-blue,bg-white,pa-50,l-end
Video player in Angular applications

Here, the text "Skateboards make me happy" on the video with a font size of 100, blue text color, white background, and 50px padding at the end position

For more information, refer to Imagekit's video overlay doc.

Generate thumbnail with Imagekit.io

Video-thumbnail feature can be used to generate poster images or thumbnails for a good video-playback experience.

To generate a video thumbnail, use ik-thumbnail.jpg suffix in the URL path.

Example: https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg

Video player in Angular applications
Example of video thumbnail generated by Imagekit.io

You can further customize the thumbnail and apply transformations using the transformation (tr) query to resize, crop, add overlays, etc.

In the transformation query, you can use the so (start-offset) parameter to pick the thumbnail from a specific timestamp of the video. By default, the first frame of the video (so=0) is used.

Example: https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg?tr=so-2,w-400,h-300

Here, the thumbnail is cropped to 400x300 pixels from the 2-second mark of the video.

Video player in Angular applications
Example of video thumbnail generated by Imagekit.io at 2 second offset

Generate thumbnails or posters for your videos using AI

ImageKit’s Generative AI transformations allow you to generate a images from text prompt. This feature allows you to generate attention grabbing poster and thumbnail images for your videos.

You can generate an image based on a text prompt by simply describing what you want in the URL. Apply the following syntax:

https://ik.imagekit.io/your_account/ik-genimg-prompt-{description}/image.jpg

Replace {description} with a short phrase describing the image.

For example, to create a unique thumbnail featuring a skateboard on grass, we will use the following URL:

https://ik.imagekit.io/ikmedia/ik-genimg-prompt-A skateboard on grass/skateboard.jpg
Video player in Angular applications
Image generated using Imagekit AI

Adaptive bitrate streaming with Imagekit.io

In previous sections, we have already discussed what ABS is, what are ABS playlists and how can we implement them in Angular applications using Video.js. But the elephant in the room remains: how can we generate these ABS playlists efficiently and scalably without any hassles?

The good news is that you can easily create an ABS playlist of your videos using ImageKit’s video API. ImageKit can generate and deliver all necessary variants and manifest files from a single source video that is accessible through your ImageKit account.

To generate an ABS playlist using ImageKit, you need to append the following keywords to your video URL path:

For a DASH playlist, append /ik-master.mpd to your video URL. Example: https://ik.imagekit.io/demo/sample-video.mp4/ik-master.mpd?tr=sr-240_360_480_720_1080

For an HLS playlist, append /ik-master.m3u8 to your video URL. Example: https://ik.imagekit.io/demo/sample-video.mp4/ik-master.m3u8?tr=sr-240_360_480_720_1080

The tr=sr-<representations> transformation query specifies the video renditions to include in the playlist. For example, tr=sr-240_360_480_720_1080 creates profiles of 240p, 360p, 480p, 720p, and 1080p. Consult the ImageKit documentation for more details on supported representations: Adaptive Bitrate Streaming

How ImageKit helps with ABS

Essentially, ImageKit's video API empowers you to effortlessly implement ABS, freeing you from the intricacies of manual setup and management. Here's how ImageKit streamlines the process:

  • Automatic Playlist Generation: Forget the hassle of manually creating and managing ABS playlists. ImageKit automatically generates both DASH and HLS playlists from your source video, saving you time and effort.
  • Effortless Integration: Integrating ABS with ImageKit is as simple as adding a few characters to your video URLs. Append /ik-master.mpd for DASH or /ik-master.m3u8 for HLS, and you're ready to stream.
  • Apply transformations: Apply trimming, add image overlays, text overlays, subtitle overlays, and border, etc. Note, you can not resize or crop the base video in ABS, please refer to ABS docs for more information.
  • Customizable Renditions: Tailor your ABS playlists to perfection with ImageKit's transformation queries. ImageKit allows you to specify the video renditions to include in the ABS playlist using the tr=sr-<representations> transformation query. Example: tr=sr-240_360_480_720_1080 creates profiles of 240p, 360p, 480p, 720p, and 1080p.

You can do all this in combination with all other video API features like thumbnail generation.

Conclusion

This guide walked through adding video playback to an Angular application, starting with the HTML5 <video> tag and supporting multiple formats for better browser compatibility.

We built a reusable Angular component for a basic HTML5 video player using the default customizations provided by most browsers. Then we built another Angular component for a more advanced video player using Video.js, enabling better controls, consistent UI across browsers and Adaptive Bitrate Streaming (ABS).

We also discussed how Imagekit equips you with tools and capabilities for an outstanding video playback experience:

  • In addition to resize, optimise and transform your video. Imagekit also delivers videos in the most optimal format that is compatible with your end user's platform automatically.
  • You also add text, subtitles, images, and even video overlays to your videos.
  • You can extract thumbnails from video frames using ImageKit's video thumbnail feature.
  • You can use ImageKit's AI to generate images from text prompts for attention-grabbing posters, thumbnails, and banners.
  • We explored how ImageKit automates ABS playlist generation, ensuring seamless streaming across different devices and network conditions.
]]>
<![CDATA[React image and video upload]]>https://imagekit.io/blog/react-image-and-video-upload/67b588fc47ef7900014b76ceTue, 25 Feb 2025 10:44:08 GMT

At some point in your career, you will need to implement file uploading in your application. While React simplifies building user interfaces, handling large-scale file uploads can still be a significant challenge.

This guide walks you through the step-by-step implementation of file uploads in a React application. Once we're done, you'll have an app that looks like this:

Here’s a summary of what you’ll learn in this tutorial:

Excited? Let’s jump right in! 🚀

You can check out the live demo on CodeSandbox and explore the code on GitHub.

What do you need to continue?

Before we begin, make sure you have all the prerequisites in place. You'll need Node.js - download the latest LTS version from the official website (for this project, we will be using Node 20.13.0). It is also recommended that you have a basic understanding of HTML, CSS, JavaScript/TypeScript, React, and some backend technology like Node.js. With these in place, you're ready to move forward!

Setting up the project

To get started, we will generate a new React application by running the following commands:

npm create vite@latest react-file-upload -- --template react-ts
cd react-file-upload
npm install

This initializes a React project with a fast, minimal setup using Vite and Typescript.

Now, let’s start a development server using npm run dev command.

❯ npm run dev
> react-file-upload@0.0.0 dev
> vite
  VITE v6.0.11  ready in 123 ms
  ➜  Local:   <http://localhost:5173/>
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

When we navigate to the url provided by the output of the command, we are greeted with a screen like this.

React image and video upload

Before starting to code, I like to remove the boilerplate code so that our project is minimal. This step is completely optional.

After cleaning up, the App.tsx should look something like this

function App() {
  return (
    <>
      <h1>Vite + React</h1>
      <div className="card">
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">Click on the Vite and React logos to learn more</p>
    </>
  );
}

export default App;

We’ll also just keep the basic styling in index.css

:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #131313;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

#root {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}

Setting up the upload form

Now that our project is set up, let's build the file upload component!

We’ll create a basic user interface for uploading files

import { File as FileIcon, Trash as TrashIcon, Upload as UploadIcon } from "@phosphor-icons/react";
import { useRef, useState } from "react";

const styles: Record<string, CSSProperties> = {}

function App() {
  const inputRef = useRef<HTMLInputElement>(null);

  const [file, setFile] = useState<File | null>(null);
  const [status, setStatus] = useState<"pending" | "uploading" | "success" | "error">("pending");

  const handleUpload = () => {
    setStatus("uploading");
    setTimeout(() => {
      setStatus("success");
    }, 2000);
  };

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        handleUpload();
      }}
      onReset={() => {
        setStatus("pending");
        setFile(null);
      }}
    >
      <h1 style={styles.heading}>Upload Files</h1>

      <div style={styles.uploadBox} onClick={() => inputRef.current?.click()}>
        <div style={styles.content}>
          <div style={styles.circle}>
            <UploadIcon size={32} />
          </div>

          <h2 style={styles.uploadText}>
            Drop your files here,
            <br /> or browse
          </h2>
        </div>
      </div>
      <input
        type="file"
        onChange={(e) => {
          setStatus("pending");
          setFile(e.target.files?.[0] || null);
        }}
        hidden
        ref={inputRef}
      />

      {file && (
        <>
          <div style={styles.fileList}>
            <div style={styles.fileElement}>
              <div style={styles.fileIcon}>
                <FileIcon size={32} />
              </div>
              <div style={styles.fileDetails}>
                <p style={styles.fileName}>{file.name}</p>
                <p style={styles.fileSize}>{(file.size / 1024).toFixed(2)} KB</p>
              </div>

              <div style={styles.filler} />

              {status === "pending" && (
                <button
                  style={styles.trash}
                  onClick={(e) => {
                    e.preventDefault();
                    if (inputRef.current) {
                      inputRef.current.value = "";
                    }
                    setFile(null);
                  }}
                >
                  <TrashIcon size={32} />
                </button>
              )}
              {status === "uploading" && <p style={styles.uploadingText}>Uploading...</p>}
              {status === "success" && <p style={styles.successText}>File uploaded successfully!</p>}
              {status === "error" && <p style={styles.errorText}>File upload failed!</p>}
            </div>
          </div>
          <div style={styles.uploadButtonContainer}>
            {status === "success" ? (
              <button style={styles.uploadButton} type="reset">
                Reset
              </button>
            ) : (
              <button style={styles.uploadButton} type="submit" disabled={status === "uploading"}>
                Upload Files
              </button>
            )}
          </div>
        </>
      )}
    </form>
  );
}

export default App;
React image and video upload

The code above defines a React component that allows users to upload files. The component uses the useRef and useState hooks to manage the state of the component. The useRef hook is used to create a reference to the file input element. The useState hook is used to manage the state of the file, the status of the upload, and the styles of the component.

The component has three main functions: handleUpload, handleDragOver, and handleDrop. The handleUpload function is called when the user clicks the upload button. It sets the status to "uploading" and then sets the status to "success" after 2 seconds

Now, let’s change the appearance of this form to make it look awesome.

We’ll create a file called styles.ts that will store our styles for our application, which we can get from here and then import it in App.tsx

import { File as FileIcon, Trash as TrashIcon, Upload as UploadIcon } from "@phosphor-icons/react";
import { useRef, useState } from "react";

-	const styles: Record<string, CSSProperties> = {}
+	import styles from "./styles";

This is what the application looks like after adding the styles

React image and video upload

Now, let’s add the drag-and-drop functionality into the elements

const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
  e.preventDefault();
  setStatus("pending");
  setFile(e.dataTransfer.files[0]);
};

const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
  e.preventDefault();
};

const handleUpload = () => {
  setStatus("uploading");

  const formData = new FormData();
  formData.append("file", file!);

  const xhr = new XMLHttpRequest();
  xhr.open("POST", "<http://localhost:3000/upload>");

  xhr.onreadystatechange = () => {
    if (xhr.readyState === XMLHttpRequest.DONE) {
      if (xhr.status === 200) {
        setStatus("success");
      } else {
        setStatus("error");
      }
    }
  };

  xhr.send(formData);
};

In the above code, we are defining functions to handle the following tasks.

  1. The handleDrop function is called when a file is dropped on the element that the function is attached to. It prevents the default browser behavior of dropping a file, which is to open the file in the browser. It then sets the file state to the first file in the dataTransfer object.
  2. The handleDragOver function is called when a file is dragged over the element that the function is attached to. It prevents the default browser behavior of dropping a file, which is to open the file in the browser.
  3. The handleUpload function is called when the user clicks the upload button. It sets the status state to "uploading". It then creates a new FormData object and appends the file state to it. It then creates a new XMLHttpRequest object and sets the open method to "POST" and the url to "http://localhost:3000/upload". It then sets the onreadystatechange property of the xhr object to a function that checks the readyState and status of the request. If the request is successful, the status state is set to "success". Otherwise, the status state is set to "error". Finally, the xhr object is sent with the formData object.

Now let’s bind these functions to the elements we have in DOM

<div
  style={styles.uploadBox}
  onClick={() => inputRef.current?.click()}
+ onDrop={handleDrop}
+ onDragOver={handleDragOver}
>
  <div style={styles.content}>
    <div style={styles.circle}>
      <UploadIcon size={32} />
    </div>

    <h2 style={styles.uploadText}>
      Drop your files here,
      <br /> or browse
    </h2>
  </div>
</div>

At this point if we try to upload a file, we will get an error saying “File upload failed!”.

This is because there is no backend server to upload to, so let’s set that up in the next step.

React image and video upload

Setting up the upload backend

Let’s switch gears to the server-side implementation.

For the scope of this tutorial, we will be using NodeJS and saving the files in the local filesystem.

We will start by creating a new folder in the project called server.

In this folder, we will run the following commands to setup a basic express.js server with multer to allow file uploads

npm init
npm install express multer cors

Now we will create a file called index.js in the server folder.

const express = require("express");
const multer = require("multer");
const fs = require("fs");
const cors = require("cors");

const app = express();
const upload = multer();

app.use(cors());

const uploadDir = "uploads";

if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir);
}

app.post("/upload", upload.single("file"), (req, res) => {
    const file = req.file;

    if (!file) {
        return res.status(400).send({ status: "error", message: "No file uploaded" });
    }

    const filePath = `${uploadDir}/${file.originalname}`;
    try {
        fs.writeFileSync(filePath, file.buffer);
        res.send({ status: "success", message: "File uploaded successfully" });
    } catch (error) {
        res.status(500).send({ status: "error", message: "Failed to save file" }); 
    }
});

app.listen(3000);

Let's understand what is happening in the code above:

  1. Importing and initializing modules
    The application requires several modules to function, including a web framework, a middleware for handling file uploads, a file system module for file operations, and a module to handle Cross-Origin Resource Sharing (CORS). After importing them, it creates an instance of the web framework and a configured instance of the file upload middleware.
  2. Enabling CORS
    The application enables Cross-Origin Resource Sharing (CORS) to allow requests from other domains or ports. This is useful if the client-side and server-side are hosted on different URLs.
  3. Configuring the file uploads directory
    A directory name (for example, uploads) is assigned to store the uploaded files. The code checks if this directory exists on the server, and if it doesn’t, it is created.
  4. Handling file upload requests
    The code sets up a route that accepts POST requests for file uploads. When a file is sent to this route, the middleware processes it and attaches the file data to the request object.
  5. Writing the uploaded file to disk
    In the route handler, the file’s buffer (which contains its content) is written to the specified directory using the file’s original name. Proper error handling is implemented to respond with an error if something goes wrong during file saving.
  6. Starting the server
    Finally, the application starts listening for incoming requests on a specific port (in this case, port 3000), making the file upload route accessible.

We can start the server by running the command node index.js

Let’s test it out

With the backend and front end working, we seem to have completed the upload function, so now it’s time to test it out once.

If things go well, you should be able to see a green message saying “File uploaded successfully!” right next to the file's name.

React image and video upload

Implementing upload progress bar

Now that we have a working file upload in place let's add a progress bar for better user experience.

In App.tsx, replace the section where we are displaying the “File uploading” status with the code below

- {status === "uploading" && <p style={styles.uploadingText}>Uploading...</p>}
+ {status === "uploading" && (
+   <div style={styles.uploadingProgress}>
+     <div
+       style={{
+         ...styles.uploadingBar,
+         width: `${progress}%`,
+       }}
+     />
+     <p style={styles.uploadPercent}>{progress}%</p>
+   </div>
+ )}

After that, we’ll add the styles in the styles.ts file

uploadingProgress: {
  backgroundColor: "#3a3a3a",
  height: "24px",
  marginTop: "12px",
  maxWidth: "200px",
  width: "100%",
  textAlign: "center",
  lineHeight: "24px",
  position: "relative",
},
uploadingBar: {
  backgroundColor: "#0450d5",
  height: "24px",
  position: "absolute",
  width: "100%",
  zIndex: 0,
},
uploadPercent: {
  color: "white",
  margin: 0,
  lineHeight: "24px",
  position: "absolute",
  left: "50%",
  transform: "translate(-50%, 0%)",
  zIndex: 1,
},

It's time to add the javascript to update the progress bar. This can be achieved by using the progress event fired on the XMLHttpRequest.upload object. The event gives us 3 read-only properties with which we can calculate the percentage of the upload, but we are more interested in the following

  • total: The total size of the file being uploaded
  • loaded: The size of the file that has already been uploaded

So, let’s bind the event to the XHR request to update the progress bar. In the script tag, add the following javascript.

xhr.open("POST", "<http://localhost:3000/upload>");

xhr.upload.onprogress = (e) => {
  const percentLoaded = Math.round((e.loaded / e.total) * 100);
  setProgress(percentLoaded);
};

Voila!! You should now have a working progress bar for your file uploads.

Upload Validations

Finally, to make this production-ready, the upload flow should include at least basic file validations to prevent abuse of the API. These validations may be changed to suit business requirements. In addition to server side checks, implementing client side validations in your React application can greatly enhance user experience by catching errors before the file is sent to the server.

Restricting files based on type metadata

On server-side:

const upload = multer({
  fileFilter: (req, file, cb) => {
    // Allow only JPEG or PNG images
    if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
      cb(null, true); // Accept the file
    } else {
      cb(new Error("Invalid file type"), false); // Reject the file
    }
  },
});

This code sets a custom file filter for multer, a middleware used in Node.js for handling file uploads. It checks the MIME type of the uploaded file and allows only JPEG or PNG images to pass. If the file’s type matches "image/jpeg" or "image/png", it calls cb(null, true) to accept the file. Otherwise, it calls cb(new Error("Invalid file type"), false) to reject it.

On client-side:

const handleFileChange = (e) => {
  const file = e.target.files[0];
  // Validate file type before upload
  if (file && !["image/jpeg", "image/png"].includes(file.type)) {
    alert("Invalid file type. Please select a JPEG or PNG image.");
    return;
  }
  // Proceed with file upload if validations pass
  // e.g., setFile(file);
};

This code snippet checks the selected file's type before it is uploaded. If the file type is not JPEG or PNG, an alert notifies the user, preventing unnecessary server requests.

Restricting file size

On server-side:

const upload = multer({
    limits: {
        fileSize: 1024 * 1024 * 5, // 5MB
    },
});

This configuration sets a file size limit for uploads using multer. The limits property defines various constraints, and here fileSize is set to 5MB (5 * 1024 * 1024 bytes). When a user attempts to upload a file, multer will automatically reject any file that exceeds this size limit. If a file is too large, multer will throw an error, which you can handle in your error-handling middleware to inform the user that their file is too big. Implementing file size restrictions helps protect your server from excessive resource usage and ensures that uploads remain manageable and efficient.

On client-side:

const handleFileChange = (e) => {
  const file = e.target.files[0];
  // Validate file size before upload (limit to 5MB)
  if (file && file.size > 1024 * 1024 * 5) {
    alert("File size exceeds the 5MB limit.");
    return;
  }
  // Proceed with further processing or file upload if file size is within limit
  // e.g., setFile(file);
};

This client side validation checks the file size immediately after selection. If the file size exceeds 5MB, it alerts the user, thus reducing unnecessary load on the server.

Preventing file overwrites

const crypto = require("crypto")

const filePath = `${uploadDir}/${crypto.randomUUID()}-${file.originalname}`;

To prevent overwriting any existing upload, it’s always recommended to set the filePath with a file name that is not already used in the destination folder One of the simplest ways to achieve this would be to prefix the file name with a random UUID generated by crypto.randomUUID()

By adding both server-side and client-side checks, you create a safer and smoother user experience. The server validations protect your system from malicious or accidental misuse, while the client-side checks give users quick feedback before they even click “Upload.”

Kudos! We have a fully functional file upload widget ready in React. You can see a functional application on CodeSandbox

What's wrong with this approach?

Building your own upload system from the ground up is entirely feasible and ideal for small projects. However, what happens if your application suddenly gains massive popularity? Is your system equipped to manage a surge of users uploading large files simultaneously? Can users maintain optimal upload speeds? These are critical considerations when designing the upload functionality for your application.

While the do-it-yourself (DIY) method is excellent for educational purposes, it often falls short in real-world scenarios.

Common Challenges You May Face

  1. Limited file storage on servers
    Most DIY setups store uploaded files on the server’s disk, which has limited capacity. As your application scales, managing storage becomes a bottleneck. Expanding storage requires upgrading disks or shifting to a distributed storage solution, adding complexity.
  2. High latency with large file uploads
    Large files take longer to upload, and users farther from your server experience even more delay. Deploying servers in multiple regions helps, but it increases infrastructure costs and operational overhead.
  3. Security risks in file uploads
    File uploads are a common attack vector—malicious files can compromise your server. Implementing robust validation, sandboxing, and security protocols adds to development effort.
  4. Efficient file delivery
    Uploading files is only half the challenge—delivering them quickly and in the right format is another. Handling high request volumes, optimizing media, and ensuring seamless playback require additional processing layers.

A Smarter Way to Handle These Challenges

Instead of dealing with these complexities manually, a dedicated media management solution like ImageKit.io simplifies storage, speeds up uploads, enhances security, and ensures optimized file delivery—all without the need for extensive infrastructure management.

Uploading files directly from the browser

Uploading files directly from the browser saves us from handling the file upload on the backend and reduces server load and bandwidth usage. To achieve this, we will need to perform the following steps

  1. Setup the imagekit-react sdk
  2. Instead of directly using the upload API from the backend, we'll be using the IKUpload component provided by the React SDK to upload files to the ImageKit Media Library.
  3. Generate authentication parameters If we want to implement client-side file upload, we will need a token, expiry timestamp, and a valid signature for that upload.

Setting up the React SDK

We’ll start by using the same frontend we created above.

However, instead of creating and calling the API ourselves, we’ll be using the ImageKit React SDK, which provides a wrapper around the upload API to simplify the process.

Get the Developer Credentials from the ImageKit Dashboard

From the Developer settings in the ImageKit Dashboard, find and save your public key and private key to be used later.

React image and video upload

Install and Initialise the React SDK

To install the ImageKit React SDK, run the command

npm install imagekitio-react

After installing, let’s proceed to setting the SDK in our project, in our App.tsx we will wrap the form element in IKContext

<IKContext
      urlEndpoint="YOUR_IMAGEKIT_ENDPOINT"
      publicKey="YOUR_PUBLIC_KEY"
      authenticator={async () => {
        try {
          const response = await fetch("YOUR_BACKEND_ENDPOINT");
          const data = await response.json();
          return data.token;
        } catch (error) {
          console.error(error);
        }
      }}
    >
    <form ....>
     ....
    </form>
</IKContext>

Now let’s replace our input element on our website with IKUpload component from SDK

<IKUpload
  onChange={(e) => {
    setProgress(0);
    setStatus("pending");
    setFile(e.target.files?.[0] || null);
  }}
  onUploadStart={() => { 
    setStatus("uploading");
  }}
  onUploadProgress={(e) => {
    const percent = Math.round((e.loaded / e.total) * 100);
    setProgress(percent);
  }}
  onError={() => {
    setStatus("error");
  }}
  onSuccess={(res) => {
    console.log(res);
    setStatus("success");
  }}
  hidden
  ref={inputRef}
/>

In the first block of code, we initialize the ImageKit SDK by wrapping the form element with the IKContext component. This setup is crucial as it provides the necessary configuration for ImageKit to operate seamlessly within your React application. Here's a breakdown of the props used:

  • urlEndpoint: This is your unique ImageKit endpoint URL where the files will be uploaded.
  • publicKey: Your ImageKit public API key, which is essential for authenticating upload requests.
  • authenticator: An asynchronous function responsible for generating authentication parameters. We'll delve into the specifics of this function in the next section.

Moving on to the second block, we replace the standard file input with the IKUpload component from the ImageKit SDK.

React image and video upload

This component simplifies the upload process and provides several event handlers to manage different stages of the upload lifecycle:

  • onChange: Triggered when a user selects a file. It resets the upload progress, sets the status to "pending," and stores the selected file in the component's state.
  • onUploadStart: Called when the upload process begins, updating the status to "uploading" to inform users that their file is being uploaded.
  • onUploadProgress: Provides real-time feedback on the upload progress by calculating the percentage of the upload completed and updating the progress state accordingly.
  • onError: Handles any errors that occur during the upload process by setting the status to "error," allowing you to inform the user and take appropriate actions.
  • onSuccess: Executed upon a successful upload, logging the response from ImageKit and updating the status to "success" to notify the user that their file has been uploaded successfully.
  • The hidden attribute ensures that the default file input remains invisible, enabling you to design a custom upload button or interface that aligns with your application's aesthetics. Additionally, the ref={inputRef} connects the upload component to a reference, allowing you to programmatically trigger the file selection dialog or access the uploaded file as needed.

Generate authentication parameters

Now that we have done the front end, you might have observed that we have something called authenticator in the above code. This asynchronous function responsible for generating the necessary authentication tokens by fetching them from your backend server.

For this task we will ImageKit NodeJS SDK in our server to create API that returns authentication parameters.  Learn more about how to create the authentication parameters here

Let’s start by installing the NodeJS SDK in our server,

npm install imagekit

Once you are done installing the SDK, in our index.js file, we’ll add the following code

const ImageKit = require("imagekit");

const imagekit = new ImageKit({
    publicKey: "YOUR_IMAGEKIT_PUBLIC_KEY",
    urlEndpoint: "YOUR_IMAGEKIT_ENDPOINT",
    privateKey: "YOUR_IMAGEKIT_PRIVATE_KEY",
});

app.get("/auth", (req, res) => {
    res.send(imagekit.getAuthenticationParameters());
});

And we are done; we should have a completely functional application that uploads your files to ImageKit.

Upload Validations using ImageKit Upload

To enforce limits related to file size and file type, we can add checks that the ImageKit backend will evaluate while uploading the files.
You can read more about these checks here

1. Restrict uploads for a specific file type
In the IKUpload component that we used to upload the files, we can add the check, for instance, to allow only images to be uploaded

<IKUpload
  ...
  checks={`"file.mime": "image/"`}
/>

2. Restrict uploads depending on file size
In the IKUpload component that we used to upload the files, we can add the check to check if the being uploaded is less than the specified size. The check below checks if the file is larger than 1024 bytes by smaller than 5MB

<IKUpload
  ...
  checks={`"file.size" > 1024 AND "file.size" < "5mb"`}
/>

What more does ImageKit have to offer?

After completing the upload process, we need a scalable solution to efficiently optimize and deliver these assets with various transformations. ImageKit.io  provides a robust platform that delivers a complete solution for comprehensive media management, optimization, and distribution.

Image and Video Optimization

ImageKit.io includes a range of features such as automatic selection of the optimal format, quality enhancement, and metadata manipulation right out of the box to minimize the final size of images. Additionally, ImageKit.io offers extensive video optimization capabilities to ensure your media is efficiently processed.

Image and Video Transformation

Transforming images and videos is seamless with ImageKit.io by simply adjusting URL parameters. You can perform basic tasks like resizing images or more advanced operations such as adding watermarks, smart cropping, or object-aware cropping. For videos, ImageKit.io enables you to generate thumbnails, convert GIFs to MP4s, and stream videos using adaptive bitrate streaming (ABS) for the best viewing experience.

Collaboration & Sharing

ImageKit’s Digital Asset Management (DAM) solution facilitates the organization, sharing, and management of user access with customizable permission levels for individual users and user groups, ensuring secure and efficient collaboration.

Conclusion

In this tutorial, we've covered:

  • Building a file upload application in React from scratch.
  • Implementing file type and size validations for secure uploads.
  • Transitioning to ImageKit.io for direct uploads from the browser, making our application more efficient and scalable.
  • Utilizing ImageKit's free upload API, ImageKit React SDK, and ImageKit NodeJS SDK for a streamlined experience with minimal code.

You can check out the live demo on CodeSandbox and explore the code on Github.

]]>
<![CDATA[Next.js image and video upload]]>https://imagekit.io/blog/nextjs-image-and-video-upload/67bc72db47ef7900014b7d94Tue, 25 Feb 2025 06:25:12 GMT

In this guide, we will learn step-by-step how to handle file uploads in a Next.js application.

You can check out the final, working application here, or explore the source code from this GitHub repository.

The final result will look like this:

This guide is divided into the following sections:

Requirements

To complete this tutorial, we will need the following. If you are using more recent versions of any of these components, you may have to make minor adjustments. The guide also assumes you have a basic knowledge of HTML, JavaScript, and CSS.

  1. Node.js - version 22
  2. npm
  3. npx (comes packaged with npm; if not, then install with npm install -g npx)

Set up the Next.js application

Let’s set up a starter Next.js application.

Run the following command in the directory that you want the project to be created:

npx create-next-app

You will be asked a few questions related to the configuration of the project. You may answer them as you prefer.

Now, run

npm run dev

When we navigate to localhost:3000 in our browser, we should see a default home page like this:

Next.js image and video upload
Next.js default starter page

Add a simple upload button

Let’s remove everything from src/app/page.js, and begin building our upload interface. We start by adding a basic <input> element to accept files.

src/app/page.js should have the following code:

'use client' 

import styles from "./page.module.css";

export default function Home() {
  return (
    <div className={styles.page}>
      <main className={styles.main}>
        <input type="file" />
      </main>
    </div>
  );
}

The webpage at localhost:3000 should now look like this:

Next.js image and video upload
The webpage now has a basic upload HTML element

Now, when we click on “Browse…“ and select a file to upload, the file does get selected with its name displayed in place of “Browse…“, but we are not sending the file anywhere outside of this webpage.

Let’s fix that by adding a JavaScript “handler“ function to do something with the picked-up file. The handler function  handleUploadsends a POST request to the route /api/upload with the file attached to the request body. We use the native FormData API to simplify this.

src/app/page.js should have the following code:

'use client';
import styles from "./page.module.css";
 
export default function Home() {
  const handleUpload = (file) => {
    if (!file) return;
 
    const formData = new FormData();
    formData.append('file', file);
 
    const xhr = new XMLHttpRequest();
 
    xhr.onload = (obj) => {
      if (xhr.status === 200) {
        alert("File uploaded successfully!")
      } else {
        alert("File could not be uploaded!")
      }
    };
 
    xhr.onerror = () => {
      alert("File could not be uploaded!")
    };
 
    xhr.open('POST', '/api/upload');
    xhr.send(formData);
  };
 
  return (
    <div className={styles.page}>
      <main className={styles.main}>
        <input type="file" onChange={(e) => handleUpload(e.target.files[0])} />
      </main>
    </div>
  );
}

Set up the backend to accept and save assets

The handleUpload function attempts to send the file to the /api/upload API, but there is no such API endpoint. Let’s create one. Create a new file src/app/api/upload/route.js

src/app/api/upload/route.js should have the following code:

import { writeFile, mkdir } from 'fs/promises';
import { NextResponse } from 'next/server';
import path from 'path';
 
export async function POST(request) {
  try {
    const formData = await request.formData();
    const file = formData.get('file');
     
    // error out if no file is received via FormData
    if (!file) {
      return NextResponse.json(
        { error: 'No file received.' },
        { status: 400 }
      );
    }
 
    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);
 
    // build the complete path to our 'public/uploads' directory
    const filePath = path.join(process.cwd(), 'public/uploads', file.name);
    // ensure the uploads directory exists
    await mkdir(path.dirname(filePath), { recursive: true });
    await writeFile(filePath, buffer);
 
    return NextResponse.json({ message: 'File uploaded successfully!' });
  } catch (error) {
    // handle any unknown error
    return NextResponse.json(
      { error: 'Error uploading file.' },
      { status: 500 }
    );
  }
}

We now have an API route at /api/upload that accepts a file called file in the request body, and saves it to the public/uploads/ directory in the project. Let’s try it out. Click on “Browse…“ on the webpage again, and select a file. You should see the “File uploaded successfully“ browser alert popup. In the public/uploads directory of your project, you should see the uploaded file.

Add basic validation and security

However, the request might fail if your selected file is larger than the default limit that Next.js sets up. Let’s fix that, and allow files up to a maximum of 5 MB (or some other number) to be uploaded. Along with this, we also add a few basic validation checks on the incoming file. This is critical to protect your server from attacks via malicious file uploads. We will revisit the security aspect of file uploads in a later section. Let’s add our validations now.

Make the following changes in src/app/api/upload/route.js:

// old imports
export async function POST(request) {
  try {
    // old code
 
    // Validate file type
    const allowedTypes = [
      'image/jpeg',
      'image/png',
      'image/gif',
      'image/webp',
      'video/mp4',
      'video/webm',
      'video/quicktime'
    ];
 
    if (!allowedTypes.includes(file.type)) {
      return NextResponse.json(
        { error: 'File type not allowed. Only images and videos are accepted.' },
        { status: 400 }
      );
    }
 
    // Validate file size (5MB = 5 * 1024 * 1024 bytes)
    const maxSize = 5 * 1024 * 1024;
    if (file.size > maxSize) {
      return NextResponse.json(
        { error: 'File size exceeds 5MB limit.' },
        { status: 400 }
      );
    }
 
    // Validate filename
    const filename = file.name.replace(/[^a-zA-Z0-9.-]/g, '_');
    if (filename !== file.name) {
      return NextResponse.json(
        { error: 'Filename contains invalid characters.' },
        { status: 400 }
      );
    }
 
    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);
 
    const uploadDir = path.join(process.cwd(), 'public/uploads');
    await mkdir(uploadDir, { recursive: true });
    await writeFile(path.join(uploadDir, filename), buffer);
 
    return NextResponse.json({
      message: 'File uploaded successfully!',
      filename: filename
    });
  } catch (error) {
    return NextResponse.json(
      { error: 'Error uploading file.' },
      { status: 500 }
    );
  }
}

You should see an error being raised like this on invalid file uploads:

Next.js image and video upload

We have successfully created our basic file upload module!

Add some bells and whistles (drag-and-drop, copy-paste, progress bar)

Now, it’s time to make it look pretty. We will add three things:

  1. A progress bar for an ongoing upload
  2. The ability to drag and drop files for upload
  3. The ability to paste a file from the clipboard for upload

1. Progress bar

To display a progress bar, we use the onprogress event handler on the XMLHttpRequest.upload object. The event object received as an argument to this callback gives us two key numbers:

1. The number of bytes sent to the server

2. The total number of bytes that need to be sent to the server

Using these two numbers, we calculate the progress percentage of our upload. Let’s write the code for this.

Along with adding a progress bar, we apply some cosmetic changes as well.

Make the following changes to src/app/page.js:

// old imports
import { useState, useRef } from "react"

export default function Home() {
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadStatus, setUploadStatus] = useState(null);
  const [uploadStats, setUploadStats] = useState({ loaded: 0, total: 0 });
  const [isUploading, setIsUploading] = useState(false);
  
  const resetUpload = () => {
    setUploadProgress(0);
    setUploadStatus(null);
    setUploadStats({ loaded: 0, total: 0 });
    setIsUploading(false);
    if (formRef.current) {
      formRef.current.reset();
    }
  };

  // modified upload handler
  const handleUpload = (file) => {
    // old code

    setIsUploading(true);
    setUploadStatus(null);

    // new event callback
    xhr.upload.onprogress = (event) => {
      if (event.lengthComputable) {
        const progress = (event.loaded / event.total) * 100;
        setUploadProgress(progress);
        setUploadStats({
          loaded: event.loaded,
          total: event.total
        });
      }
    };

    // set the upload progress to 0 after request completion
    xhr.onload = (obj) => {
      setIsUploading(false);
      if (xhr.status === 200) {
        setUploadStatus('success');
        setUploadProgress(100);
      } else {
        setUploadStatus('error');
        setUploadProgress(0);
      }
    };

    // set the upload progress to 0 after request failure too
    xhr.onerror = () => {
      setUploadStatus('error');
      setUploadProgress(0);
      setIsUploading(false);
    };

    // old code
  };

  const formatBytes = (bytes) => {
    if (bytes === 0) return '0 KB';
    const k = 1024;
    return `${(bytes / k).toFixed(1)} KB`;
  };

  return (
    <div className={styles.page}>
      <main className={styles.main}>
        <div className={`${styles.uploadArea} ${isUploading ? styles.disabled : ''} ${(uploadProgress > 0 || uploadStatus) ? styles.withProgress : ''}`}>
          <p className={styles.uploadText}>
            Select an image or video to upload<br />
          </p>
          <label className={`${styles.fileInputLabel} ${isUploading ? styles.disabled : ''}`}>
            <input
              type="file" 
              name="file"
              className={styles.fileInput}
              disabled={isUploading}
              onChange={(e) => handleUpload(e.target.files[0])}
            />
            Choose a file
          </label>

          {(uploadProgress > 0 || uploadStatus) && (
            <div className={styles.uploadProgress}>
              {uploadStatus ? (
                <div className={`${styles.uploadStatus} ${styles[uploadStatus]}`}>
                  {uploadStatus === 'success' ? (
                    <>
                      <p>✓ Upload completed successfully!</p>
                      <button type="button" className={styles.restartButton} onClick={resetUpload}>
                        ↺ Upload another file
                      </button>
                    </>
                  ) : (
                    <>
                      <p>✕ Upload failed. Please try again.</p>
                      <button type="button" className={styles.restartButton} onClick={resetUpload}>
                        ↺ Try again
                      </button>
                    </>
                  )}
                </div>
              ) : (
                <>
                  <div className={styles.uploadProgressHeader}>
                    <div className={styles.fileIcon}>📄</div>
                    <div>Uploading...</div>
                  </div>
                  <div className={styles.progressContainer}>
                    <div 
                      className={styles.progressBar} 
                      style={{ width: `${uploadProgress}%` }}
                    />
                  </div>
                  <div className={styles.progressStats}>
                    <span>{formatBytes(uploadStats.loaded)} / {formatBytes(uploadStats.total)}</span>
                    <span>{Math.round(uploadProgress)}%</span>
                  </div>
                </>
              )}
            </div>
          )}
        </div>
      </main>
    </div>
  );
}

We also need some CSS to make the progress bar look nice. Add the following CSS to the end of src/app/page.module.css

.progressContainer {
  width: 100%;
  margin-bottom: 1rem;
  background: rgba(0, 112, 243, 0.08);
  border-radius: 4px;
  overflow: hidden;
}

.progressBar {
  height: 6px;
  background: linear-gradient(90deg, #0070f3, #00a3ff);
  transition: width 0.3s ease-out;
  border-radius: 3px;
}

.uploadProgress {
  border: 1px solid rgba(0, 112, 243, 0.1);
  border-radius: 8px;
  padding: 1rem;
  margin-top: 1rem;
  background: rgba(0, 112, 243, 0.03);
  backdrop-filter: blur(8px);
}

.uploadProgressHeader {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
  color: #666;
  font-size: 0.9rem;
}

.fileIcon {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 112, 243, 0.08);
  border-radius: 6px;
  color: #0070f3;
  font-size: 1rem;
}

.progressStats {
  display: flex;
  justify-content: space-between;
  font-size: 0.875rem;
  color: #666;
  margin-top: 0.5rem;
}

.uploadStatus {
  text-align: center;
  padding: 1rem;
}

.uploadStatus.success {
  color: #16a34a;
}

.uploadStatus.error {
  color: #dc2626;
}

.restartButton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: #f5f5f5;
  color: #666;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.875rem;
  margin-top: 1rem;
  transition: all 0.2s ease;
}

.restartButton:hover {
  background: #e5e5e5;
}

@media (prefers-color-scheme: dark) {
  .uploadProgress {
    border-color: rgba(0, 112, 243, 0.2);
    background: rgba(0, 112, 243, 0.05);
  }

  .fileIcon {
    background: rgba(0, 112, 243, 0.15);
    color: #3291ff;
  }

  .progressContainer {
    background: rgba(0, 112, 243, 0.15);
  }

  .uploadProgressHeader {
    color: #999;
  }

  .restartButton {
    background: #262626;
    color: #999;
  }

  .restartButton:hover {
    background: #333;
  }
}

.uploadArea {
  padding: 2rem;
  border: 2px dashed #ccc;
  border-radius: 8px;
  text-align: center;
  background: #fafafa;
  transition: all 0.2s ease;
  cursor: pointer;
  width: 100%;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
}

.uploadArea.withProgress {
  min-height: 320px;
  transition: min-height 0.3s ease-out;
}

.uploadArea.disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.uploadArea.disabled:hover {
  border-color: #ccc;
  background: #fafafa;
}

.uploadText {
  margin: 0;
  color: #666;
}

.uploadText span {
  display: block;
  margin: 0.25rem 0;
  color: #999;
}

.fileInput {
  display: none;
}

.fileInputLabel {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: #0070f3;
  color: white;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.fileInputLabel:hover {
  background: #0060df;
}

.fileInputLabel.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: #999;
}

.fileInputLabel.disabled:hover {
  background: #999;
}

File uploads will now show a progress bar. However, the progression in the progress bar may not be noticeable. This is because the upload begins and completes almost instantly since we are using a local backend to handle the upload. You can use the throttling option in the “Network” tab of the developer tools in your browser. Setting the throttling level to “Good 3G“ or “Regular 3G“ (on Firefox) does the trick for me. The upload is slowed down now and the progress bar takes its time to fill up.

Here’s what it looks like:

Next.js image and video upload
The progress bar in action

2. Drag and Drop

Let’s add the ability to drag and drop a file into the page to initiate the upload. Achieving this is rather simple without the need for an external package. We use the native HTML onDragOver, onDragLeave, and onDrop events to enable this feature.

src/app/page.js should have the following code:

// old imports

export default function Home() {
  // old state definitions
  const [isDragging, setIsDragging] = useState(false);

  // old code
  // use a designated callback for the vanilla HTML <input> element
  const handleFileInput = (e) => {
    const file = e.target.files[0];
    handleUpload(file);
  };
 
  // new handlers for drag-and-drop
  const handleDragOver = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  };
 
  const handleDragLeave = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  };
 
  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
 
    const file = e.dataTransfer.files[0];
    handleUpload(file);
  };

  return (
    // attach the drag-and-drop handlers to the main, outermost div
    <div 
      className={styles.page}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
    > 
      // change the main element to incorporate drag-and-drop
      {isDragging && !isUploading && (
        <div className={styles.dropZone}>
          <div className={styles.dropZoneContent}>
            Drop your file here
          </div>
        </div>
      )}
      <main className={styles.main}>
        <div className={styles.uploadArea}>
          <p className={styles.uploadText}>
            Drag and drop your file here<br />
            <span>or</span>
          </p>
          <label className={styles.fileInputLabel}>
            <input 
              type="file" 
              onChange={(e) => handleUpload(e.target.files[0])}
              className={styles.fileInput} 
            />
            Choose a file
          </label>

          // old code
    </div>
  );
}

We need to add some styling too to make the UI of the drag-and-drop look intuitive.

Add the following classes to src/app/page.module.css:

.dropZoneContent {
  padding: 2rem 4rem;
  background: white;
  border: 2px dashed #0070f3;
  border-radius: 8px;
  font-size: 1.25rem;
  color: #0070f3;
}

.dropZone {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 112, 243, 0.05);
  backdrop-filter: blur(2px);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

The page should look like this now:

Next.js image and video upload
Upload via drag-and-drop

3. Paste from clipboard

Let’s add a third method to upload files on the page - Pasting a file from the clipboard. Most modern browsers and operating systems support pasting files into a webpage using the paste shortcut (ctrl/cmd + v). But our webpage needs to have the JavaScript code to detect the paste and handle the file. Let’s add that code!

src/app/page.js should have the following code:

// old imports
import { useEffect, useState } from "react";

export default function Home() {
  // old state definitions

  // old code
  // attach an event listener for the "paste" event. capture and upload the file in this handler
  useEffect(() => {
    const handlePaste = (e) => {
      e.preventDefault();
      const items = e.clipboardData?.items;
      
      if (!items) return;

      for (const item of items) {
        if (item.kind === 'file') {
          const file = item.getAsFile();
          handleUpload(file);
          break;
        }
      }
    };

    window.addEventListener('paste', handlePaste);

    return () => {
      window.removeEventListener('paste', handlePaste);
    };
  }, []);

  return (
      // old code
      <main className={styles.main}>
        <div className={`${styles.uploadArea} ${isUploading ? styles.disabled : ''} ${(uploadProgress > 0 || uploadStatus) ? styles.withProgress : ''}`}>
          <p className={styles.uploadText}>
            Drag and drop your file here<br />
            <span>or</span>
          </p>        
          // add some text to let the user know they can paste files for uploading
          <p className={styles.uploadHint}>
            You can also paste files using Ctrl+V / Cmd+V
          </p>
          <label className={styles.fileInputLabel}>
        
            // old code
            
          </label>
        </div>
      </main>
      // old code
  );
}

Add the following class to src/app/page.module.css

.uploadHint {
  margin: 0.5rem 0;
  font-size: 0.9rem;
  color: #666;
  font-style: italic;
}

The webpage should now look like this, and pasting a copied file should successfully upload it.

Next.js image and video upload
The complete upload interface

Why this upload module is not efficient or scalable

We are currently storing files locally, but this won't work if our application becomes popular. We need a solution that can handle millions of files, terabytes of storage, and hundreds of requests per second. The problem is even bigger with videos since they are large files and take a long time to upload. If our users are from different parts of the world, we need to run our backend in multiple regions to ensure a good user experience. While a DIY approach is good for learning, it isn't practical for real-world applications.

Let's look at some common problems and explore solutions for them:

Limited File Storage on Servers

  • Files are stored on a file system, and they have limited disk space. Scaling up requires increasingly larger disks.
  • Local disks can only be attached to one server, preventing multiple application instances.
  • What we need is a globally distributed upload backend that can manage billions of files, terabytes of storage, and hundreds of requests per second.

High Latency with Large File Uploads

  • Large files like videos take longer to upload.
  • Users in different regions may experience high latencies when uploading to a single region.
  • We can deploy and run the upload backend in multiple regions to solve this.

Centralization of the file store

  • In our DIY setup, the uploaded files are stored at a single, centralized location. If you have multiple instances of your upload API servers running, they must all upload to this same central store.
  • This becomes a bottleneck for performance, besides being a single point of failure.
  • We need the flexibility of being able to use multiple storage systems. Using a service like AWS S3 for the actual file storage makes it a lot more reliable.

File Delivery

  • After uploading, delivering files to users requires another application layer.
  • We need an application that sits in front of the storage, scales automatically, handles very high request rates, and has caching integrated in it so we don’t overburden our storage system.

Security Concerns

  • File uploads can be entry points for hackers to inject malicious files. This could compromise the entire cloud infrastructure.
  • We need to decouple the file upload, storage, and delivery systems from our main application containing the business logic.

ImageKit.io is a third-party service that can handle all your file upload and storage needs, solving each of the above problems. Let’s see how:

  • File Storage: ImageKit can handle billions of files, terabytes of storage, and hundreds of requests per second.
  • Latency: ImageKit offers a global upload API endpoint. Upload requests are routed to the nearest of six strategically located regions to minimize latency.
  • Decentralization: The upload endpoint is highly available and distributed so that the file upload does not become a point of failure for your application. Moreover, ImageKit allows you to use multiple storage services for the actual file storage.
  • Delivery: ImageKit provides a robust delivery API and supports high request rates with multiple layers of caching. It offers features such as intelligent image optimization, resizing, cropping, watermarking, file format conversion, video optimization, and streaming.
  • Security: With ImageKit, you offload file handling to an external service to protect your servers from attacks. This allows you to decouple upload, storage, and delivery from the rest of your application.

Let’s integrate ImageKit into our upload module.

Set up direct uploads from browser to ImageKit

Let's do everything again, but this time using ImageKit with a few lines of code. The overall functionality will remain unchanged. To ease the development, we will use ImageKit Next.js SDK. In this case, we will upload files to ImageKit directly from the browser.

With this integration, our frontend upload interface remains unchanged. Our backend upload API becomes completely redundant. The webpage will now send the file directly to ImageKit’s public upload endpoint, authenticated by your ImageKit API key.

Set up the ImageKit Next.js SDK

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

npm install --save imagekitio-next imagekit

Before adding ImageKit-related code to the project, let’s split our website into two different routes. One for native uploads that we have built so far, and another for ImageKit uploads that we are about to build. Create two new files src/app/native-upload/page.js, and src/app/imagekit-upload/page.js. Move everything currently in src/app/page.js into src/app/native-upload/page.js, and overwrite the src/app/page.js file with the following code. Don’t forget to update the import path of the CSS file to ../page.module.css.

'use client';
import styles from "./page.module.css";
import Link from 'next/link';

export default function Home() {
  return (
    <div className={styles.homePage}>
      <div className={styles.demoContainer}>
        <h1>Next.js upload file demo</h1>
        <Link href="/native-upload" className={styles.demoLink}>
          Native Next.js upload demo
        </Link>
        <Link href="/imagekit-upload" className={styles.demoLink}>
          ImageKit Next.js upload demo
        </Link>
      </div>
    </div>
  );
}

Also, add the following new styles to src/app/page.module.css

.demoContainer {
  background: white;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.demoContainer h1 {
  margin-bottom: 2rem;
  text-align: center;
  color: #000033;
}

.demoLink {
  display: block;
  padding: 1rem;
  margin: 1rem 0;
  border: 2px dashed #4285f4;
  border-radius: 4px;
  text-align: center;
  color: #4285f4;
  text-decoration: none;
  transition: all 0.3s ease;
}

.demoLink:hover {
  background: #4285f4;
  color: white;
}

.homePage {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

Initialize the Next.js SDK:

Before using the SDK, let's learn how to obtain the necessary 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 needed 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. We will see how to generate these in the following section.
💡
Note: Do not include your private key in any client-side code.

To integrate uploads to ImageKit in our application, we will need to define and add a bunch of new variables and functions. Let’s add them and understand why each change is necessary.

Overwrite the code inside src/app/imagekit-upload/page.js with the following:

'use client';

import { ImageKitProvider, IKUpload } from "imagekitio-next";
import styles from "../page.module.css";
import { useState, useEffect, useRef, useCallback } from "react";


export default function Home() {
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadStatus, setUploadStatus] = useState(null);
  const [uploadStats, setUploadStats] = useState({ loaded: 0, total: 0 });
  const [isUploading, setIsUploading] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const ikUploadRef = useRef(null)

  // This function fires a "change" event on the IKUpload's internal <input> element
  const uploadViaIkSdk = useCallback((files) => {
    if (ikUploadRef?.current) {
      const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
        window.HTMLInputElement.prototype,
        'files').set;
      nativeInputValueSetter.call(ikUploadRef.current, files);
      const changeEvent = new Event('change', { bubbles: true });
      ikUploadRef.current.dispatchEvent(changeEvent);
    }
  }, [ikUploadRef])

  // Call our backend API to generate short-lived authentication credentials using our ImageKit API key
  const authenticator = async () => {
    try {
      const response = await fetch("/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}`);
    }
  };

  // This function now calls 'uploadViaSdk' to trigger the "change" event on IKUpload
  useEffect(() => {
    const handlePaste = (e) => {
      e.preventDefault();
      const files = e.clipboardData?.files;
      
      if (!files || files.length === 0) return;

      uploadViaIkSdk(files)
    };

    window.addEventListener('paste', handlePaste);

    return () => {
      window.removeEventListener('paste', handlePaste);
    };
  }, []);

  // event handlers for IKUpload: onError, onProgress, and onSuccess
  const onError = (err) => {
    setUploadStatus('error');
    setUploadProgress(0);
    setIsUploading(false);
  };
  
  const onProgress = (e) => {
    if (e.lengthComputable) {
      const progress = (e.loaded / e.total) * 100;
      setUploadProgress(progress);
      setUploadStats({
        loaded: e.loaded,
        total: e.total
      });
    }
  };

  const onSuccess = (res) => {
    setIsUploading(false);
    setUploadStatus('success');
    setUploadProgress(100);
  };

  const resetUpload = () => {
    setUploadProgress(0);
    setUploadStatus(null);
    setIsUploading(false);
  };

  const formatBytes = (bytes) => {
    if (bytes === 0) return '0 KB';
    const k = 1024;
    return `${(bytes / k).toFixed(1)} KB`;
  };

  const handleDragOver = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  };

  const handleDragLeave = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  };

  // This function now calls 'uploadViaSdk' to trigger the "change" event on IKUpload
  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);

    uploadViaIkSdk(e.dataTransfer.files)
  };

  return (
    // The main <div> is wrapped under this provider to make ImageKit-related variables available
    <ImageKitProvider
      publicKey={process.env.NEXT_PUBLIC_PUBLIC_KEY}
      urlEndpoint={process.env.NEXT_PUBLIC_URL_ENDPOINT}
      authenticator={authenticator} 
    >
      {/* The <IKUpload> is internally simply an <input> file picker. But since we have our own three upload UI interfaces, ...
      ... we hide the <IKUpload> element, and just reference it to manually trigger a “change“ event on it. */}
      <IKUpload
        onError={onError}
        onSuccess={onSuccess}
        onUploadProgress={onProgress}
        // we use this ref to manually trigger the "change" event on this element
        ref={ikUploadRef}
        style={{visibility: 'hidden', height: 0, width: 0}} // hide the default button
      />
      <div 
        className={styles.page}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
      >
        {ikUploadRef && (
          <>
            {isDragging && !isUploading && (
              <div className={styles.dropZone}>
                <div className={styles.dropZoneContent}>
                  Drop your file here
                </div>
              </div>
            )}
            <main className={styles.main}>
              <div className={`${styles.uploadArea} ${isUploading ? styles.disabled : ''} ${(uploadProgress > 0 || uploadStatus) ? styles.withProgress : ''}`}>
                <p className={styles.uploadText}>
                  Drag and drop your file here<br />
                  <span>or</span>
                </p>
                <p className={styles.uploadHint}>
                  You can also paste files using Ctrl+V / Cmd+V
                </p>
                <label className={`${styles.fileInputLabel} ${isUploading ? styles.disabled : ''}`}>
                  <input
                    type="file" 
                    name="file"
                    className={styles.fileInput}
                    disabled={isUploading}
                    // This function now calls 'uploadViaSdk' to trigger the "change" event on IKUpload
                    onChange={(e) => {
                      e.stopPropagation()
                      e.preventDefault()
                      uploadViaIkSdk(e.target.files)
                    }}
                  />
                  Choose a file
                </label>
                
                {(uploadProgress > 0 || uploadStatus) && (
                  <div className={styles.uploadProgress}>
                    {uploadStatus ? (
                      <div className={`${styles.uploadStatus} ${styles[uploadStatus]}`}>
                        {uploadStatus === 'success' ? (
                          <>
                            <p>✓ Upload completed successfully!</p>
                            <button type="button" className={styles.restartButton} onClick={resetUpload}>
                              ↺ Upload another file
                            </button>
                          </>
                        ) : (
                          <>
                            <p>✕ Upload failed. Please try again.</p>
                            <button type="button" className={styles.restartButton} onClick={resetUpload}>
                              ↺ Try again
                            </button>
                          </>
                        )}
                      </div>
                    ) : (
                      <>
                        <div className={styles.uploadProgressHeader}>
                          <div className={styles.fileIcon}>📄</div>
                          <div>Uploading...</div>
                        </div>
                        <div className={styles.progressContainer}>
                          <div 
                            className={styles.progressBar} 
                            style={{ width: `${uploadProgress}%` }}
                          />
                        </div>
                        <div className={styles.progressStats}>
                          <span>{formatBytes(uploadStats.loaded)} / {formatBytes(uploadStats.total)}</span>
                          <span>{Math.round(uploadProgress)}%</span>
                        </div>
                      </>
                    )}
                  </div>
                )}
              </div>
            </main>
          </>
        )}
      </div>
    </ImageKitProvider>
  );
}

Create a file .env at the root of your project and add the following to it:

NEXT_PUBLIC_PUBLIC_KEY=<your_imagekit_public_key>
NEXT_PUBLIC_URL_ENDPOINT=<your_imagekit_url_endpoint>
PRIVATE_KEY=<your_imagekit_private_key>

Create a file src/app/api/auth/route.js and add the following to it:

import ImageKit from "imagekit";
import { NextResponse } from "next/server";

const imagekit = new ImageKit({
  publicKey: process.env.NEXT_PUBLIC_PUBLIC_KEY,
  privateKey: process.env.PRIVATE_KEY,
  urlEndpoint: process.env.NEXT_PUBLIC_URL_ENDPOINT,
});

export async function GET(request) {
  const authParams = imagekit.getAuthenticationParameters()
  return NextResponse.json(authParams);
}

Let’s describe all of the changes and the reason for making them:

  • The <div> in the return statement is now wrapped inside a <ImageKitProvider>, which sets up the context with required ImageKit-related variables.
  • The <IKUpload> is internally simply an <input> file picker. But since we have our own three upload UI interfaces, we hide the <IKUpload> element and just reference it to manually trigger a “change“ event on it.
  • ikUploadRef is used to reference and control the <IKUpload> element. This is required to manually trigger the “change“ event on this element.
  • The authenticator function calls a backend API (which we will write next) to generate authentication parameters for the file upload. This is required because you can authenticate to ImageKit only via your account private key, and we never store our private key in the frontend code.
  • The uploadViaIkSdk function fires a “change” event on the <IKUpload> element. The “change” event triggers the HTTP requests for authentication and finally, the actual upload. This is required because we have three different UI handlers to initiate uploads, and they all need a common interface to trigger the <IKUpload> element’s change handler.
  • onSuccess, onError, onProgress are callbacks to handle the respective events received from <IKUpload>
  • handleDrop now calls uploadViaIkSdk instead of the previous handleFileInput, which has been removed completely now.
  • The “paste“ event handler now calls uploadViaIkSdk instead of the previous handleFileInput, which has been removed completely.
  • The onChange event handler on the <input> element now also calls uploadViaIkSdk instead of handleFileInput

Here’s how the flow of our uploads works now:

Next.js image and video upload
Flow of upload
  1. When a file is sent for upload via any of the three methods, a “change“ event on the <IKUpload> element is fired.
  2. The “change“ event internally triggers two HTTP requests. One to our own application’s backend to generate the authentication parameters, and another to ImageKit’s public upload endpoint for the actual upload.
  3. The upload finishes successfully (or fails) and the corresponding callbacks that we sent to <IKUpload> are invoked.

Following these changes, the visual output on the webpage should remain exactly the same. The only change is in the upload destination. The files are now uploaded to your ImageKit account instead of your local project directory.

Validation

When uploading to ImageKit, we have the option of writing validation checks both for the frontend and the backend. Backend checks are much more secure than frontend checks since they are executed on your application server. Let’s see how to implement both in our upload module via ImageKit.

  1. Backend checks: The <IKUpload> component accepts a checks prop that has a string value. This string represents what server-side checks must be performed before the file is uploaded. Learn about upload checks in detail here. For example, "request.folder : "offsites/" will limit file uploads to the folder offsites and its sub-folders.
  2. Frontend checks: The <IKUpload> component accepts a function for the prop validateFile. Let’s utilize that to run a basic frontend file validation check.

The corresponding code changes in src/app/imagekit-upload/page.js for this are as follows:

// define two state variables to track frontend validation errors
const [isFileValid, setIsFileValid] = useState(true)
const [fileValidationError, setFileValidationError] = useState(undefined)

// code to run the validations
const validateFile = (file) => {
  if (file?.size > 5 * 1024 * 1024) {
    setIsFileValid(false)
    setFileValidationError("File must be less than 5MB in size.")
    return false
  }
  if (!file?.type?.startsWith("image/") && !file?.type?.startsWith("video/")) {
    setIsFileValid(false)
    setFileValidationError("File must be an image or a video.")
    return false
  }
  setIsFileValid(true)
  setFileValidationError(undefined)
  return true
}

// show an alert if validation fails
useEffect(() => {
  if (!isFileValid) {
    alert(fileValidationError ?? "File is not valid. Please make sure it is an image or a video, and less than 5MB in size.")
    setIsFileValid(true)
    setFileValidationError(undefined)
  }
}, [isFileValid, fileValidationError])

// Assign the `validateFile` and `checks` props to IKUpload
<IKUpload
  ...
  validateFile={validateFile}
  checks={'"request.folder":"offsites/"'}  ...
>

Bonus: Optimize, transform, and deliver the uploaded image/video

Now that you have safely uploaded your image or video to ImageKit, let’s see how ImageKit helps with the file’s delivery flow. ImageKit can do three (among many other) things when delivering your image or video to your frontend clients:

  • Optimize: ImageKit will convert the image or video into the format that has the lowest file size before delivering it.
  • Transform: You can perform a host of transformations on the image/video like resizing, cropping, rotating, and a lot more.
  • Cache: ImageKit caches all your assets on the CDN by default. Even the transformed and optimized versions of them!

Here’s some Next.js code to do all of the above things:

/**
* This fetches an image from "https://ik.imagekit.io/<your_imagekit_id>/<your_url_endpoint_identifier>/default-image.jpg",
* optimizes it to get the lowest possible file size, applies the resize and rotation transformations,
* caches it at the CDN, and finally delivers it to this webpage.
** /
<ImageKitProvider urlEndpoint="https://ik.imagekit.io/<your_imagekit_id>/<your_url_endpoint_identifier>/"
>
  <IKImage 
    path="/default-image.jpg"
    transformation={[
      {
        "height": "200",
        "width": "200",
      },
      {
        "rotation": "90"
      }
    ]}
    alt="Alt text"
  />
</ImageKitProvider>

Conclusion

In this tutorial, we've covered:

  • Building a file upload application in Next.js from scratch.
  • Implementing file type and size validations for secure uploads.
  • Transitioning to ImageKit.io for direct uploads from the browser, making our application more efficient and scalable.
  • Utilizing ImageKit's free upload API and Next.js SDK for a streamlined experience with minimal code.

You can check out the live demo on CodeSandbox and explore the code on Github.

]]>
<![CDATA[Crop and resize videos in React]]>https://imagekit.io/blog/crop-and-resize-videos-in-react/67bc629547ef7900014b7c89Tue, 25 Feb 2025 04:15:37 GMT

We want our websites to be responsive and provide a good browsing experience to users with different devices and screen sizes. To make this happen, we must also resize the media content, like videos, to fit seamlessly into the layout.

Most of the time, the videos that we display need to be resized to a smaller size and with a specific aspect ratio, like vertical for mobile devices (having an aspect ratio of 9:16), horizontal like different video players (16:9) or square (1:1). We often have to crop the videos to fit these dimensions and aspect ratios to ensure the main subject of the video is in focus and your web page is still optimal and engaging.

This blog will explore how to resize and crop videos directly in the browser (client-side) and discuss the challenges of this approach. We’ll then look at how to handle resizing and cropping using FFmpeg on the backend, addressing its complexities. Finally, we’ll introduce a more efficient solution using ImageKit, demonstrating how to integrate it into any React application in just minutes.

Cropping and resizing videos on the browser

Using the height and width property on HTML <video> element

A simple solution to resize the video that comes to mind is to use the height and width attributes in the <video> element. We can set these attributes based on the viewport dimensions and add CSS breakpoints to adjust in a responsive layout. For example, if we have a video with dimensions 2160 x 3840 and size 24.3 MB, and we want to display it in our application with a width of 270 CSS pixels, we can do it using the following example:

<video width="270" controls>
  <source src="https://ik.imagekit.io/<IMAGEKIT-ID>/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4" type="video/mp4" />
</video>

The browser will display the resized video. However, it must still download the large video file from the source URL. So, whether you display a larger or smaller-dimension video, the browser downloads the original video before rendering the resized video.

Moreover, setting the width and height of the video element adjusts the playback window rather than cropping or resizing the video. As a result, the video will scale to fit within the specified dimensions, preserving its original proportions. This outcome is not what we want if the goal is to resize and crop the video, such as converting it to a vertical aspect ratio dimension commonly seen in short video content. Simply resizing the player does not crop or resize the video itself.

Cropping and resizing videos on the server side

Videos should be transformed, optimised, and delivered from the server-side to be easily used in the <video> element for faster load times and reliable playback across various devices. By handling these transformations on the server, you can deliver videos in the optimal quality, size, and format tailored to varying network conditions and device requirements. This ensures that your frontend React application always displays the right videos based on the above needs.

FFmpeg can be used for video transformations like resizing, cropping, etc. It is a preferred tool for server-side video processing because it handles various video transformations easily.

Using FFmpeg for video transformations

FFmpeg is a powerful, open-source multimedia framework used for a wide range of video and audio processing tasks. We will now look at some examples of resizing, cropping, and transcoding videos using FFmpeg’s command line tool.

Resizing video:

Resizing a video is a common operation and can be easily done using FFmpeg. To resize a video to a resolution of 1280×720 pixels, we can use this command:

ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4

This command takes a video input.mp4, applies the scale filter to adjust the resolution, and outputs the resized video as output.mp4.

Cropping video:

We can also crop a video to extract a specific area. For example, to crop a video from the center, say a 640×480 section, we can use this command:

ffmpeg -i input.mp4 -vf "crop=640:480:(in_w-640)/2:(in_h-480)/2" output.mp4

This command calculates the center of the video by subtracting the crop width and height from the input video dimensions (in_w and in_h) and dividing by 2, resulting in a centered 640×480 crop, which is then saved as output.mp4.

Converting MP4 video to WebM:

Converting an MP4 video to the WebM format using the VP9 codec can reduce file size while keeping the quality at a similar level. Here's a simple FFmpeg command to do that:

ffmpeg -i input.mp4 -c:v libvpx-vp9 output.webm

The command above takes input.mp4 as the source video, and encodes it with the VP9 codec. The final output is saved as output.webm.

Videos generated using these FFmpeg commands can then be stored and served to any React application.

Using FFmpeg on the browser

For scenarios like resizing or cropping videos before upload, simple in-browser editing, or basic on-the-fly transformations, a popular option is ffmpeg.wasm, a WebAssembly (WASM) port of FFmpeg. It allows you to run many of the same FFmpeg commands you would on a server, but directly in the browser. However, because it’s running client-side, it can be quite resource-intensive—using significant memory and CPU—and might lead to sluggish performance on lower-end devices. Longer initialization and processing times also become a concern when dealing with larger files or complex commands.

If you need more efficient, real-time performance—especially for interactive editing scenarios where low latency is important—the WebCodecs API is a compelling alternative. It provides low-level, hardware-accelerated video encoding and decoding, giving direct access to raw video frames. This hardware acceleration can significantly speed up tasks like resizing or cropping while reducing CPU overhead compared to software-based solutions like ffmpeg.wasm. However, keep in mind that the WebCodecs API can be more complex to implement, given its lower-level approach and current browser support constraints.

Key components for transforming and delivering videos

Let us understand what is needed to deliver these transformed videos to the frontend:

  1. Storage: The main video and all its resized, cropped, or transformed versions need to be stored along with any video-related metadata associated with it that we may need. We should also be able to upload, manage, and delete those videos.
  2. Processing: A pipeline that would take the original input video, resize, crop, and transform it to meet the requirements of our application. Videos are bigger in size compared to images, so it takes more time to process and be ready. Keeping the transformations processed before adding them to your application is suitable.
  3. Delivery: Different devices support different video formats. Many support the webm format, which can deliver a similar quality of video at a smaller size compared to a format like mp4. Moreover, we need to ensure that the quality of the transformed video is suitable for viewing and not degraded.
  4. Caching: Once any video is resized or cropped, it is prudent to store and cache it so that the same version can be picked from the cache and delivered, saving you redundant processing costs. This also provides optimal performance to your React application as the videos will be available quickly.

We will need to set up a backend application that can transform the videos to implement all this. However, there is a lot more than cropping and resizing when setting up this logic.

Even though we didn't originally set out to address these issues, delivering the video in the optimal format, and size, and with the necessary transformations remains essential.

Thankfully, we don’t have to tackle this by building our own solution to resize and crop videos in our React application. ImageKit solves all these problems and much more with its easy-to-use Video API.

Cropping and resizing videos using ImageKit

ImageKit is a real-time media processing platform that helps you process, optimise and deliver media files at scale.

Getting started

  1. Create a free account.
  2. Upload a video to the Media Library.
  3. Crop and resize videos using simple URL-based transformation parameters.
  4. Configure the imagekitio-react SDK in your project and deliver optimised cropped and resized videos.

Upload a video to the Media library

There are several ways to upload files in the Media Library. It can be done programmatically using APIs and SDKs and also from the dashboard.

Once logged in to the dashboard, navigate to the media library and click the new button to select and upload a file. You can also drag and drop a file to upload to the media library.

You can download this video for the following demonstrations:

https://ik.imagekit.io/ikmedia/blog-feb-25/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4?tr=orig
Crop and resize videos in React
Upload video to the media library

Once the video is uploaded, you can copy and paste the URL into the browser. Your file is now accessible via the URL.

The structure of a typical URL is like this:

https://ik.imagekit.io/<IMAGEKIT-ID>/<PATH-TO-YOUR-FILE>

Crop and resize using URL transformation parameters

We will use the width (w), height (h), and aspect ratio (ar) transformations to generate square, horizontal, and vertical variations of this video.

💡
Note that video transformations take some time to be ready, as they are asynchronous by nature. Once they are ready, they are cached and instantly accessible at the requested URL.

ImageKit uses URL path or query parameters to apply these transformations to the video. A path transformation parameter starts with a tr: prefix, and the different transformation parameters are comma-separated.

Square:

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:ar-1-1,w-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4

The above transformation tr:ar-1-1,w-300 creates a resized video with aspect ratio 1:1 and width 300 px.

Square video (1:1)

Vertical:

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:ar-9-16,w-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4

The above transformation tr:ar-9-16,w-300 creates a resized video with aspect ratio 9:16 and width 300 px.

Vertical video (9:16)

Horizontal:

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:ar-16-9,w-800/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4

The above transformation tr:ar-16-9,w-800 creates a resized video with aspect ratio 16:9 and width 800 px.

Horizontal video (16:9)
💡
Note that if both width and height parameters are given then the aspect ratio transformation parameter is ignored.

We have now resized the video horizontally, but notice that quite a bit of the main subject in the video is getting cropped. We can use various crop and crop mode transformations for a suitable output.

Pad resize cropping with blurred background in the horizontal video:

Look at the following example that uses a padding resize cropping strategy. This does not clip the video and adds padding to the leftover space on the left and right sides to respect the requested dimensions.

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:h-450,w-800,cm-pad_resize,bg-blurred/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4
Horizontal video with pad resize cropping (16:9)

Thumbnail:

Another important aspect of video playback in any React application is providing a thumbnail. It improves user engagement and is essential to convey information to the user so that they can click and play it.

Using ImageKit, we can easily create thumbnails for videos using URL-based transformation on the same video file. We need to add a suffix /ik-thumbnail.jpg to the video URL.

https://ik.imagekit.io/<IMAGEKIT-ID>/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4/ik-thumbnail.jpg
Crop and resize videos in React
Thumbnail

Setting up the React application

Now that we’ve seen how URL transformations for videos work with ImageKit, let’s implement it in a React application.

We will use Create React App to quickly spin up our project:

npx create-react-app video-crop-resize-demo
cd video-crop-resize-demo

Install the ImageKit React SDK:

npm install imagekitio-react

To render the video in your react app, you’ll need your URL endpoint and the file’s path in the media library. You can get your URL-endpoint and ImageKit ID from the developer options section of the dashboard.

In src/App.js:

import "./App.css";
import { IKVideo } from "imagekitio-react";

function App() {
  const urlEndpoint = "https://ik.imagekit.io/<IMAGEKIT-ID>";

  return (
    <div className="App">
      <h1>Resize and Crop videos using ImageKit</h1>
      <IKVideo
        urlEndpoint={urlEndpoint}
        path="/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4"
        controls={true}
      />
    </div>
  );
}

export default App;

The above IKVideo component renders the following element in the DOM:

<video controls>
  <source src="https://ik.imagekit.io/<IMAGEKIT-ID>/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4" type="video/mp4">
</video>

Now we are able to render videos in our react application using ImageKit.

Resizing videos

We can resize the video using the parameters provided in the transformation prop to IKVideo.

We can specify the width of the output video using the following code snippet:

<IKVideo
  urlEndpoint={urlEndpoint}
  path="/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4"
  transformation={[
    {
      width: "300",
    },
  ]}
  controls={true}
/>

This renders the following element in the DOM:

<video controls>
  <source src="https://ik.imagekit.io/<IMAGEKIT-ID>/tr:w-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4" type="video/mp4">
</video>

Notice the transformation parameter added in the URL:

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:w-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4

When only the width is specified for the video, the height is adjusted accordingly to preserve the original video's aspect ratio.

Similarly, height of the video can be specified like this:

<IKVideo
  urlEndpoint={urlEndpoint}
  path="/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4"
  transformation={[
    {
      height: "300",
    },
  ]}
  controls={true}
/>

Which will render the video using the following URL:

https://ik.imagekit.io/<IMAGEKIT-ID>/tr:h-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4

Just like the width transformation, the aspect ratio is preserved in the video for the required height.

We can also control the aspect ratio of the video by specifying the proportions of the required width and height. For example:

<IKVideo
  urlEndpoint={urlEndpoint}
  path="/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4"
  transformation={[
    {
      ar: "9-16",
      width: "300",
    },
  ]}
  controls={true}
/>

This generates the following video element:

<video controls>
  <source src="https://ik.imagekit.io/<IMAGEKIT-ID>/tr:ar-9-16,w-300/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4" type="video/mp4">
</video>

Cropping videos

We can do the cm-pad_resize crop on the video using the SDK like this:

<IKVideo
  urlEndpoint={urlEndpoint}
  path="/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4"
  transformation={[
    {
      height: 450,
      width: 800,
      cropMode: "pad_resize",
      bg: "blurred",
    },
  ]}
  controls={true}
/>

This generates the following video element and URL:

<video controls>
  <source src="https://ik.imagekit.io/<IMAGEKIT-ID>/tr:h-450,w-800,cm-pad_resize,bg-blurred/pexels-jill-burrow-8953678-uhd_2160_3840_30fps.mp4" type="video/mp4">
</video>

Here’s a table of different crop and crop modes in ImageKit:

Crop / Crop Mode Strategy Transformation Behaviour
Pad resize crop cm-pad_resize Resizes the video to the exact width and height requested, maintains the original aspect ratio, and pads leftover space to avoid cropping or distortion.
Forced crop c-force Forces the video to match the exact width and height requested, ignoring the original aspect ratio. This can cause distortion (stretching or squeezing).
Max-size crop c-at_max Ensures the video fits within the specified width and height while maintaining the aspect ratio. No cropping or distortion; one dimension may scale down.
Min-size crop c-at_least Ensures the video dimensions are equal to or larger than the specified width and height while maintaining the aspect ratio. One dimension will match the requested size, and the other will be scaled up proportionally (no cropping).
Maintain ratio crop c-maintain_ratio This is the default strategy. If no crop is specified, this gets applied. Resizes the video to the requested dimensions while maintaining the aspect ratio and then crops extra parts to achieve the exact width and height.
Extract crop cm-extract Extracts a region of the requested width and height directly from the original video, maintaining the aspect ratio. Unlike c-maintain_ratio, no resizing is performed—only the requested portion is extracted.

Conclusion

  • Setting height and widthattributes on the video tag only adjusts the display size, and doesn’t actually resize or crop the video file.
  • Server-side implementations for video transformations solve the problem but involve setting up transformation pipelines, storage, and caching, which is complex to implement.
  • ImageKit offers an out-of-the-box solution that handles video storage, transformations (crop, resize, etc.), and optimized delivery with simple URL transformation parameters.
  • The React SDK makes video embedding and transformation easy, reducing both development effort and page load times.
  • Using the React SDK, you can also apply transformations like text and image overlays on videos and upload files to the media library.

Further reading:

]]>
<![CDATA[React video optimization]]>https://imagekit.io/blog/react-video-optimization/67b64c4a47ef7900014b796aMon, 24 Feb 2025 11:44:34 GMT

Videos are incredibly engaging. Over the last five years, they’ve practically taken over social media: Instagram, TikTok, LinkedIn, Twitter... you name it. Marketers and creators are racing to make video content.

But here’s the thing: making a great video is just the start. You still have to get people to actually watch it on the web, and that’s where things can get tricky. If your video delivery isn’t optimized, it can greatly impact the user experience of your website or app.

Hosting your videos on platforms like YouTube or Vimeo is perfectly fine. However, if you want total control over the user experience and your branding, you’ll need to host and stream the content yourself. And that’s exactly why optimizing videos for the web is so important.

This blog is for developers who want to stream optimized videos in React applications. We’ll cover why video optimization matters, show you the essential tools for encoding and compression, and walk through how to set up smooth streaming so your users get a seamless viewing experience.

What is Video Optimization?

Video optimization is the process of compressing and converting videos to reduce their file size while maintaining the best possible quality. This process ensures that videos load quickly and play smoothly on all devices. There are various ways to optimize videos:

  • Lazy loading - Loading videos only when the user plays them.
  • Video resizing - Changing the dimensions of a video on the server side to fit the application layout on the front end.
  • Video format selection - Choosing the right output video format based on the video content and device.
  • Video compression - Reducing the video file size while maintaining visual quality using lossy compression techniques.
  • Adaptive bitrate streaming - Delivering videos at different quality levels based on the user's network speed.


You can implement some optimizations by yourself but using a specialized video CDN (content delivery network) like ImageKit lets you build a video application without worrying about the complexities of encoding, storage, caching, and delivery.

ℹ️

Setting up the App

Let’s go through an example project for a more hands-on experience on implementing these optimizations without using any third-party services and then compare those solutions with ImageKit.

If you already have a React project set up, you can follow along. If not, run the command below.

npm create vite@latest my-app -- --template react

This’ll set up a project with React using the Vite build tool (which is one of the recommended ways to use React now).

You can specify react-ts instead of react if you want to use a template that has React with TypeScript.

Switch to the newly created app directory and run npm install to install the required dependencies. Once that’s done, you can use the npm run dev command to run the template locally.

React video optimization
Initial Screen

If you created a new app, your directory would look like this:

.
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── node_modules
├── public
│   └── vite.svg
├── src
│   ├── App.css
│   ├── App.jsx
│   ├── assets
│   ├── index.css
│   └── main.jsx
└── vite.config.js
Directory Tree

We’ll start by using the <video> tag to embed a video on the webpage.

Before that, let’s clear the default styles from App.css & index.css.

In your index.css file, paste this:

:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: 6rem;
  min-height: 100vh;
}

Clear the the App.jsx file & paste this snippet instead to add a video:

import "./App.css";

function App() {
  return (
    <>
      <video height="452" width="768" controls playsInline>
        <source src="https://ik.imagekit.io/ikmedia/example_video.mp4" />
        Your browser does not support the video tag...
      </video>
    </>
  );
}

export default App;

Let’s go through the different attributes we used:

  • controls:  adds native video playback controls (e.g., play, skip, volume adjustment).
  • playsinline: prevents videos from playing in full-screen mode on iOS devices.

We’re using an example video link from ImageKit as our source, but you can also use other links or a file stored in the assets or public directory.

The page should look like this now:

React video optimization
Adding the video tag

Now that we’ve setup our app, let’s review different ways to optimize the performance of our video content.

Lazy loading

Browsers load a small portion of the video before you even hit play. You can either see this in the progress bar of your video player (if it supports showing the duration of pre-loaded content) or check this in the network tab of your browser’s developer tools.

React video optimization
Browser Pre-loading

While pre-loading videos might be ideal in some cases, it impacts your website’s performance and consumes bandwidth unnecessarily if the user doesn’t even want to play a specific video. In some cases, the browser may fetch the entire video.

To prevent this, you can set the preload attribute for the video element to none.

<video height="452" width="768" controls playsInline preload="none">
  <source src="https://ik.imagekit.io/ikmedia/example_video.mp4" />
  Your browser does not support the video tag...
</video>
ℹ️
For an even improved experience, you can use react-lazyload that’ll only mount components when they’re visible in the viewport.

When the page reloads, you’ll notice that the video thumbnail has disappeared because the browser didn’t pre-load the video or its metadata.

React video optimization
No thumbnai with preload="none"

To show a thumbnail, you can use the poster attribute with any image of your choice. You can either capture a screenshot or get a thumbnail at any timestamp using ffmpeg like this:

ffmpeg -i input.mp4 -ss 00:00:5 -vframes 1 thumbnail.jpg

  • -i input.mp4: specifies the input video file named input.mp4.
  • -ss 00:00:5: seeks to 5 seconds into the video.
  • -vframes 1: extracts only one frame.
  • thumbnail.jpg: Name of the output image file.
<video
  height="452"
  width="768"
  controls
  playsInline
  preload="none"
  poster="./thumbnail.png"
>
  <source src="https://ik.imagekit.io/ikmedia/example_video.mp4" />
  Your browser does not support the video tag...
</video>

Instead of the browser pre-loading the video to show a thumbnail, using a thumbnail image leads to much better performance.

ℹ️
With ImageKit, you can generate an optimized thumbnail by appending ik-thumbnail.jpg to the video URL:
https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg

To capture a thumbnail from a specific timestamp, use the so (start-offset) parameter:
https://ik.imagekit.io/ikmedia/example_video.mp4/ik-thumbnail.jpg?tr=so-5

Here, so-5 extracts a frame 5 seconds into the video instead of the default first frame.

Video resizing

Using videos with lower resolutions helps save a lot of bandwidth for mobile users. You can use a tool like ffmpeg to manually convert your videos to lower resolution.

Download the example MP4 video from https://ik.imagekit.io/ikmedia/example_video.mp4

You can check the video resolution using either your file explorer or running ffmpeg -i input.mp4, where input.mp4 is the name of your video file.

To reduce the resolution to a specific dimension while preserving the aspect ratio:

ffmpeg -i input.mp4 -vf scale=-1:480 -c:a copy output-480p.mp4

  • -vf scale=-1:480: applies a video filter (-vf) to scale the video.
  • scale=-1:480: Resizes the video to a height of 480p while maintaining the original aspect ratio.
  • -c:a copy: copies the audio stream without re-encoding it (faster and preserves original audio quality).
ℹ️
Note: Some video codecs don’t work if the height and width of the video isn’t exactly divisible by 2.

If you face this issue, you can add some padding to round off the dimension to the nearest even number by using the vf flag like this: -vf "scale=-1:480,pad=ceil(iw/2)*2:ih". Here:
- iw: is the input width after scaling.
- ceil(iw/2)*2: rounds up the width to the nearest even number to ensure it is divisible by 2.
- ih: keeps the height unchanged.

If you’re using ImageKit, you can use the height (h) transformation for the same result.
https://ik.imagekit.io/ikmedia/example_video.mp4?tr=h-480

h-480 resizes the video to have a height of 480px while maintaining the width as per the original aspect ratio.

<video
  height="452"
  width="768"
  controls
  playsInline
  preload="metadata"
  poster="./thumbnail.png"
>
  <!-- Mobile devices: Small screens (e.g., phones) -->
  <source
    src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=h-240"
    media="(max-width: 480px)"
  />
  
  <!-- Tablets and larger mobile devices -->
  <source
    src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=h-480p"
    media="(max-width: 768px)"
  />
  
  <!-- Small laptops and large tablets -->
  <source
    src="https://ik.imagekit.io/ikmedia/example_video.mp4?tr=h-720"
    media="(max-width: 1024px)"
  />

  <!-- Default fallback (highest quality available) -->
  <source src="https://ik.imagekit.io/ikmedia/example_video.mp4" />

  Your browser does not support the video tag...
</video>

Video format selection

WebM is a newer video format that provides high-quality video playback with smaller file sizes and faster loading times. However, MP4 is widely compatible across all browsers and devices. You should encode your videos in WebM for better performance and provide MP4 as a fallback for optimal performance & compatibility.

We’ll see how we can add this fallback once we understand how to convert MP4 to WebM. To convert an MP4 video to WebM, run

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -c:a libopus output.webm

  • -c:v libvpx-vp9: Sets the video codec to VP9, which is commonly used for WebM.
  • -crf 30: Adjusts the quality (lower value = better quality). A typical range is 20–40.
  • -c:a libopus: Sets the audio codec to Opus, which is recommended for WebM files.
  • output.webm: Specifies the name of the output WebM file.
ℹ️
If you want to learn more about both formats and other codecs, head over to Exploring WebM vs MP4.

You can use the videos as shown in the snippet below. Remember to keep the WebM video above the MP4 one so that the browser checks for the WebM video first and only uses the MP4 video as a fallback.

<video
  height="452"
  width="768"
  controls
  playsInline
  preload="metadata"
  poster="./thumbnail.png"
>
  <source src="./video.webm" />
  <source src="./video.mp4" />
  Your browser does not support the video tag...
</video>

ImageKit automatically selects the best format for the user depending on browser support. You don’t need to add any additional parameters or put multiple URLs like this using source tag. Just upload an MP4 video to ImageKit, and it’ll be delivered as WebM on the same URL if that’s the best format for a user.

For example, even though the original video uploaded (https://ik.imagekit.io/ikmedia/example_video.mp4?tr=orig-true) was in the MP4 format, I got delivered the more efficient WebM format in my Chrome browser on Mac. Some older browsers don’t support WebM, so providing MP4 as a fallback is essential.

ℹ️
You can check WebM compatibility for different platforms here: WebM video format | Can I use.
React video optimization
Automatic Format Optimization

ℹ️
You can still use the format (f) query parameter for more control over the video format. For example, to deliver the video in MP4 format.
https://ik.imagekit.io/ikmedia/example_video.mp4?f=mp4

Adaptive Bitrate Streaming (ABS)

One of the biggest challenges in delivering video content online is ensuring a smooth and uninterrupted viewing experience for all users, regardless of their internet speed or device capabilities. Viewers with slow or unstable connections often face buffering, lag, and poor video quality, while those with high-speed connections may not be getting the best possible resolution due to static video delivery methods.

Adaptive Bitrate Streaming (ABS) ensures a smooth and high-quality viewing experience by dynamically adjusting the video quality based on the viewer's internet speed and device capabilities. This reduces buffering, minimizes interruptions, and optimizes bandwidth usage, delivering the best possible video quality for each user while maintaining efficiency.

ABS works by encoding a video into multiple quality levels or bitrates and splitting it into small chunks. As the video streams, the player's client dynamically selects the best quality chunk based on the viewer's current network conditions and device capabilities. If the connection is strong, higher-quality chunks are streamed; if it weakens, the player seamlessly switches to lower-quality chunks to avoid buffering.

There are 2 different protocols for using ABS: HLS (HTTP Live Streaming) & DASH (Dynamic Adaptive Streaming over HTTP). You can learn more about them here: HLS Vs. DASH: Which Streaming Protocol is Right for You?.

If you’re not using any external service like ImageKit for ABS streaming, you’ll need to process your videos beforehand to use ABS.

To generate an HLS playlist that splits the video into multiple segments and supports different resolutions (360p, 480p, 720p, 1080p):

ffmpeg -i input.mp4 \
  -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
  -c:v h264 -profile:v main -c:a aac -ar 48000 \
  -filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease -b:a:0 96k \
  -filter:v:1 scale=w=842:h=480:force_original_aspect_ratio=decrease -b:a:1 128k \
  -filter:v:2 scale=w=1280:h=720:force_original_aspect_ratio=decrease -b:a:2 128k \
  -filter:v:3 scale=w=1920:h=1080:force_original_aspect_ratio=decrease -b:a:3 192k \
  -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3" \
  -hls_time 4 \
  -master_pl_name master.m3u8 \
  -hls_segment_filename output/stream_%v_%03d.ts output/stream_%v.m3u8
ℹ️
Remember to create an output directory (output in our case) if not already present to prevent ffmpeg from erroring out in case the directory isn’t present for HLS segments.

Let’s go through the options used in this command:

  • -map 0:v:0 -map 0:a:0 ... - maps the first video (0:v:0) and first audio (0:a:0) streams 4 times for different variants.
  • -c:v h264 : specifies H.264 as the video codec.
  • -profile:v main : uses the "Main" profile of H.264 (better compression and quality).
  • -c:a aac : specifies AAC as the audio codec.
  • -filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease: rescales the first video stream to 640x360 while preserving the aspect ratio.
  • -b:a:0 96k : sets the audio bitrate for the first variant to 64 Kbps.
  • -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3" : groups audio and video streams for different bitrate variants.
  • -hls_time 4 : splits the video into 4-second segments.
  • -master_pl_name master.m3u8` : generates a master playlist file (master.m3u8) that lists all available stream variants.
  • -hls_segment_filename output/stream_%v_%03d.ts output/stream_%v.m3u8 : specifies the naming pattern for HLS segments.

You can see the different bitrate streams listed in the master playlist (output/master.m3u8) like this:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=105600,RESOLUTION=640x360,CODECS="avc1.4d401e,mp4a.40.2"
stream_0.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=842x474,CODECS="avc1.4d401e,mp4a.40.2"
stream_1.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
stream_2.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=211200,RESOLUTION=1920x1080,CODECS="avc1.4d4028,mp4a.40.2"
stream_3.m3u8

The playlist for each bitrate stream (eg. output/stream_0.m3u8) shows the segmented video streams.

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:2
#EXTINF:10.000000,
stream_1_002.ts
#EXTINF:10.000000,
stream_1_003.ts
#EXTINF:10.000000,
stream_1_004.ts
#EXTINF:10.000000,
stream_1_005.ts
#EXTINF:10.000000,
stream_1_006.ts
#EXT-X-ENDLIST

ℹ️
To learn more about the HLS playlist format, see Creating a Multivariant Playlist | Apple Developer Documentation

Once you’ve created the playlist and video segments, you can host them on your server to use ABS.

If you don’t want the hassle of generating and hosting multiple bitrate variants for optimal ABS streaming, you can use ImageKit’s ABS capabilities. You just need to specify the required resolutions like in the following URL:

https://ik.imagekit.io/ikmedia/example_video.mp4/ik-master.m3u8?tr=sr-360_480_720_1080

ℹ️
See the list of resolutions supported by ImageKit here: Adaptive Bitrate Streaming

Now that we have a link to our HLS manifest, let’s update our video player to support ABS.

The HTML <video> tag works well, but it doesn’t support using ABS. We’ll use the popular video.js library for ABS support.

Let’s install the required dependencies:

npm install video.js@7.18.1 videojs-contrib-quality-levels@2.1.0 videojs-http-source-selector@1.1.6

Using the specific version 7.18.1 of video.js is recommended to ensure compatibility with the plugins used.
  • videojs-contrib-quality-levels: provides an interface for accessing and managing available quality levels in a video.js player, useful for monitoring or customizing ABS playback.
  • videojs-http-source-selector: uses videojs-contrib-quality-levels to offer manual user-selectable level selection options for adaptive HTTP streams.

Create a new directory components under src. Add a file named VideoPlayer.jsx to it with the code below:

import { useEffect, useRef } from "react";
import videojs from "video.js";
import "video.js/dist/video-js.css";

import "videojs-contrib-quality-levels";
import "videojs-http-source-selector";

export const VideoPlayer = (props) => {
  const placeholderRef = useRef(null);
  const playerRef = useRef(null);
  const { options, onReady } = props;

  useEffect(() => {
    // Make sure Video.js player is only initialized once
    if (!playerRef.current) {
      const placeholderEl = placeholderRef.current;
      const videoElement = placeholderEl.appendChild(
        document.createElement("video-js")
      );

      const player = videojs(videoElement, options, () => {
        player.log("player is ready");
        onReady && onReady(player);
      });

      playerRef.current = player;

      // Binding to the source selector plugin in Video.js
      player.httpSourceSelector();

      // You can update player in the `else` block here, for example:
    } else {
      const player = playerRef.current;
      player.autoplay(options.autoplay);
      player.src(options.sources);
    }
  }, [options, onReady]);

  // Dispose the Video.js player when the functional component unmounts
  useEffect(() => {
    const player = playerRef.current;

    return () => {
      if (player) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, [playerRef]);

  return <div ref={placeholderRef}></div>;
};

export default VideoPlayer;

Replace the contents of App.jsx with

import "./App.css";
import VideoPlayer from "./components/VideoPlayer";

function App() {
  const videoJsOptionsM3u8 = {
    controls: true,
    autoplay: false,
    width: 768,
    sources: [
      {
        src: "https://ik.imagekit.io/ikmedia/example_video.mp4/ik-master.m3u8?tr=sr-360_480_720_1080",
        type: "application/x-mpegURL",
      },
    ],
    plugins: {
      httpSourceSelector: {
        default: "auto",
      },
    },
  };

  return (
    <>
      <VideoPlayer options={videoJsOptionsM3u8} />
    </>
  );
}

export default App;

You can learn more about VideoJS options here: Video.js Options Reference.

After making all the changes, you’ll get a video player that auto-selects the best stream provided by ImageKit & also provides different options for resolutions to the user.

React video optimization
ABS-compatible video player

Conclusion

Optimizing video content in React ensures a smooth user experience, better performance, and reduced bandwidth costs.

You can significantly improve how videos are delivered and consumed on your website by applying techniques such as preloading control, using multiple resolutions, providing multiple formats, and ABS.

Tools like ImageKit simplify this process further by automating transformations and delivering optimized videos based on user context without the hassle of doing things manually.

]]>
<![CDATA[How we quadrupled our traffic to 625K monthly page views]]>https://imagekit.io/blog/4x-organic-traffic/67b57f7a47ef7900014b76bdThu, 20 Feb 2025 08:37:16 GMT

Our organic website traffic skyrocketed, growing 4x to 625,000 monthly page views in less than two months. The best part? This hockey stick growth hasn’t slowed down—it looks like we’ll easily surpass 1 million page views per month by the next quarter. 🚀

How we quadrupled our traffic to 625K monthly page views
A screenshot of our GA showing weekly page views - organic, excluding dashboard, login, etc.

In this blog post, I’ll share what we did, why we did it, and a bit of the backstory.

Hint - We didn’t achieve this growth by writing tons of blog posts or spending money on ads.

The Problem: A slowdown in website traffic growth

We noticed a slowdown in website traffic growth and needed a way to fix it quickly. But not just any traffic—we needed a disproportionately high amount of relevant visitors who could turn into potential customers.

Why Not Blog Posts?

We’ve been writing blog posts for a long time, but ranking at the top keeps getting harder. No matter how good our content is, Google’s algorithm changes constantly, and sometimes, a random 4-year-old Reddit post outranks even the best-written articles. So, relying on blog content wasn’t a viable option.

The Strategy: Build free, useful tools

Instead of focusing on content, we decided to build a few free tools that our potential customers could use immediately, with no ads or paywalls.

After analyzing traffic volume and keyword difficulty, we settled on these three tools:

  1. Online image format converter - Potential traffic: 6.6M globally, 985K in the US.
  2. Online image compression tools – Potential traffic: 1.6M globally, 44K in the US.
  3. Free image and video hosting – Potential traffic: 74K globally, 33K in the US.

From here, we executed fast—and the results were game-changing.

Ahrefs screenshots of traffic potential

How we quadrupled our traffic to 625K monthly page views
Format converter tools
How we quadrupled our traffic to 625K monthly page views
Image compression tools
How we quadrupled our traffic to 625K monthly page views
Free media hosting

We prioritized the online format converter and image compression tool first because they were easy to implement. Our goal was to offer these tools for free without increasing our costs. To achieve this, we developed browser-only solutions where all processing happens locally on the user's device. This ensures fast performance while keeping files completely private, as they never leave the user's device.

Shortly after launch, we began ranking in the top 5-6 positions for these keywords. However, despite Ahrefs indicating low keyword difficulty, we struggled to reach the top spots. It took us some time to realize that both tools faced fierce competition, making it harder to secure the top rankings.

So what now?

Realizing the intense competition for the first two tools, we quickly moved to the third one—free image and video hosting.

While its traffic potential was lower, it was highly relevant to our offering. ImageKit provides a full-fledged digital asset management solution, so the idea of giving marketers and designers a lightweight personal media library resonated with us.

We implemented and launched the tool within a week. It was designed to be simple: users can upload an image or video, generate shareable public links, and even get a CDN-powered link—all without needing to create an account. Just open the page, and it works. We also created a short demo video to showcase its functionality.

Within 10 days, we started ranking in the top 3-4 positions for keywords like "image to URL," "video to URL," and "free image hosting."

A few days later, we launched on ProductHunt, where we ranked 5th, and on Peerlist, where we secured 2nd place. While nothing extraordinary came from these launches, we aimed to maximize visibility. Ultimately, Google search drove the most traffic to the tool.

Despite its low traffic potential, the free media hosting tool ended up driving a significant share of clicks because we ranked at the top. It turned out to be the most valuable tool in terms of both traffic generation and attracting our ideal potential customers for our Digital Asset Management (DAM) product.

Good! Let's talk about numbers now

We were getting a lot of page views and wanted to verify if it was worth the effort and if we should continue or not. To make an informed decision, we focused on a few key metrics:

  1. SERP rankings - Seeing how we rank on Google, for how many keywords, etc.
  2. Traffic growth – Tracking total page views and unique users to measure overall reach.
  3. Basic engagement metrics – Looking at engagement time, page views per user, and how long visitors interacted with our site.
  4. Traffic to high-intent pages – Monitoring visits to our registration and pricing plan pages to see if users were moving toward conversion.
  5. Brand queries – Checking how often people searched for "ImageKit" on Google, which indicated growing brand awareness.
  6. Actual signups – The most critical metric is how many users were signing up for our product as a result of this increased traffic.

SERP ranking

We started ranking in the top 3 positions in the US for 173 new keywords within just two months.

How we quadrupled our traffic to 625K monthly page views

We even managed to rank in the top 3 positions for some highly competitive keywords, which was unexpected.

How we quadrupled our traffic to 625K monthly page views
How we quadrupled our traffic to 625K monthly page views
Ranking at the top for the image to url
How we quadrupled our traffic to 625K monthly page views
Video to url
How we quadrupled our traffic to 625K monthly page views
Free image hosting

Beyond ranking at the top, we also gained:

  1. 97 featured snippets
  2. 65 AI overview mentions
  3. 1113 people also ask mentions

These placements significantly boosted our visibility and organic reach.

Website traffic

Traffic has increased almost 4x, reaching 156,000 visits per week—and it's still growing.

This excludes traffic from login pages, the dashboard, and our reusable footer iframe. We're only counting direct and organic traffic from Google, Bing, and other search engines.

How we quadrupled our traffic to 625K monthly page views
A screenshot of our GA showing weekly page views - excluding dashboard, login etc.

Unique users

Unique visitors have grown 3.5x in the past two months, now reaching nearly 140,000 new users every month—and the numbers keep rising.

If a public link to an asset is shared on Reddit and the post goes viral, our tools capture a share of that traffic.

How we quadrupled our traffic to 625K monthly page views

Page views per user

Page views per user is a strong indicator of how interested someone is in your product—the higher, the better. On our tools pages, engagement was notably high:

  • Free image and video hosting tools - 3.95
  • Format converter – 5.33 (likely because we have separate pages for different format conversions)
  • Blog – 1.25

Overall, these numbers look pretty good.

Engagement metrics

We analyzed Google Analytics' time spent on the page and engagement rate metrics. Unlike page views per user, a higher time spent on the page doesn’t always indicate better engagement. Here’s what we found:

  • Format conversion pages – 1 min avg time, 86% engagement
  • Image and video hosting – 34 to 1min avg time, 91% engagement
  • Blogs – 42 sec avg time, 80% engagement

These numbers make sense. File uploads are quick, and users copy the public URL and leave in under a minute. Format conversion pages take longer, likely because users download files, which explains the higher time spent on the page.

Traffic on the pricing page

If someone visits the pricing page, it’s a strong signal that they’ve learned something about the product. Traffic to the pricing page increased by roughly 33%.

How we quadrupled our traffic to 625K monthly page views

Brand queries

We saw a noticeable uptick in brand searches for ImageKit on Google. However, it's tricky to attribute this entirely to the viral tools, as we also collaborated with a few YouTube influencers around the same time.

To stay on the safe side, we’d attribute this increase more to YouTube, as there's a clear correlation between the video launch dates and the rise in brand queries.

How we quadrupled our traffic to 625K monthly page views

Signup

January 2025 saw our highest number of signups so far. We also observed that the tools-to-signup conversion rate was significantly better than the blog-to-signup conversion rate:

  • Tools – 1.49%
  • Blog – 0.53%

This reinforces the idea that useful tools drive more engaged and conversion-ready users compared to blog content.

How we quadrupled our traffic to 625K monthly page views
How we quadrupled our traffic to 625K monthly page views

The 0.53% blog-to-signup conversion rate is an average across all blog posts, but not every post performs the same. Bottom-of-the-funnel content tends to convert at a higher rate, even if it attracts a smaller audience.

Additionally, it's tricky to fully attribute the overall increase in signups to our tools alone, as this spike coincided with the launch of a few YouTube videos promoting our product.

Way forward

We have more useful tools in mind that marketers, designers, and developers can benefit from. Some ideas we’re exploring:

  • Browser-only background removal – While there are existing options, most don’t offer decent output quality. Background removal is a complex problem—high-quality results require downloading large AI models in the browser. We plan to launch this with a trimmed-down version of our AI model (used in our backend) to deliver high-quality background removal without heavy processing.
  • Online video compression, resizing, and basic editing tools – Again, browser-only for speed and privacy.

A little backstory

The idea of creating useful, viral tools was first discussed back in June 2020, but for some reason, we never pursued it. Honestly, I don’t even remember why!

How we quadrupled our traffic to 625K monthly page views
How we quadrupled our traffic to 625K monthly page views

Conclusion

  1. Organic traffic soared in under 2 months, climbing to 625,000 monthly page views and on track to hit 1 million.
  2. Ranked in the top 3–4 positions for keywords like “image to url” and “video to url” soon after launch.
  3. Claimed 173 new top-3 rankings in under 2 months, plus 97 featured snippets, 65 AI overview mentions, and 1113 people also ask mentions.
  4. Unique visitors have grown 3.5× in the past two months, now reaching nearly 140,000 new users per month—and the numbers keep rising.
  5. Tools to signup conversion is 1.49%, almost triple the 0.53% from blog pages  - January 2025 saw the highest signups to date, indicating relevant, high-quality leads.
  6. Building useful, share-worthy tools drove more effective organic growth than writing additional blog posts.
  7. If you have noticed, most of our tools do heavy work in the browser. It serves two purposes. First, it doesn't cost us anything in terms of processing on servers. Second, better privacy for users. Their files never leave their computer.
]]>
<![CDATA[How Apollo 24|7 boosted performance & reduced costs with ImageKit]]>https://imagekit.io/blog/apollo247-imagekit-case-study/676e327747ef7900014b6e4fMon, 13 Jan 2025 06:00:50 GMTAbout Apollo 24|7How Apollo 24|7 boosted performance & reduced costs with ImageKit

Apollo 24|7 is India's largest omni-channel digital healthcare platform. It blends Apollo Hospitals' clinical expertise with advanced technology to make healthcare accessible to all.

Offering services like doctor consultations, online pharmacy, and diagnostic tests, Apollo 24|7 ensures fast, reliable delivery across 19,000+ pin codes. Key features include 15-minute video consultations, quick medicine delivery in 19 minutes, and home sample collection. Users enjoy exclusive health perks and priority doctor access with the CIRCLE membership program.

Apollo 24|7 is dedicated to transforming healthcare in India, ensuring quality and convenience for millions.

This case study explores how Apollo 24|7 partnered with ImageKit to scale media delivery, enhance user experience, and drive operational efficiency.

Challenges faced by Apollo 24|7

Before partnering with ImageKit, Apollo 24|7 relied on a global CDN solution for its media delivery processes on its website and apps, which presented several challenges with business scalability:

  • Escalating costs: The CDN's pricing model, which included charges for usage traffic and midgress bandwidth, became increasingly concerning as Apollo scaled. Rising subscription fees and the need to purchase add-ons for essential features like geographic restrictions further drove up costs, making the setup unsustainable.
  • Limited analytics: As Apollo’s usage increased, they wanted to get insights regarding their bandwidth consumption patterns but the dashboard analytics weren’t of any use.
  • Need for better support: While the CDN solution partner offered 24x7 L1 support across time zones, Apollo's developers often required specialized technical expertise to address their media optimization queries. This resulted in prolonged delays, with the team usually waiting hours to resolve their critical issues effectively.
  • Multiple system, no unified solution: Apollo 24|7 used AWS S3 for media storage and the global CDN for media delivery, adding unnecessary complexity as the business scaled. This fragmented approach limited their ability to maximize the potential of their tools, leading to inefficiencies and operational challenges.

While the team explored alternative solutions, they faced a significant hurdle—the existing setup had been deeply integrated into their website and app over several years. Migrating from it, especially in older app versions, was complex and had to be executed seamlessly to avoid downtime.

ImageKit's solution

ImageKit is a trusted partner for leading global brands across industries. Apollo 24|7 discovered ImageKit’s innovative URL-based approach to image optimization and transformation, making it the ideal solution to eliminate their manual image optimization processes.

Here's how ImageKit addressed their needs:

  • Unified platform: ImageKit provided an all-in-one solution for media storage, optimization, transformation, and delivery, eliminating costly multi-vendor setups and manual processes. This streamlined Apollo 24|7's operations and reduced costs.
  • Magento 2 integration: ImageKit's seamless compatibility with Magento 2 allowed Apollo 24|7 to integrate media management without disrupting existing workflows.
  • URL-based transformations: Apollo 24|7 could quickly resize, crop, and adjust its media assets for different use-cases with URL-based transformations. This removed the manual processes that were in use.
How Apollo 24|7 boosted performance & reduced costs with ImageKit
Real-time resize for different aspect ratios.
  • Automatic format conversion: ImageKit's auto-format and quality optimization features enabled Apollo 24|7 to deliver media assets in optimized sizes and modern formats across browsers.
  • All-inclusive plan with transparent pricing: ImageKit's pay-as-you-go model included critical features like geo-restriction without additional costs, enhancing both affordability and functionality.
  • Actionable analytics: A clear analytics dashboard with performance insights helped Apollo 24|7 monitor usage and further optimize their media assets, ensuring top-tier web performance across devices.
  • Dedicated priority support: With customized SLAs, direct access to support engineers, and a dedicated Customer Success Manager, Apollo 24|7 gained prompt expert support and enabling faster resolutions.

Through ImageKit, Apollo 24|7 achieved operational efficiency, cost savings, and scalable media delivery, paving the way for seamless growth.

Implementation and results

Migrating Apollo 24|7's media delivery to ImageKit—impacting millions of users—required meticulous testing to ensure seamless functionality and top-tier performance. During the pilot phase, Apollo 24|7 rigorously evaluated ImageKit’s capabilities with real app users, consistently exceeding critical performance benchmarks.

Apollo 24|7 relied on AWS S3 (external cloud storage) to store its media assets and wanted to continue using it. They seamlessly connected their existing S3 bucket to ImageKit with just a few simple steps. With support from the ImageKit team, they quickly implemented URL-based transformations to resize, adapt, and optimize media in real-time for various use cases, fully automating previously manual processes.

Reflecting on the integration, Prabhat Sharma, AVP of Engineering at Apollo 24|7, shared:

Switching to ImageKit was a pivotal decision for Apollo 24|7, given the scale of our operations and user base. ImageKit not only exceeded our expectations but also ensured a seamless transition without requiring changes to our storage from AWS S3 or domain name. By enabling faster load times and delivering optimized media at 50% cost savings, ImageKit has become an indispensable part of our tech stack.

Since transitioning to ImageKit in May 2023, Apollo 24|7 has achieved an impressive 180% increase in overall traffic. ImageKit's robust infrastructure ensured seamless handling of this massive surge, ensuring uninterrupted media delivery for Apollo 24|7.

Today, ImageKit efficiently manages approximately 2.4 billion monthly requests, a number that continues to grow.

Here's how ImageKit has helped unlock significant value for Apollo 24|7:

  • Cost savings and efficiency: By optimizing delivery bandwidth, Apollo 24|7 reduced their media delivery costs by 50%, achieving remarkable savings and enhanced operational efficiency.
  • Actionable insights: With ImageKit's intuitive analytics, their team gained deep visibility into delivery patterns, optimization opportunities, and error identification, enabling data-driven decisions.
  • Seamless integration: Apollo leverages Drupal (CMS) and Magento (e-commerce) with media storage on AWS S3 for their online business. ImageKit’s integration with their existing tools have ensured high-performance visual experiences without disrupting established media-related processes.
  • Better image optimization and transformations: With ImageKit's automatic media optimization, format conversion, and URL-based transformations, the Apollo 24|7 team can seamlessly adjust images to fit various screen sizes and resolutions, which helps them reduce bandwidth usage and significantly improve load times.
How Apollo 24|7 boosted performance & reduced costs with ImageKit
Quicker app load time with modern media formats.

ImageKit has simplified Apollo 24|7's media operations and unlocked measurable gains in performance, efficiency, and cost savings, making it an invaluable part of their tech infrastructure.

Conclusion

Partnering with ImageKit allowed Apollo 24|7 to overcome critical media delivery challenges, achieving enhanced user experience, streamlined operations, and significant cost savings. This collaboration underscores the value of selecting the right technology partner to drive growth and innovation in a continuously evolving market.

If your business faces similar media delivery and management challenges, contact us at support@imagekit.io for a consultation, or try our product by creating a free account here.

]]>
<![CDATA[Simplify your media workflows with ImageKit DAM integrations]]>https://imagekit.io/blog/imagekit-dam-integrations/677d584d47ef7900014b6ec2Tue, 07 Jan 2025 16:55:24 GMT

Adopting a new tool often comes with hesitation, especially when it risks disrupting existing workflows. Sometimes, DAM solutions that promise simplicity complicate processes, forcing teams to juggle apps, repeatedly download and re-upload assets, and endure a frustrating user experience. These inefficiencies pile up, causing delays and draining productivity for creative teams, marketers, and project managers.

ImageKit DAM eliminates these challenges with seamless integrations through its DAM App. It centralizes asset management, streamlines workflows, and enhances productivity—all without requiring major changes to your existing processes.

How does ImageKit DAM streamline integrations?

ImageKit DAM is built with one goal in mind: to simplify how teams access, manage and use their digital assets.

Seamless connections to your favorite tools

Whether you’re a designer working on a Figma project, a marketer crafting a Mailchimp email, or a project manager organizing tasks in Asana, ImageKit DAM lets you access assets directly within these platforms. You can continue working seamlessly in your preferred tools while benefiting from quick and easy access to assets from the DAM—without ever leaving the tool. This ensures your assets are always at your fingertips, eliminating repetitive tasks like downloading, uploading, or switching between tools.

Easy setup and user-friendly interface

ImageKit offers a desktop DAM application for Windows and macOS, providing a user-friendly interface for managing your digital assets. With this app, you can browse and search assets, create new folders, upload files and folders, and perform operations such as copying file URLs and downloading files. Additionally, the app supports drag-and-drop functionality, allowing you to quickly move files between the app and other applications, ensuring a seamless workflow.

A centralized approach to asset management

By enabling you to manage your assets directly from the tools you use daily, ImageKit DAM ensures consistency and efficiency. You can rest assured that everyone on your team is working with the latest, most optimized versions of your files, reducing errors and improving collaboration.

In the next sections, we’ll explore how ImageKit DAM’s integrations are tailored to meet specific use cases across design, collaboration, marketing, and more.

What tools does ImageKit DAM integrate with?

ImageKit DAM supports a wide range of tools, ensuring a seamless experience for creative teams, marketers, and project managers. Below is a breakdown of the integrations:

ImageKit DAM integration with creative and design tools

ImageKit DAM - Photoshop Integration

If you’re a graphic designer dealing with a number of graphics on a daily basis, ImageKit DAM integration with Photoshop makes your life so much easier. You can open the file directly in Photoshop, make your edits, and save it right back to the DAM—no downloads, no uploads, no hassle. Plus, your team instantly gets the updated version, so everyone’s always on the same page with the latest visuals.

ImageKit DAM - Figma Integration

With ImageKit DAM’s all your assets are stored in one centralized location, ensuring everything is organized and up to date. Since assets are managed within the DAM, you can be confident that only brand-approved materials are available, reducing the risk of using outdated or incorrect files. Plus, with the DAM app integrating with your Figma workflows, you can pull up the assets you need directly within Figma, without having to switch tools. This makes your workflow more consistent, efficient, and saves you valuable time.

ImageKit DAM - Canva Integration

For marketers and content creators using Canva, ImageKit DAM provides a centralized hub for storing and accessing brand-approved visuals. This integration ensures high-quality assets can be easily added to social media posts, infographics, or ad designs, maintaining brand consistency across campaigns.

A social media manager preparing a campaign for an upcoming event can quickly access the approved banner image and brand visuals directly within Canva. There’s no need to download files or switch tools, making the workflow seamless and efficient while ensuring only the correct assets are used.

Take a look at ImageKit DAM’s integration with Canva → here.

ImageKit DAM integration with collaboration and communication platforms

Collaboration often means sharing and discussing assets in real time. With ImageKit DAM’s integrations with platforms like Slack, and Confluence, you can access DAM stored assets without having to switch tools, so your workflow stays smooth and uninterrupted.

ImageKit DAM - Slack Integration

ImageKit’s DAM integration with Slack allows you to seamlessly share media files for marketing or branding work directly within your conversations. While collaborating over the DAM itself is the best approach for media feedback, the Slack integration offers an alternative for those who prefer working within the platform. You can review and discuss assets without leaving Slack or disrupting the flow of communication, making it easy to exchange input in real-time.

ImageKit DAM - Confluence Integration

With ImageKit DAM’s Confluence integration, adding media to your documentation is effortless. You can attach relevant visuals directly to Confluence pages without leaving the platform, simplying workflows relating to project documentation or knowledge-sharing articles. Also the DAM’s centralized storage and custom -organized assets makes finding the right files quick and straightforward.

ImageKit DAM integration with project management and productivity tools

When it comes to project management, having everything in one place makes life a lot easier. With ImageKit DAM, you can embed assets from the DAM by simply dragging and dropping them into tools like Asana, Monday.com, JIRA, Trello, and Notion.

ImageKit DAM - Asana Integration

ImageKit DAM’s integration with Asana allows you to access and attach media files directly into tasks – Instead of hunting through emails or multiple platforms, you can pull the exact assets you need from your DAM and attach them to your tasks in Asana without leaving the platform. Plus you save time searching for files since the custom-organized assets make file retrieval easier.

As a designer, you can open an Asana task for a product launch campaign, pull the necessary assets—such as product images or mockups—directly from ImageKit DAM, and attach them to the task. Beyond this seamless integration, you can also provide feedback or updates on designs within the DAM itself. With version control managed by DAM, you can be confident that you're always working with the latest files, eliminating the risk of using outdated versions.

ImageKit DAM - Monday.com Integration

With ImageKit DAM integration with Monday.com, you can keep your campaigns and projects organized by embedding assets directly into your project boards. This makes it easy for your team to access the right visuals at the right time, all without leaving Monday.com.

For example, as a project manager overseeing a seasonal ad campaign, you can track deliverables in Monday.com and directly embed product images from ImageKit DAM into the project timeline. Designers and marketers can access the approved visuals instantly, without delays or needing to switch platforms - making your workflow efficient.

ImageKit DAM - JIRA Integration

When managing development or creative tasks, ImageKit DAM’s JIRA integration allows you to attach all the relevant media directly to your JIRA issues without leaving the platform. Whether it’s screenshots, videos, or graphics, you can easily add assets to tasks, providing more context and enhancing collaboration. This ensures your team stays aligned and focused on the project requirements, all within the JIRA interface.

ImageKit DAM - Trello Integration

ImageKit DAM integration with Trello allows you to access and attach media directly to Trello cards without leaving the platform. Whether it's hero images, drafts, or other assets, everything you need is easily accessible within Trello. Since the assets are organized with custom metadata in ImageKit DAM, searching for and finding the right files is faster, helping you stay organized and keep tasks moving smoothly without switching between tools.

ImageKit DAM - Notion Integration

Through the DAM app, integrating ImageKit into your Notion workflows is easier than ever. You can embed media assets directly into your knowledge bases, project plans, or team collaboration pages without leaving the platform. This ensures your documents remain visually engaging and always up-to-date with the latest versions of assets, as ImageKit DAM manages version control and organization.

ImageKit DAM integration with Marketing and social media platforms

For marketers, managing campaigns across multiple platforms can be daunting, especially when juggling creative assets and ensuring brand consistency. ImageKit DAM integrations with marketing and social media tools streamline these workflows, keeping assets organized and easily accessible.

ImageKit DAM - HubSpot Integration

ImageKit DAM’s integration with HubSpot makes managing campaign assets straightforward. You can directly access and insert approved visuals into your email templates, landing pages, or other marketing content without leaving the platform.

For example, when running a lead generation campaign, you can pull high-resolution property images straight from ImageKit DAM into your email templates. This integration eliminates the need for repetitive uploads or switching between tools, ensuring that every campaign stays visually consistent and on-brand.

For a visual understanding of how it works, look here.

ImageKit DAM - Mailchimp Integration

ImageKit DAM integration simplifies email marketing workflows by providing direct access to your media library without switching from Mailchimp’s interface. Teams can quickly locate and embed the right visuals into email templates while maintaining efficiency and brand alignment.

For instance, during a holiday sale campaign, your design team uploads festive banners and product images to ImageKit DAM. These assets can then be added to email templates in Mailchimp without the need for downloading or re-uploading files, streamlining the entire process.

ImageKit DAM - Facebook Ads integration

Managing your Facebook Ads becomes smoother with ImageKit DAM. You can access your media library and optimized visuals for ad placement—all without leaving the Facebook Ads platform. This integration ensures your campaigns remain visually consistent and saves you the hassle of juggling multiple tools during ad creation.

Note: ImageKit provides media processing capabilities as well - which help optimize, transform,personalize, and stream rich images and videos at scale.

ImageKit DAM - Hootsuite integration

Scheduling posts on Hootsuite is more efficient with ImageKit DAM app. You can pull optimized visuals directly from the DAM while staying in Hootsuite. For example, if you’re a food delivery service - you can effortlessly retrieve high-quality images of dishes or promotions and add them to scheduled posts. This integration keeps your visuals on-brand and your workflow uninterrupted.

ImageKit DAM - Buffer integration

Managing your social media workflow on Buffer becomes seamless with ImageKit’s DAM integration. You can directly access and attach media files like campaign banners, product images, or promotional graphics to your social media posts without ever leaving the Buffer interface. This streamlined process is particularly helpful for repetitive tasks, such as scheduling weekly posts or running ongoing campaigns, saving you valuable time while keeping your workflow efficient and consistent.

ImageKit DAM - Instagram integration

With ImageKit’s DAM integration, finding the right assets for your Instagram posts has never been easier. Custom metadata and organized collections allow you to quickly search and locate the visuals you need. Simply drag and drop them into Instagram for quick uploads.

Since the DAM platform is designed for efficient media management, you can be sure that your managed visuals stay on-brand. Collaboration happens directly within the DAM, ensuring all assets are approved and aligned, leaving little to no room for error. This means your company’s Instagram pages will consistently feature the right posts and reels, every time.

ImageKit DAM integration with e-commerce and website platforms

A consistent and visually appealing online presence is crucial for e-commerce stores and websites. ImageKit DAM integrates seamlessly with platforms like Shopify, BigCommerce, WordPress, and Wix, making it easier for teams to manage optimized visuals for storefronts and content pages.

ImageKit DAM - Shopify Integration

ImageKit DAM integrates seamlessly with Shopify, offering effortless access to product visuals. You can upload optimized images directly from the DAM, ensuring fast-loading, high-quality visuals for your online catalog, including seasonal collections. With faster search capabilities, finding the right assets is quicker than ever. Plus, there’s no need for repetitive upload-download cycles— files can be dragged and dropped into Hubspot through the DAM app.

Additionally, ImageKit DAM enables on-the-fly image optimization, allowing you to use perfectly tailored visuals in your Shopify workflows, improving page load speeds and enhancing the user experience.

Learn why Shopify users need a DAM solution on our blog.

ImageKit DAM - BigCommerce Integration

Running a BigCommerce store means juggling multiple tasks, but managing visuals doesn’t have to be one of them. With ImageKit DAM, you can quickly pull product images, videos, or banners directly into your listings without leaving the platform.

Forget tedious uploads and downloads—your media library is always organized and ready to access. Whether updating a product page or refreshing seasonal visuals, this integration keeps your workflow smooth and efficient, so you can focus on growing your business.

ImageKit DAM - WordPress Integration

For content-heavy websites, WordPress integration with ImageKit DAM ensures that optimized media assets are readily available for use. Teams can pull visuals directly into their pages and posts without leaving the WordPress editor through a simple drag and drop.

Read our detailed guide on managing your Wordpress media better through a DAM solution.

ImageKIt DAM - Wix Integration

You can transform your Wix- created website’s visual appeal and performance with ImageKit DAM’s seamless integration. This connection allows you to access and manage media assets directly within Wix, eliminating the need to switch platforms. High-quality images and videos are always within reach, making your workflow faster and more efficient.

For example, if you’re a graphic designer building a portfolio site, you can easily bring in high-resolution visuals from the DAM while working on Wix. Your images will be sharp, optimized for fast loading, and adapt perfectly to any device, ensuring a visually stunning, high-performing site that captivates your audience—especially if you leverage ImageKit’s media processing solution.

ImageKit DAM integration with cloud storage and file-sharing tools

We don’t recommend using Google Drive or Dropbox for storing your files because they’re not very efficient for media management. They don’t offer custom metadata for organizing files, so finding assets can be a hassle. Plus, these platforms aren’t built for media workflows, making it harder to manage media files properly.

Read why ImageKit DAM is the perfect alternative to Google Drive and Dropbox.

But if you still decide to use these tools alongside, ImageKit DAM integrates easily with Dropbox and Google Drive through the DAM app.

ImageKit DAM integration with content creation and presentation tools

ImageKit DAM - Google Docs Integration

ImageKit DAM enables users to embed images, graphics, and other media directly into Google Docs. This integration makes it easy for teams to add rich visual context to documents without leaving the editor.

ImageKit DAM - Google Slides Integration

Presentations are more impactful when supported by on-brand visuals. ImageKit DAM integrates with Google Slides, allowing users to insert images and videos directly from their asset library into slides (without having to switch tools), saving time and ensuring consistent branding.

ImageKit DAM - YouTube Integration

For video content creators, ImageKit DAM makes your workflow effortless with its YouTube integration. You can manage your entire video library, access optimized file formats, and upload content directly to your channel—all without any extra steps.

Imagine you’re a marketer planning a series of promotional videos for a campaign. With ImageKit DAM, you can upload optimized videos straight from your centralized library to YouTube, minimizing errors and ensuring your audience gets the best streaming quality every time.

ImageKit’s embeddable media library - another powerful integration capability

If you want more control over the integration, you can use ImageKit's embeddable media library widget, which is designed to enhance digital asset management within existing content management systems (CMS) or web applications. This widget allows users to seamlessly access and manage their media assets directly from their own platforms, enabling functionalities such as searching, inserting, and organizing images and videos without needing to navigate away from their CMS.

Why choose ImageKit DAM?

When evaluating DAM platforms, it’s essential to consider features that not only simplify asset management but also enhance asset performance. ImageKit combines these two necessities needed for media management and enables marketing and tech teams to see eye-to-eye.  

Our key DAM features include:

Key DAM Features:

  • Custom metadata and tagging
  • Powerful search, including AI-powered visual search
  • Granular access controls
  • Media collections for collaboration
  • Versioning and commenting for easy feedback
  • Publick link sharing (password-protected and time-restricted)
  • DAM audit logs
  • Real-time on-the-fly media editing

AI-driven features

ImageKit offers a suite of AI-driven features designed to enhance media workflows. Whether you need to generate high-quality images from a simple text prompt or changing backgrounds to suit your platform/ campaign needs, ImageKit does it all.

With features like GenFill, you can expand images with precision, ensuring every edit blends naturally. Upscaling and retouching enhance your visuals, delivering sharp, professional-quality results. For e-commerce or promotional needs, precise background removal simplifies the process, producing polished, ready-to-use content every time.

URL-based transformations enable you to resize, crop, and apply filters instantly, optimizing your workflow without limiting creativity. Additionally, when managing extensive media libraries, advanced AI-powered search capabilities make it easy to locate and organize assets efficiently.

Powerful media processing capabilities:

Eventually, every piece of media needs to be delivered efficiently, and ImageKit takes care of this part of the media workflow as well. We optimize images and videos for performance, ensuring fast load times and superior visual quality across websites and apps. With over 50+ real-time URL transformations, including resizing, cropping, and format changes, we ensure that both images and videos are dynamically adapted to the device and layout, adjusting to different screen sizes and resolutions. So - we’re able to strike the perfect balance between visual quality and performance, helping you deliver exceptional visual experiences for your customers.


Sign up with us today - we’re free forever until you decide to upgrade.

]]>
<![CDATA[Extending Lighthouse for custom image and video optimization analysis]]>https://imagekit.io/blog/how-to-extend-lighthouse-for-custom-image-and-video-optimization-analysis/674439a597563a000193ba2dMon, 25 Nov 2024 11:49:09 GMT

Optimizing website performance is critical for delivering seamless user experiences and achieving better search rankings.

While tools like Google PageSpeed Insights and Lighthouse are popular choices for performance analysis, they often fall short in addressing video content, offering only generic recommendations such as "Avoid enormous network payloads."

Extending Lighthouse for custom image and video optimization analysis
Lighthouse generic "Large network payload" audit

We faced this challenge when we wanted to develop a tool that could evaluate both images and videos. Specifically, we aimed to detect whether videos were encoded using next-generation codecs like VP9 or AV1.

So, we extended Lighthouse by creating a custom audit—and surprisingly, the process was quite straightforward.

Before diving into the details of the custom audit, let’s explore how ImageKit’s Website Performance Analyzer simplifies media performance evaluation.

How website performance analyzer works

The ImageKit Website Performance Analyzer is a free tool designed to evaluate both image and video content on your website. It generates detailed audit reports for both mobile and desktop versions, scoring websites based on key performance metrics.

Key Features

  • Device Emulation: Simulates real-world performance by replicating both mobile (e.g., Moto G Power) and desktop environments, allowing for accurate assessment across different devices and screen sizes.
  • Comprehensive overall media audit: Analyzes images and videos on your site to uncover issues such as missing size attributes, non-responsive or improperly sized media, lack of lazy loading, and the absence of next-generation formats like AVIF or WebP. Provides actionable insights to optimize media performance.
  • Video specific analysis: Identifies whether videos are encoded using advanced codecs like VP9 or AV1 to enhance playback efficiency, reduce bandwidth usage, and improve performance across modern browsers.
  • Performance Scoring: Assigns detailed performance scores based on weighted factors, helping prioritize key areas for optimization.
  • Automated monitoring with weekly alerts: Sends weekly email reports that summarize your website’s media performance. Quickly fix potential issues with these automated alerts.
  • Historical Data Tracking: Tracks and analyzes your site's performance metrics over a 90-day period, offering insights into trends and enabling continuous improvement for a better user experience.

Here’s what a sample report looks like:

Extending Lighthouse for custom image and video optimization analysis

The analyzer’s detailed feedback empowers you to make targeted optimizations, resulting in faster websites and better user experiences.

Internals of ImageKit's Website Performance Analyzer

To evaluate media performance, the analyzer uses weighted scoring for the following audits:

Audit Weightage Why It Matters
Unsized Images 5 Prevents layout shifts by ensuring explicit width and height attributes.
Responsive Image Sizing 5 Ensures sharp images by serving sizes proportional to display dimensions and DPR.
Properly Sized Images 25 Avoids oversized images, reducing bandwidth usage and load times.
Deferring Offscreen Images 10 Lazy-loads non-critical images to improve perceived page load speed.
Modern Image Formats 20 Promotes WebP and AVIF, which reduce file sizes without quality loss.
Optimized Image Encoding 15 Efficient compression accelerates load times and saves data.
Efficient Animated Content 10 Encourages replacing GIFs with video for better performance.
Modern Video Formats (Custom) 10 Detects VP9/AV1 codecs to ensure optimized playback and bandwidth efficiency.

Most of the audits listed above are standard, except for Modern Video Formats.

Creating a Custom Lighthouse Audit for Video Performance

Lighthouse allows extending its capabilities with custom audits. We leveraged this to create an audit that detects whether videos are encoded in next-generation formats like VP9 or AV1.

How It Works

The audit examines network requests to identify video files and checks if their MIME types match modern formats (e.g., WebM). If outdated formats are detected, the audit flags them and provides actionable feedback.

Here’s how you can implement it:

Step 1: Define the Audit Class

The audit class extends Lighthouse's Audit class. It defines metadata and the evaluation logic.

const { Audit } = await import('lighthouse');

class VideoOptimizationAudit extends Audit {
    static get meta() {
        return {
            id: 'modern-video-formats',
            title: 'Serve videos in modern formats',
            description: 'VP9 and AV1 offer better compression compared to H.264.',
            requiredArtifacts: ['devtoolsLogs'],
            scoreDisplayMode: Audit.SCORING_MODES.BINARY,
        };
    }

    static audit(artifacts) {
        // Audit logic goes here
    }
}

module.exports = VideoOptimizationAudit;

Step 2: Implement Audit Logic

The audit evaluates network requests to find videos and checks their MIME types.

static audit(artifacts) {
    const networkRequests = artifacts?.devtoolsLogs?.defaultPass?.filter(item => item.method === "Network.responseReceived") ?? [];

    const videoRequests = networkRequests.filter(item => {
      return item.params.response.mimeType.includes("video");
    });

    // Analyze if video mimeType is not webm
    const _nonOptimizedVideos = networkRequests.filter(item => {
      return item.params.response.mimeType.includes("video") && !item.params.response.mimeType.includes("webm");
    });

    // Unique videos based on item?.params?.response?.url because of multiple range requests for same video
    const nonOptimizedVideos = _nonOptimizedVideos.reduce((acc, item) => {
      if (!acc.find(video => video?.params?.response?.url === item?.params?.response?.url)) {
        acc.push(item);
      }
      return acc;
    }, []);

    const score = nonOptimizedVideos.length === 0 ? 1 : 0;

    let displayMessage;

    if (videoRequests.length && nonOptimizedVideos.length) {
      displayMessage = `${nonOptimizedVideos.length} non-optimized videos found`;
    } else if (videoRequests.length && !nonOptimizedVideos.length) {
      displayMessage = "All videos are optimized";
    } else {
      displayMessage = "No videos found";
    }

    return {
      score,
      displayValue: displayMessage,
      details: Audit.makeTableDetails(
        [
          { key: 'url', label: 'Video URL' }
        ],
        nonOptimizedVideos.map(video => ({
          url: video?.params?.response?.url,
        }))),
    };
  }
}

Step 3: Register the Audit

Include the custom audit in the Lighthouse configuration.

module.exports = {
    extends: 'lighthouse:default',
    audits: ['modern-video-formats'],
};

Save the file as modern-video-formats.js and run Lighthouse to generate a report with your new custom audit.

We now have video-specific audit results, which include a list of all videos on the page that are not encoded in next-generation codecs like AV1 or VP9. You can see the full report here.

Extending Lighthouse for custom image and video optimization analysis
Video optimization audit

Conclusion

By extending Lighthouse with a custom audit, you can bridge gaps in performance analysis for videos.

🚀 Try it yourself! Analyze your website’s media performance and discover actionable insights today.

]]>
<![CDATA[Brand Asset Management: What is it? How does it work?]]>https://imagekit.io/blog/brand-asset-management/63ad18cc03d137000138672eMon, 28 Oct 2024 05:19:00 GMT

A brand represents the unique identity of a business, encompassing its values, vision, and personality. When customers encounter a cohesive brand experience—whether through logos, messaging, or customer service, they are more likely to develop loyalty and advocate for the brand.

In today’s competitive market, consistent brand messaging and visuals not only enhance brand reputation but also contribute significantly to its growth and profitability. Brand asset management is a powerful tool that organizations implement for consistent branding and streamlined collaboration across teams to achieve a smooth customer experience.

What is Brand Asset Management (BAM)?

Brand asset management is the process of securely storing, sharing, and publishing all the digital assets related to a brand to ensure consistency, accessibility, and efficient use across all channels. It safeguards brand integrity by controlling access, ensuring that only authorized individuals can modify or publish assets. Additionally, it streamlines collaboration between internal and external teams, allowing for faster execution of marketing campaigns.

Understanding brand assets

When considering what qualifies as a brand asset, reflect on your most recent interactions with a company and how those moments shaped your perception of its brand. Brand assets include a wide array of elements that evoke a company's identity and values, extending beyond obvious graphical components to include more nuanced sensory experiences.

Essentially, any digital or physical asset that prompts consumers to think of your brand and the principles it embodies can be classified as a brand asset. These assets play a crucial role in shaping brand perception and developing emotional connections with consumers.

Here are a few examples to illustrate the various types of brand assets:

  • Brand typography: The specific fonts and styles used in communication that contribute to your brand’s personality, e.g., Think Coca-Cola - The classic Spencerian script has been synonymous with the brand since 1887, conveying its timeless and authentic feel.
  • Brand color palette: The colors that represent your brand, influencing recognition and emotional response. Who can forget the bright blue and yellow colors of IKEA?
  • Brand Logo: Your brand’s logo is the symbol representing your brand’s identity online. Take Starbucks as an example; they don’t even mention the brand name with their logo, which is the power of a well-recognized digital identity.  
  • Brand’s punch line, or slogan: A memorable phrase that encapsulates the brand's essence, e.g.,"Just Do It" from Nike inspires action and determination, aligning with the brand's athletic spirit.
  • Brand style guides: Documents defining branding elements and how to use them for consistent visual and verbal communication.
  • Brand audio content: Sounds, jingles, or audio logos that enhance brand recall and emotional connection, e.g., The "I'm Lovin' It" jingle from McDonald's.
  • Brand visual content: Images, graphics, illustrations, etc., for marketing materials.
  • Packaging: The design and materials used for product packaging. Think Apple - Sleek, minimalistic packaging that mirrors the brand’s commitment to high-end, user-friendly design.

Difference between Digital Asset Management (DAM) and Brand Asset Management (BAM)

When exploring Brand Asset Management (BAM), you'll likely come across Digital Asset Management (DAM) as well. Although these terms are often used interchangeably, there is a small difference between the two. BAM is a subset of DAM tailored to meet the specific requirements of brand managers.

Think of DAM as the umbrella term. It covers tools that help teams store, organize, and collaborate on a wide range of digital files—things like images, videos, PDFs, and even 3D graphics. DAM’s broad functionality is meant for the whole organization, making it easier to handle any type of digital content, integrate with different marketing tools like a CMS, PIM, or CRM, and ease multi-channel distribution.

BAM, on the other hand, zooms in on the assets that shape a brand’s identity and support its marketing. It focuses on brand-specific tools like customizable templates, secure sharing, and version control for branded content. Many DAM platforms already offer BAM features as part of their package, including content templates tailored to brand guidelines.

A Digital Asset Management (DAM) system can effectively be utilized for brand asset management, allowing branding teams to focus on brand identity while benefiting from its comprehensive capabilities.

The importance of brand asset management

Effective brand asset management is crucial for several reasons:

  • Foundation of Brand Identity: In a world where consumers are bombarded with choices, maintaining a strong and consistent identity is vital for differentiation and market positioning. BAM acts as the bedrock for a cohesive and recognizable brand presence.
  • Brand Asset Protection: Protect your brand from legal and reputational risks by having clear guidelines for managing public relations, access control measures, and tracking audit logs for brand assets.
  • Market Expansion: BAM empowers organizations to leverage their brand assets strategically, unlocking new opportunities for growth. This includes brand localization, real-time personalization, and AI-powered operations to scale the distribution of brand assets.

Key components of brand asset management

The following elements bring structure to every brand asset management strategy:

Centralized repository

A cloud-based brand asset management (BAM) system centralizes your brand assets—logos, icons, images, videos, and marketing materials—in one platform. This enables teams to easily upload files and access the latest versions of assets, ensuring seamless collaboration and brand consistency.

Custom metadata

Metadata is the crucial information that describes your brand assets, enhancing their organization and usability. While organizing files into folders is essential, metadata provides details that can't be captured in file or folder names.

For instance, a file stored at /shoes/nike/SKU1234.jpg can be enriched with metadata like brand: Nike, color: Black, and type: Running Shoe. This method allows folder paths and metadata to work together, providing a complete picture of each asset's organization and context. This ensures clarity and efficiency when managing diverse content types and channels.

User roles and permissions

Using brand asset management, you can assign different user roles & permissions to various team members depending on their responsibilities—administrator, manager, contributor, or viewer—to ensure no unauthorized edits happen.

Version control & feedback

Version control in a brand asset management system enables teams to track all changes made to brand assets, ensuring only the latest approved version is distributed while maintaining a clear history of edits and approvals. A BAM preserves the original asset, allowing teams to roll back when necessary and prevent the loss of creative value amidst multiple revisions. Additionally, it documents every action taken on an asset—including edits, comments, and approvals—providing clarity and accountability throughout the asset's lifecycle.

Easy external collaboration

A BAM offers media collections to group brand assets together for any specific business collaboration, such as working with PR agencies, freelance designers, or marketing consultancies. Creating a collection is agnostic of the existing folder structure or the current location of the file/folder; thus, the brand assets put together in a collection are merely accessible in the collection and are not duplicated in your repository.

Plus, any updates to the original assets are automatically synced across all collections, guaranteeing that everyone always has access to the latest version.

Integrations with design and marketing tools

A BAM offers seamless integrations with your content management system (CMS) and design tools to swiftly publish assets across channels, reinforcing a cohesive brand identity. You can upload and download assets seamlessly from popular tools like Photoshop, Illustrator, or Shopify using brand asset management software.

Audit logs with asset history

With a BAM system, you can track all activities related to brand assets, including uploads, deletions, and version changes, as well as updates to file organization and access controls. Utilize log filters and asset-level change history for in-depth insights, ensuring seamless collaboration and control.

Who uses brand asset management?

The following teams rely on brand asset management to ensure consistency, streamline workflows, and enhance collaboration.

  • Brand Managers: Use brand asset management to maintain control over brand identity, ensuring consistency across all touchpoints. It helps streamline the approval and distribution of assets for campaigns and product launches.
  • Creative teams: Utilize BAM to centralize design files and brand guidelines, making it easier to collaborate and ensure creative consistency. They can also perform creative operations like editing, background removal, and cropping inside the BAM.
  • Marketing & Sales teams: Leverage it to find and customize approved assets for campaigns, presentations, and advertisements, ensuring brand consistency. It also helps them reduce time spent searching for up-to-date materials like logos, email graphics, etc.
  • Agencies & External Partners: BAM helps agencies manage assets for multiple brands by organizing each brand's assets into distinct libraries, allowing for easy navigation and retrieval of brand-specific content. Access and permissions can be tailored for each client, ensuring that only authorized team members have access to specific brand assets, safeguarding sensitive or proprietary materials.
  • Legal and Compliance Teams: These teams ensure all digital assets adhere to legal, regulatory, and brand standards before they are distributed. They can track version history, set up approval workflows, and monitor asset usage to mitigate risks associated with non-compliance or outdated content distribution.
  • Product Managers: Product managers rely on a BAM to ensure all product-related visuals, documentation, and messaging align with the brand’s guidelines. They use it to coordinate with other teams during product launches to maintain a unified brand presence.

Benefits of effective brand asset management

Brand asset management delivers the following key benefits that enhance overall brand performance and engagement:

Consistency across channels

Effective brand asset management ensures a cohesive brand identity across all platforms—social media, advertising, product packaging, etc. This coherence enhances brand recognition and makes it easier for consumers to engage with the brand. For example, global brands like Apple and McDonald's enforce strict brand guidelines to ensure their franchises and partners use approved brand assets like logos, imagery, and messaging for consistent branding worldwide.

Faster time to market

When brand assets are well-organized with metadata and accompany clear version history and feedback, teams can collaborate on assets faster, eliminating delays caused by using outdated or unapproved versions. Features like AI tagging, visual search, and advanced search filters in a BAM help in quick organization and searching of brand assets to accelerate campaigns or product launches.

Customer loyalty

When a brand consistently maintains its messaging and visual identity with brand asset management, customers can easily recognize that brand. This fosters a sense of trust and loyalty among customers. Over time, this loyalty translates into repeat business and positive word-of-mouth, which is invaluable for any brand.

Improved ROI

Consistent brand presentation across all platforms increases revenue by up to 10-20%. When customers get a seamless experience engaging with your brand on social media, website, and in-store, their confidence in the brand’s offerings increases, which results in higher conversion rates and long-term customer retention. Using a BAM for cross-channel marketing amplifies the impact of your campaigns, leading to increased sales and better ROI.

When it comes to implementing brand asset management, choosing the right tool is key. Here are some popular brand asset management systems designed to help you create a consistent and recognizable brand.

ImageKit DAM

ImageKit’s DAM is tailored to meet all brand asset management needs of growing businesses. Unlike many popular DAM systems with high, enterprise-level costs, ImageKit offers transparent and affordable pricing based on your storage and user account needs. We also offer a usage-based pricing model so that you can scale without worrying about upfront costs. The best part? You can get started with the forever-free plan and pay as you go!

ImageKit DAM Demo

ImageKit allows you to

  • Store assets without restrictions: ImageKit offers an intuitive drag-and-drop interface and API access for unlimited file uploads, allowing you to store various asset types, including large videos and diverse formats, in a centralized BAM repository.
  • Organize brand assets with business parameters: Structure your assets with custom metadata like brand name, campaign, channel, or creator rather than just depending on file or folder names. Utilize AI tags to automatically organize your brand library, making it easily searchable.
  • Go-to-market faster with powerful asset retrieval: ImageKit's AI-powered search provides content suggestions as you type, and can find content visually similar to your input text or image. You can also combine multiple filters, including custom metadata & different file attributes, to pinpoint the specific assets you need.
  • Collaborate with external teams seamlessly: Easily compile media assets and folders into virtual media collections, eliminating the need for constant reorganization and duplication for each access request. Share these collections with agencies or freelancers with granular permission control on who can view, contribute, or manage assets.
  • Create brand templates and personalize assets: Seamlessly layer logos, icons, text, and other brand elements onto your images and videos, ensuring cohesive branding across every visual, no matter the scale.
  • Centralize creative versioning and feedback: Imagekit DAM centralizes version history and specific feedback to replace scattered collaboration efforts on Slack, email attachments, or drive links.

Bynder DAM

Bynder is an enterprise-grade digital asset management platform built for large organizations to streamline brand asset storage, management, and distribution. It offers AI-powered tagging, advanced search, and specialized asset workflows to enhance marketing efficiency.

Compare Bynder with ImageKit

Brandfolder DAM

Brandfolder is a digital asset management platform for marketing and creative teams. It allows teams to create personalized marketing materials using pre-approved assets and templates, ensuring brand consistency across all campaigns.

Compare Brandfolder with ImageKit

Canto DAM

Canto tends to maintain the traditional enterprise-style approach, much like other platforms in the digital asset management industry. Canto's standout features include customizable metadata tagging, version control, AI visual search, style guides, and role-based permissions, allowing organizations to efficiently manage their brand assets.

Compare Canto with ImageKit

Acquia DAM

Acquia DAM (formerly Widen Collective) is a digital asset management platform that streamlines asset management for the entire organization, including marketing, sales, and product teams. Acquia DAM integrates well with popular content and marketing platforms like Drupal and Airtable, providing users with extensive capabilities for collaboration and content management.

Compare Acquia with ImageKit

Wrapping up

Brand asset management is essential for maintaining a consistent and cohesive brand identity across all touchpoints. It streamlines collaboration, ensures easy accessibility, and strengthens marketing efforts. By leveraging BAM, organizations can improve brand recognition, foster customer loyalty, and drive long-term growth and profitability.

Learn more about ImageKit DAM here.

]]>
<![CDATA[WordPress Digital Asset Management Guide - Manage your WP media assets better]]>https://imagekit.io/blog/wordpress-digital-asset-management/6710b82697563a000193b926Thu, 17 Oct 2024 09:42:35 GMT

WordPress is a widely used content management system (CMS) known for its flexibility and ease of use. It provides a wide range of features and plugins to build and manage websites, whether you're a blogger or a small business owner. However, as the volume of digital assets like images, videos, and documents increases, WordPress’s media management tools may not be enough to keep up.

Managing hundreds of assets without a clear organizational structure becomes frustrating and time-consuming. This lack of effective tools can be a major drawback for websites that frequently update content or depend heavily on visual elements, like e-commerce stores or blogs.

Let’s explore the specific challenges users face when managing digital assets on WordPress.

Core challenges of managing digital assets on WordPress

WordPress Media Library can’t centralize ALL your assets

The WordPress media library shouldn’t be the central place to store all your assets. WordPress represents one part of your online presence. You also need assets for social media, marketing emails, and other uses, each requiring different media assets.

A dedicated Digital Asset Management system is a better choice for efficiently organizing and finding all these diverse assets and using them on different platforms with different teams.

Lack of Proper Organization

As your asset library grows, WordPress's basic media management features become insufficient due to poor organization. One major issue is the inability to create folders, which means all assets like images, videos, and documents are stored in a long, unorganized list, making it hard to find specific assets.

Additionally, WordPress's limited metadata features only provide primary fields like Title, Caption, Alt Text, and Description, with no room for advanced tagging. This lack of organization becomes problematic when managing different media types for various purposes, such as blogs, email campaigns, and social media posts. You have no way to filter by detailed categories, such as finding pictures of a particular city, celebrity, or event or using AI search to match a description you have in mind.

While WordPress does have a search function, it’s basic and often inefficient. You can search for assets by name, but no advanced filtering options exist. This can be a major issue when dealing with multiple versions of similar assets or a large asset repository.

The absence of advanced search filters or the ability to search by custom metadata or tags makes it challenging to retrieve specific assets quickly. This problem only worsens as more content is uploaded.

Example
If you're managing a blog, you might have hundreds of travel images. Without the ability to organize these images into folders based on categories like "destinations," "events," or "seasonal promotions," finding the right photo for a specific post can feel overwhelming. You may end up scrolling through countless assets, wasting time searching for the perfect image to match your content.

Inadequate collaboration

WordPress lacks robust collaboration and sharing tools for asset management. You can't grant controlled access to specific assets, only to the entire account, which raises security risks and complicates working with external teams like bloggers or social media agencies.

Example
Suppose you're working with a social media agency and need to share only a set of images from a recent event. In that case, you'd have to give them access to the entire media library, risking the exposure of other assets unrelated to the project.

How Digital Asset Management can help WordPress users

A Digital Asset Management (DAM) system helps businesses organize, store, and retrieve digital assets efficiently. Unlike basic media management tools that can become disorganized over time, DAM systems provide advanced features like tagging, categorization, and search capabilities, making it easier for users to find exactly what they need.

Integrating a DAM solution can address core challenges and significantly improve workflows for WordPress users who manage large media libraries, dealing with diverse asset types and content for different platforms.

Let’s explain how a DAM system addresses key challenges WordPress users face when managing digital assets.

Centralized Asset Hub: one place for all media assets

A Digital Asset Management (DAM) system centralizes all digital assets into a single, easily accessible location. This consolidation includes everything from social media images and blog graphics to marketing videos and documents like press releases. By integrating a DAM, you eliminate the hassle of managing assets scattered across multiple tools and platforms, reducing the risk of misplaced or duplicated assets.

Bulk upload and cross-platform management

A Digital Asset Management (DAM) system streamlines the process of handling bulk uploads for various types of assets, such as images, videos, and documents. It allows you to upload everything at once and organize it efficiently for different uses, whether for blog posts, social media, or email newsletters. With a DAM, you can easily manage assets across multiple platforms, ensuring consistency, proper formatting, and smooth collaboration between teams, all from a single, centralized location.

Advanced organization and search functionality

Organizing and finding specific assets can become difficult as your media library grows. A DAM solves this with custom metadata & tagging and advanced search options, allowing you to organize & locate assets faster based on specific needs.

You can tag assets by categories like topic, event, or campaign, making it easier to find what you need without endlessly scrolling. For example, if you're managing a travel blog, you could tag images by destinations like "New York", "beaches", or specific events like "New Year's Eve". Instead of sifting through hundreds of photos, DAM's advanced search allows you to type in tags like "New York skyline" or "sunset beach" and combine them with other search filters like file format, resolution, etc., instantly showing all relevant images for your next post.

Advanced Search in ImageKit

Collaboration and Sharing

A DAM enhances collaboration and sharing by allowing you to keep assets for different platforms like email marketing, social media, and more in one place. You can invite specific teams or individuals, such as an external social media agency, to access only the assets according to their role. This ensures that only the right people can make changes and everyone stays on the same page.

With built-in tools for comments and approvals, DAM allows your team to collaborate on a centralized platform instead of email, Slack, and many other tools. In some DAMs, real-time updates allow team members to receive alerts for new comments, mentions, and shared assets, keeping everyone informed and engaged.

Managing Asset Versions

Asset versioning in a Digital Asset Management system helps you easily manage and restore different versions of your assets. This feature is helpful for content creators and marketers who frequently update media for their websites or campaigns.

When you upload a new version of an asset with the same name, everyone with access to that asset immediately gets to see the new asset version. The previous versions are also available, allowing you to effortlessly switch between asset versions, whether it's to correct a mistake on the graphic or accommodate a change in the content.

This way, you avoid having too many similar-looking asset updates cluttering your library while ensuring you have the right assets.

Asset Versioning in ImageKit

Why ImageKit DAM is ideal for solving WordPress's Asset Management challenges

ImageKit is a modern cloud-based Digital Asset Management (DAM) solution designed to make media management easier for WordPress users. It provides essential features for better organization, quicker searches, and smooth collaboration, ensuring your digital assets are efficiently managed and delivered. Built to integrate seamlessly into your existing workflows, ImageKit saves time and enhances productivity while optimizing your assets for fast and reliable delivery across all platforms.

It also offers a free plan with substantial storage and all the features required to simplify your media management.

DAM Overview

However, many WP administrators hesitate to adopt DAM tools, fearing its complexity and integration with Wordpress-related workflows.

With ImageKit, that's not a concern. It's designed to seamlessly integrate into your existing processes without adding complexity.

Seamless integration with WordPress and simple onboarding for effortless media management

ImageKit integrates smoothly with WordPress, allowing you to manage, search, and insert media directly from your WordPress dashboard.

With the ImageKit DAM app available on Mac and Windows, you can quickly access your media library as if it were a locally available folder on your system and drag and drop assets into your WordPress dashboard without switching any windows.

ImageKit DAM demo

Gen AI-Powered Image Creation

ImageKit’s Gen AI capabilities allow you to generate new images directly within the media library. Whether you need fresh visuals for a blog post or social media, ImageKit’s AI makes creating and storing new images easy, saving you time and enhancing creativity. This is an excellent solution for teams that need to quickly create visuals for their content without relying on external design tools or services, speeding up the process and keeping everything in-house.

Effortless image editing

With ImageKit, editing images is a breeze. The platform features an intuitive browser-based image editor that allows you to make quick adjustments to your assets in the DAM without the need for additional software. Whether you need to resize, crop, rotate, or add text overlays, the simple interface makes these tasks straightforward and efficient.

ImageKit also offers user-friendly URL-based transformation parameters that allow you to transform your images and videos in real-time at scale. These transformations include background removal, adding drop shadows, retouching, upscaling, object-aware cropping, generating new images from text prompts, and creating variations of existing images. While it requires some technical knowledge, this functionality makes it easy for your team to customize visuals at scale according to your specific needs.

Conclusion

Managing digital assets on WordPress can be challenging, but with a DAM like ImageKit, you can simplify the process, improve team collaboration, and deliver faster, optimized content across platforms. From centralized storage and advanced search features to AI-powered tagging and seamless integration with WordPress, ImageKit has everything you need to keep your media organized and efficient.

So, if you're a WordPress user struggling with asset management—don't wait. Give ImageKit a try for free today! It’s completely free until you're ready to upgrade.

]]>
<![CDATA[Why Shopify retailers need a digital asset management solution]]>https://imagekit.io/blog/shopify-digital-asset-management-solution/66fa302297563a000193b814Mon, 30 Sep 2024 06:58:09 GMT

Shopify is a go-to platform for online retailers and D2C brands, offering an easy-to-use interface, customizable themes, and plenty of integration options to help you grow your e-commerce business.

But as your business expands with more products and categories, the number of digital assets you need to manage grows too. You'll have to deal with product images, sale banners, category images, and more. Managing all of these across different platforms for your campaigns can quickly get out of hand.

And Shopify’s functionality alone might not be enough to handle it all.

Core problems retailers face on Shopify with their digital assets


Shopify can’t centralize ALL your assets

Shopify is just one part of your digital presence - your online store. Your assets go beyond the store — you'll need them for social media ads, posts on Facebook and Instagram, and marketing emails. Each platform needs different images, videos, or graphics, and Shopify shouldn't be a warehouse to centralize and manage all these distinct assets.

No easy way to collaborate or give secure access

When you need to work with others—like a photographer or social media agency—Shopify doesn't let you give them controlled folder-level access to upload assets (in fact, it doesn't have a concept of folders for assets). So, the only way they can upload directly into your Shopify media library is by inviting them as a user with access to the entire Shopify account.

Since this is far from ideal, they’ll probably end up emailing you files or sending Google Drive links, which are hard to keep organized. And managing and storing these assets becomes a mess without a secure, central place.

Shopify’s media library makes it hard to keep assets organized. Without folders or metadata tagging, everything you upload goes into one long list. Searching for images becomes tedious because you can’t filter by custom tags like product type, SKU ID, category, color, or any other attribute.

For example, if you're looking for a high-resolution image of a red sneaker to create a new product category banner, you'd need to scroll through the entire library instead of simply filtering for “red” or “sneaker.” This lack of structure only worsens as your store grows, making asset management time-consuming and inefficient.

What is a DAM, and how do DAMs solve Shopify’s digital asset management issues

A digital asset management (DAM) system helps you efficiently store, manage, and retrieve all your digital assets related to Shopify and any external campaigns you run.

With a DAM, you can:

  • Centralize your assets: Store all assets like product images, videos, product specification documents, social media posts, ads, and more in one centralized hub, reducing the clutter of scattered files.
  • Easily organize assets: Tag and categorize assets for quick retrieval based on specific criteria like product names or SKU IDs.
  • Enhance search: Use powerful AI-powered search features tailored to your organizational schema to find assets quickly
  • Control versions: Track and manage different versions of assets, ensuring easy updates without creating duplicates.
  • Collaborate seamlessly: Work with internal team members and external contributors with shared access. Centralize feedback and iterations on assets within the same platform.

Let’s delve into the each of these functionalities in detail:

Centralized asset hub

A DAM helps centralize assets by consolidating all digital assets—whether they come from your Shopify store or marketing campaign assets from your external collaborators—into a single, easily accessible location. So you don’t have to deal with multiple storage areas and in turn you don’t risk misplaced or duplicated files.

With all assets stored in one hub, you or your team can quickly find, share, and update content without navigating through disorganized folders or platforms.

Centralized storage is the core feature of a DAM, but it works in combination with several other functionalities (discussed in the following sections) that make it an ideal solution for Shopify retailers.

Faster asset organization and search with custom metadata

Organized assets are easier to find. A DAM helps you organize assets as per your business requirements. With a DAM, you can tag assets using relevant metadata—whether it's product categories, SKUs, colors, or custom tags you define. This means you can retrieve assets based on very business-specific criteria. Instead of scrolling through hundreds of images, you can type in a product name, category, or even custom tags like "summer collection", and the system finds exactly what you're looking for in seconds.

For example, if you sell footwear on Shopify and need images of your "blue sneakers", you can search using tags like "blue", "sneakers", or even the SKU number. The DAM instantly pulls up all matching images, letting you update or reuse them without sifting through irrelevant content.

In cases where you forget to custom tag your assets, a few DAMs allow you to search them through visual cues – you just need to type in the description of the image you're looking for, and the DAM pulls out all relevant images in seconds.

ImageKit DAM offers this functionality. Here’s a detailed video on how it works.

Easier sharing and collaboration

With a Digital Asset Management system, you and your team can collaborate on the same central platform. You control who can access or edit each asset, so only the right people can make changes. Whether you're sharing with an individual or an entire team, you maintain full control, keeping the process smooth and secure.

DAM also makes sharing and managing feedback much easier. No more digging through endless email threads or Slack channels collating feedback from different stakeholders—just leave comments directly on the assets, whether it's product images or banners, and view all iterations in one place. This way, you can quickly finalize and approve visuals, ensuring they're just right for your Shopify store.

Why Shopify retailers need a digital asset management solution
Collaboration on ImageKit DAM 

Version control for the right asset version

As a Shopify retailer, you’ll spend a good chunk of time creating assets for your various promotional channels apart from Shopify.

Let's say you had a banner promoting a 20% discount, but now the offer has increased to 25%. Instead of creating another copy of the same banner with the updated text, a DAM allows you to upload a new asset version. Once you update the asset version, everyone with access to the file or any online portal that publishes this file on the web will start getting the new version. This means you don't clutter your media library with endless duplicates and don't have to re-share the file or update it everywhere online. Simply create a new version, and it automatically updates everywhere.

Why ImageKit DAM is the best for Shopify retailers

ImageKit is a modern cloud-based DAM solution that provides all the digital asset management features discussed above for better organization, faster searches, and smoother collaboration. It is also available for free with ample storage and all the features needed for a small business.

However, many retailers hesitate to adopt DAM tools, fearing its complexity and integration with Shopify-related workflows.

ImageKit DAM demo


With ImageKit, that's not a concern. It's designed to seamlessly integrate into your existing processes without adding complexity.

ImageKit seamlessly integrates with Shopify

ImageKit not only provides a browser-based interface for the DAM but also comes with native applications for Mac and Windows.

Let's say you're working on a new campaign and need to find images from a previous product launch, like your summer sandals collection. Instead of opening another tab to access the tool to search for those assets, you can do it all while staying on the Shopify interface using ImageKit's DAM app.

Search directly in the DAM app by product name, SKU, or any custom tags you've set up and get the exact assets you need without disrupting your workflow.

This is incredibly useful because it saves you time and prevents the hassle of juggling multiple platforms. It works with Shopify and any other tool in your workflow, such as Photoshop, Instagram, Facebook, etc. Whether you're updating product pages or uploading new marketing content, the DAM app ensures you always have the right asset at your fingertips without ever leaving Shopify or losing your trail of thought.

ImageKit DAM app for seamless Shopify integration

Perform quick image edits

With ImageKit, you can quickly and easily edit your images using the browser-based image editor. Whether you need to resize, crop, rotate, or add text overlays and frames, the intuitive interface allows for seamless edits.

If you're looking to remove distracting backgrounds, the AI-powered background removal tool simplifies this process, enabling you to enhance your visuals with just a few clicks. The editor saves time and eliminates the need for expensive software like Photoshop for small edits.

Generate new images with Gen AI

In addition to editing, ImageKit's integrated Gen AI capabilities allow you to create entirely new images for your marketing campaigns. Once generated, these images can be saved directly to your media library for further editing. From here, you can easily add text overlays or other elements to align with your campaign needs, all within the same platform. This ensures your visuals remain fresh and engaging, boosting customer interaction.These features are easily accessible via ImageKit's URL-based API, making image management a streamlined process for your team.

Here’s how you can generate various images based on your requirements through ImageKit.

Bonus: Unmatched media processing with ImageKit

Whether you're managing a Shopify store or any other online platform, ImageKit helps you deliver top-notch media with ease. From optimizing and compressing your images to delivering them at lightning speed, ImageKit ensures your visuals always look their best across all devices. With features like real-time resizing, cropping, and format conversion, there's no need to store multiple versions of your files. And if your business requires handling large volumes of media, ImageKit offers flexible plans to meet even the most demanding needs.

Take advantage of our Forever Free plan now.

Why Google Drive or Dropbox can’t solve Shopify digital asset management challenges


Google Drive and Dropbox aren't designed to compete with the specialized functionality of a DAM. They're built for general file storage and sharing, not the intricate as set management needs of Shopify retailers. While they offer basic features like file sharing and access controls, they fall short when it comes to organizing large volumes of digital assets efficiently.

For example, asset organization on these platforms is limited to simple file and folder structures. You can't add custom metadata or group assets into virtual collections for easier management and sharing. Searching for specific assets can also be frustrating due to this limited organization.

So, why rely on Google Drive or Dropbox when a DAM provides so much more? A DAM can streamline managing your Shopify store's digital assets in ways these platforms simply weren't built to handle.

To learn in detail why these platforms don’t compare with a DAM’s functionality, read -  Google Drive vs. DAM and Dropbox vs. DAM

Comparing ImageKit with other DAMs for Shopify’s digital asset management needs

When it comes to picking the right DAM solution for Shopify, ImageKit really shines compared to other big names like Cloudinary, Bynder, and Widen. All of these platforms offer solid features, but ImageKit stands out for small Shopify retailers because it’s easier to use, integrates smoothly with Shopify, and doesn’t break the bank. The other options tend to be geared more toward larger businesses, often requiring more resources to implement and manage, which might not be ideal for a smaller team. ImageKit gives you what you need without all the extra complexity and cost, making it a great fit if you’re a Shopify retailer.

Want to dive deeper? Here’s where you can read the details on each comparison:

So, if you’re a Shopify retailer - don’t wait— give ImageKit a try for free today!

It’s completely free until you're ready to upgrade.

]]>
<![CDATA[DAM vs. SharePoint: Which is best for you?]]>https://imagekit.io/blog/dam-vs-sharepoint/66da795397563a000193b19eFri, 06 Sep 2024 08:44:11 GMT

Today's digital world is fast-paced, which makes managing growing volumes of digital content crucial. Whether you're a creative professional, a marketer, or part of a large enterprise, keeping track of digital assets like images, videos, and documents can be challenging. That's where Digital Asset Management (DAM) and platforms like SharePoint come into play.

But which one is right for you? This blog will explore the nitty-gritty of DAM systems and SharePoint, comparing their features, benefits, and the types of teams that will benefit most from each.

What is Digital Asset Management (DAM)?

Digital Asset Management (DAM) is a system designed to store, organize, manage, and distribute digital assets such as images, videos, documents, and other media files. The DAM system provides a centralized repository where various organizational stakeholders can easily store, retrieve, and use digital assets. Whether it's marketing materials, product images, or videos, DAM systems ensure that these assets are accessible and usable when needed.

What DAM systems are designed to do?

In a DAM system, digital assets can be stored and categorized in a structured way, making them easy to organize and find later. From creation to distribution to collaboration, a DAM system simplifies the management of digital assets. Furthermore, the system makes sure only authorized users can access and modify assets, keeping the brand consistent and in control of its use.

The essential features and advantages of a DAM system.

Centralized Storage

DAM systems provide a single source of truth for all digital assets, reducing the risk of asset duplication and loss, due to which all the teams members have access to the same, up-to-date files eliminating confusion and inconsistencies.

Improved Searchability

With robust metadata tagging and advanced search functionalities, DAM systems make it easy to find the right asset quickly, saving time and improving efficiency. This enhanced search capability speeds up project timelines.

Version Control

DAM systems track changes to assets, ensuring that users are always working with the most up-to-date version while maintaining an archive of previous versions.

Access Control

DAM systems help manage permissions and rights associated with assets, ensuring compliance with copyright laws and licensing agreements.

Collaboration

Teams can collaborate more effectively by sharing assets and providing feedback directly within the DAM system, streamlining workflows and reducing bottlenecks. This integrated collaboration fosters creativity and speeds up project completion by keeping all communications and revisions in one place.

Integration with Creative Tools

DAM systems often integrate seamlessly with creative tools like Adobe Photoshop, Illustrator, and various content management systems (CMS). This integration allows creative teams to access and use digital assets directly within their preferred tools, streamlining the creative process and ensuring that assets remain consistent and up-to-date across all platforms.

What is SharePoint?

SharePoint is a web-based collaboration platform developed by Microsoft. It is primarily designed for document management, storage, and team collaboration. SharePoint enables organizations to create websites for storing, organizing, and sharing information, making it a powerful tool for managing a wide range of content, from documents to intranet sites.

At its core, SharePoint is a content management system that allows organizations to create, store, and share documents and information. It’s designed to facilitate collaboration among teams, offering tools for document management, file sharing, and workflow automation.

Common Uses and Applications

SharePoint is commonly used for:

  • Document Management: Storing, organizing, and retrieving documents.
  • Team Collaboration: Enabling teams to work together on projects by sharing files, tracking progress, and communicating through integrated tools like Microsoft Teams.
  • Intranet Sites: Creating internal websites for sharing news, resources, and organizational information.
  • Workflow Automation: Automating business processes like document approval, task management, and project tracking.

Key Features of SharePoint

Document Management and Collaboration Tools

SharePoint offers robust document management features, allowing users to securely store, organize, and share documents. It also provides collaboration tools, such as co-authoring, which enables multiple users to work on a document simultaneously. These features are particularly beneficial for teams that need to manage large volumes of documents and ensure that everyone has access to the most current version.

Integration with Microsoft Products

One of SharePoint’s most significant advantages is its integration with other Microsoft products like Office 365, Teams, and Outlook. This integration allows users to create and manage documents directly within the SharePoint environment, making it easier to collaborate, communicate, and stay organized.

DAM vs. SharePoint: Comprehensive Comparison of Features and Cons.

Features DAM Systems SharePoint
Primary Use Case
  • Manages diverse digital assets.
  • Supports complex media libraries.
  • Suitable for marketing and creative workflows.
  • Manages documents and collaboration.
  • Ideal for businesses with document-centric needs.
  • Facilitates process automation and task management.
Integration with Tools
  • Integrates with creative tools like Adobe Photoshop, Illustrator, and various content management systems.
  • Enhances creative workflows with seamless integration.
  • Supports real-time media processing and optimization.
  • Integrates with Microsoft Office.
  • Streamlines document editing and sharing.
  • Offers out-of-the-box integration with other Microsoft services.
Asset Organization
  • Advanced tagging and categorization.
  • AI-driven tagging for enhanced asset discoverability.
  • Supports complex hierarchical structures and taxonomies.
  • Basic metadata and categorization.
  • Simple categorization tools for documents.
  • Manual tagging may be required for detailed organization.
Search and Retrieval
  • AI-driven, powerful search.
  • Supports categorized search and advanced filtering.
  • Quick retrieval of assets based on metadata, content, or visual similarity.
  • Standard search needs customization.
  • Basic keyword search with limited filtering options.
  • Customizable search scopes and refiners within document libraries.
Collaboration
  • Built for creative team collaboration.
  • Supports version control, feedback loops, and approval processes.
  • Centralized collaboration on media assets.
  • Strong document collaboration.
  • Real-time document co-authoring and sharing.
  • Integration with Microsoft Teams for communication and collaboration.
Brand Consistency
  • Ensures brand control.
  • Centralized management of brand assets.
  • Automated enforcement of brand guidelines.
  • Limited brand control.
  • Basic version control features.
  • Requires manual enforcement of brand standards.
Customization
  • Highly customizable.
  • Supports custom workflows and automation.
  • Flexible UI to match organizational needs.
  • Customizable but needs technical expertise.
  • Customizable document libraries and workflows.
  • Requires knowledge of Microsoft Power Platform for advanced customization.
User Interface
  • Intuitive for creatives.
  • User-friendly for media-heavy teams.
  • Tailored interfaces for different user roles.
  • Familiar to Microsoft users.
  • Consistent experience across Microsoft tools.
  • Customizable UI but less intuitive for non-document management.
Cost
  • Can be costly depending on the scale and features required.
  • Starting from approx $89 to $10,000+ per month.
  • Generally lower cost, especially for organizations already using Microsoft products.
  • Starting from approx $5 to $35 per user per month.
Scalability
  • Scales with growing asset libraries.
  • Supports large-scale media operations.
  • Adaptable to increasing asset types and volumes.
  • Scales for document management.
  • Efficient for scaling document storage and collaboration.
  • May require third-party tools for expanded capabilities.
Benefits
  • Streamlines workflows, ensures brand consistency.
  • Enhances efficiency in media production and distribution.
  • Facilitates centralized control over brand assets.
  • Enhances collaboration, integrates with Microsoft.
  • Streamlines communication and document workflows.
  • Cost-effective for organizations already using Microsoft products.
Types of Assets
  • Handles high-quality multimedia.
  • Suitable for high-resolution imagery and video content.
  • Supports complex asset types like 3D models and interactive content.
  • Primarily for document files.
  • Efficient for text-based documents and spreadsheets.
  • Limited support for non-document asset types.
User Access
  • Supports specific asset permissions.
  • Role-based access for different team members.
  • Secure sharing and distribution options.
  • Strong document permissions.
  • Supports hierarchical permissions within document libraries.
  • Integrates with Active Directory for centralized access control.

Cons DAM Systems SharePoint
Cost
  • Higher costs due to specialized features.
  • Cost scales with the size of the asset library.
  • Significant investment for organizations with complex media needs.
  • Higher costs due to specialized features.
  • Cost-effective for document management.
  • Potential hidden costs for storage and advanced customization.
Complexity
  • Steeper learning curve.
  • Requires training for effective use.
  • Complexity increases with asset variety and volume.
  • Simpler but limited in asset management.
  • Scales effectively for growing media libraries.
  • Suitable for enterprises with significant media content.
Scalability
  • Overkill for basic needs.
  • Scales effectively for growing media libraries.
  • Suitable for enterprises with significant media content.
  • Limited for diverse assets.
  • Efficient for scaling document storage.
  • May require third-party solutions for managing large media files.
Challenges
  • Complex, costly for multimedia.
  • Requires careful planning for integration and migration.
  • Higher learning curve for non-creative teams.
  • Limited asset management needs customization.
  • Customization can be time-consuming and requires technical expertise.
  • May not fully support complex media workflows.

DAM vs. SharePoint: Key Considerations for Asset Management and Integration

Considerations DAM Systems SharePoint
Asset Management
  • Best for diverse digital assets.
  • Ideal for marketing, media, and creative industries.
  • Supports detailed asset categorization and retrieval.
  • Ideal for document management.
  • Efficient for managing text-based documents.
  • Supports collaborative document creation and sharing.
Integration
  • Integrates with creative tools.
  • Seamless integration with tools like Adobe Creative Suite.
  • Supports API-based integrations with various platforms.
  • Works with Microsoft Office.
  • Strong integration with Office 365 and Teams.
  • Supports third-party integrations through Microsoft AppSource.
Customization
  • Requires creative tool expertise.
  • Customizable UI and workflows.
  • Requires specialized knowledge for setup and maintenance.
  • Easier for Microsoft users.
  • Customizable document libraries and dashboards.
  • Supports advanced customization through Power Apps and Flow.

Which teams will benefit from DAM vs. SharePoint?

Teams that Benefit from DAM

Teams that Benefit from SharePoint

  • Administrative and Document Management Teams: Best for teams needing robust document management and collaboration tools.
  • IT and Operations Teams: Suitable for teams familiar with and already using Microsoft products like Office 365.
  • Project Management Teams: Ideal for those needing process automation and customizable workflows within a familiar Microsoft environment.
]]>
<![CDATA[AI-powered Metadata and Tagging in Digital Asset Management]]>https://imagekit.io/blog/ai-powered-metadata-tagging-digital-asset-management/6698be79ae01d30001bfc6a4Fri, 19 Jul 2024 07:12:05 GMT

In today's digital world, the volume of digital content created is massive. Every day, you make and receive tons of content. Keeping track of all this can become a challenging task. This is where systems like Digital Asset Management (DAM) come in handy. They act like a super-organized digital cabinet, helping you efficiently store, organize, and find your assets.

But as the volume grows, so does your pile of digital content. Even the best DAM systems can sometimes need help keeping them in order. That's where metadata and AI's use for adding metadata come into the picture.

In this article, we'll learn how organizing your digital assets with metadata can make everything easier. We'll also read about the challenges of doing it manually and how AI-powered metadata tagging can simplify workflows and unlock faster execution speed for marketing and creative teams.

Why is organization in Digital Asset Management important?

Imagine you or your team is working on a new campaign and needs quick access to images, videos, and documents. If everything is scattered, they waste valuable time searching for the right assets, leading to delays and frustration. But when everything is well-organized, it's easy to find, use, and repurpose assets. This organization boosts productivity and helps things run smoothly. Efficient organization is the key to a successful Digital Asset Management system.

So, how do you keep everything organized and easy to find? That's where metadata comes in.

What is the role of metadata in Digital Asset Management?

Metadata in Digital Asset Management (DAM) is the additional information that describes your digital assets, making it easier to organize, find, and use them effectively.

While you can always organize files into folders, there are often pieces of information that cannot be stuffed into the file or folder name. In such cases, metadata acts like a label on your assets, providing details such as the product color, brand name, asset type, platform for use, size, keywords, creation date, etc.

For example, you could have a file stored in the folder path `/shoes/nike/SKU1234.jpg` and can have additional information like `brand: Nike`, `color: Black`, `type: Running Shoe`, etc. associated with the image. This way, the information needed to organize and search assets gets divided into the folder path and the metadata, keeping things clean. It helps maintain order and clarity when managing various types of content.

Later, when you have to search for assets, combining these pieces of information using the DAM's search capabilities makes it a lot easier. For example, you can easily find content in video format for Puma and Basketball shoes, in red color, without having to navigate through multiple folders. You can find it by querying the correct metadata fields.

Standardizing these details ensures consistency and enhances the efficiency of your digital asset management system.

Types of Metadata in Digital Asset Management

Now that we have a glimpse of the role of metadata in asset organization and search let's dive a little deeper to understand the different types of metadata in digital asset management. The benefits of metadata will become even more evident.

1. Inherited Metadata

Inherited metadata is the information that comes with an asset automatically. For example, each asset has a type, such as an image or video, and a format, like JPG, MP4, PNG, etc. There is also information such as file size, resolution, duration in the case of videos, and more. Although you cannot see this information and do not have to add it manually, it is always there with the asset.

How this information will be used for organization and searching might not be apparent. However, in a scenario where you are looking for videos that are less than 30 seconds long and have at least 720p resolution, you are actually relying on the inherited metadata for organization and search.

2. Embedded Metadata

This is the additional information included with the asset that stays with it when it is shared. Unlike inherited metadata, it is not fundamental to defining the asset but is a part of the actual image or video asset.

For example, embedded metadata for a photograph could consist of the photographer's name, the camera used, GPS coordinates, ISO setting, copyright information, and more. You would have come across using GPS coordinates to organize photos and videos on your camera by the place where they were shot and the copyright information on stock photography websites for finding assets available for commercial use.

3. Structured Metadata

Unlike inherited or embedded metadata, which is automatically associated with the asset, structured metadata is defined externally and then associated with the assets in a Digital Asset Management system. This is the most critical component in a digital asset management (DAM) system. It allows users to create custom metadata fields according to their business needs and offers robust control over asset organization.

For example, if you sell shoes online, you could create structured metadata fields such as Brand, Color, Shoe Type, and Shoe Size to keep your asset repository organized. Or, if you sell watches, you can use structured metadata fields such as Brand, Strap Color, Dial Color, Dial Size, and Dial Shape with the assets. This flexibility of structured metadata makes it essential for better organization in a DAM system.

4. Unstructured Metadata (or Tags)

While structured metadata helps you add additional information in key-value pairs, like "Brand: Nike", unstructured metadata, as the name suggests, allows you to add more free-flowing descriptive information to the asset. Think of it as keywords or labels you assign to your assets to enhance organization and management efficiency. It is often referred to as Tags across different digital asset management software.

For example, if you have an image of a watch on a white background, you can add descriptive metadata tags to it such as "men's watch", "sporty look", "front shot", "white background", "digital display", and more. These do not follow the same structure we could enforce via structured metadata, but the descriptive tags can help find assets quickly in the future.

In the rest of the article, we will refer to structured metadata and unstructured metadata as just "metadata" and "tags" respectively, to make it easier to understand the difference.

Now that we have covered different types of metadata, let's look at how to add it and, more importantly, how AI can help add metadata and make asset organization even better.

Adding metadata manually to digital assets

Traditionally, adding metadata or tags involves manually adding them to the assets. You carefully review each asset and decide on the appropriate metadata and tags. While you can build checks and balances around this process, this takes time and creates less uniformity, as teammates might use different tags and values, knowingly or accidentally, while adding them.

Challenges with manually adding metadata and tags in DAM

Adding metadata manually can be challenging as organizations grow and have more digital assets.

  1. Time-consuming: Manually adding tags and metadata to thousands of digital assets can take a lot of time and effort, which could be utilized for other essential tasks.
  2. Inconsistent metadata: Different teammates may describe the same asset differently, creating a messy and confusing organizational system. As the volume of digital assets increases, keeping metadata and tags accurate and consistent becomes even more challenging with manual processes.
  3. Poor Search:  If tags and metadata aren't added correctly, finding specific assets within the DAM system can be difficult, making them useless.

These challenges show a need for a better way to tag metadata. That's where AI-powered metadata and tagging in Digital Asset Management come into play, offering the smartest, fastest way to manage digital assets effectively.

AI-powered metadata and tags in DAM

Artificial Intelligence (AI) has revolutionized how we organize and search for digital assets. AI can automatically analyze and tag digital content using machine learning algorithms. For example, you can give an image named `DSC1234.jpg` to the AI algorithm, which can still identify that the image contains a person wearing a shoe next to a car.

As a result, digital assets can be tagged accurately without manual input by understanding their content and context. Automating the process saves time and ensures that metadata and tags are consistent and precise across all assets.

Benefits of AI-powered metadata tagging process in DAM

AI-powered tagging of assets with the right metadata and tags is a game-changer for businesses, greatly simplifying digital asset organization, search, and consumption.

  1. Better Organization: With AI being used to add metadata and tags to assets, tagging becomes more accurate and consistent. For example, AI would always tag a beach as a "Beach" and not make spelling mistakes or use alternatives such as "Shore", "Sand", etc.
  2. Improved workflow: When adding the correct tags and metadata, what would take individual team members a few minutes to do, AI can do the same in seconds, allowing members to focus on more critical tasks, boost productivity, and streamline their workflow.
  3. Easier Search: With AI working behind the scenes to always add relevant metadata and tags, you can be assured that your assets are organized well, making it easy to locate them in the future. This increases asset reuse and saves time when launching new campaigns.

Structured metadata and AI-powered tagging in ImageKit DAM

ImageKit offers a complete, modern-day Digital Asset Management solution for high-growth businesses that want a powerful DAM system that is easy to use and cost-effective.

Among the several features it offers for digital asset management, organization, and collaboration, the ability to add structured metadata, manual tags, and AI-powered tags stands out in helping improve asset organization. With its AI-powered search, marketing and creative teams find it really easy to find the right assets when they need them to launch new campaigns or share with other teams.

Structured metadata in ImageKit

ImageKit DAM allows you to add structured metadata to your assets through the "Custom Metadata" feature.

With this feature, you can define multiple fields of different types, such as Date, Number, Single-select, Multi-select, Free text, and more, and associate them with all the assets in your asset repository.

You can also associate some default values with these fields, set them when uploading assets, or edit these values at any point later. For example, in the image below we have custom metadata fields "Brand", "Country", "Sale", "Rating", and more associated with the image.

AI-powered Metadata and Tagging in Digital Asset Management
Structured metadata in ImageKit DAM with the Custom Metadata feature

Manual and AI tagging in ImageKit

ImageKit provides manual and AI-powered tagging in its digital asset management software.

The process for manual tagging is straightforward. You can add these tags to a single file or multiple files in one go, at the time of upload, or at any time later.

However, the best part is the AI tagging of the assets. ImageKit integrates with leading third-party services, such as AWS Image Rekognition and Google Cloud Vision, to automatically add tags to images uploaded to the DAM. You can trigger these AI tagging services at any time for an asset and set a threshold to the number of tags and the confidence score when adding a tag to ensure that only the right tags get added.

In the example below, we can see that ImageKit used the AI services to add keywords like "Home Decor", "Table", and "Coffee Table" to the image, all of which are very relevant.

AI-powered Metadata and Tagging in Digital Asset Management
AI-powered tags as metadata in ImageKit's Digital Asset Management system

You can also turn on AI tagging for all assets uploaded to the DAM by default. With this setting enabled, whenever anyone uploads an image to the DAM, ImageKit will automatically analyze these images using the AI services and add the relevant tags to them.

AI tagging of assets in ImageKit

You can always combine manual and AI tagging for the same asset. You could also use a manual quality check for the tags added by AI to ensure the asset's organization. This process would still be faster than adding all the tags manually.

With automatic AI tagging, asset organization is greatly simplified and consistent and saves your team a lot of manual effort and time to organize the assets correctly.

Search using metadata, tags, and AI tags in ImageKit

ImageKit's advanced search mode allows you to combine multiple parameters, including inherited metadata, embedded metadata, custom-defined metadata, and all the tags, to find the right assets in one go.

For example, I can use the advanced search to find all images (inherited metadata), created after 1 January 2024 (embedded metadata) (custom metadata)for the Nike brand and a front shot of the shoe (tag or unstructured metadata).

AI-powered Metadata and Tagging in Digital Asset Management

The ability to combine all kinds of metadata to search for the right asset makes life easier for your marketing and creative teams. They don't have to waste hours or go through several folders searching for the right assets when launching campaigns.

Bonus: AI-powered search that doesn't require metadata or tagging

ImageKit also offers text-based and reverse-image AI search to find assets, even if no metadata or tag is associated with them in the DAM.

For example, one could type a query in natural language like a "boy in sneakers" and ImageKit's AI will find all the images that visually match this description, even if their filename, metadata, or tags do not contain any such information.

AI-powered Metadata and Tagging in Digital Asset Management

To give an example of how reverse-image search helps, you could upload an ad banner and use the reverse-image search to find all other ads that look similar to it without having to query for any metadata or tags.

While we do not recommend using this as an absolute substitute for AI tagging or metadata in digital asset management, it is still beneficial when you quickly want to find something visually similar to what you have in mind.

Conclusion

Metadata and Tagging in digital asset management help organize and find digital assets in DAM software. With AI, businesses can automate the process of tagging these assets with the correct information, thereby saving manual efforts, getting more consistent organization, improving searchability, and making workflows more efficient.

ImageKit DAM's custom metadata and AI-powered tagging features unlock the same benefits for marketing and creative teams globally. You can sign up for a Forever Free account today to use the ImageKit DAM and improve how you manage digital assets for your organization.

]]>