Getting started

Integration & migration

Image & video API

DAM user guide

API overview

Account

Ruby on Rails Integration

Integrate ImageKit into Rails with view helpers and Active Storage for seamless image and video handling.

•

The ImageKit Rails gem provides seamless integration with Ruby on Rails applications. It includes view helpers for generating responsive image and video tags with transformations, Active Storage service for storing files in ImageKit, and automatic responsive image generation with srcset.

The gem works with all Active Storage features like has_one_attached and has_many_attached, and provides dedicated view helpers (ik_image_tag and ik_video_tag) that handle URL generation, transformations, and responsive images automatically.

For complete API documentation and source code, see the ImageKit Rails gem on GitHub.

Rubydoc references:

Installation

Add the ImageKit Rails gem to your Gemfile:

Copy
gem 'imagekitio',
gem 'imagekitio-rails'

Run bundle install:

Copy
bundle install

Create config/initializers/imagekit.rb with your credentials from the ImageKit dashboard:

Copy
Imagekit::Rails.configure do |config|
  config.url_endpoint = ENV['IMAGEKIT_URL_ENDPOINT']   # https://ik.imagekit.io/your_imagekit_id
  config.public_key = ENV['IMAGEKIT_PUBLIC_KEY']
  config.private_key = ENV['IMAGEKIT_PRIVATE_KEY']
  
  # Optional defaults
  # config.transformation_position = :query  # or :path
  # config.responsive = true                 # Enable responsive images by default
end

View helpers

The Rails gem provides ik_image_tag and ik_video_tag helpers that work like Rails' built-in image_tag and video_tag but with ImageKit transformations and responsive image support.

Basic image tag

Use ik_image_tag in your views to display images:

Copy
<!-- Basic image -->
<%= ik_image_tag("/photo.jpg", alt: "My Photo") %>

<!-- With transformations -->
<%= ik_image_tag("/photo.jpg", transformation: [{ width: 400, height: 300 }], alt: "Resized Photo") %>

<!-- With standard HTML attributes -->
<%= ik_image_tag("/photo.jpg", class: "rounded shadow", alt: "Styled Photo") %>

Image transformations

Apply transformations using the transformation parameter:

Copy
<!-- Resize and crop -->
<%= ik_image_tag("/photo.jpg", transformation: [{ 
  width: 400, 
  height: 300, 
  crop: "at_max"
}]) %>

<!-- Border and radius -->
<%= ik_image_tag("/photo.jpg", transformation: [{ 
  radius: 20,
  border: "3_FF0000"
}]) %>

Chained transformations

Apply multiple transformations in sequence:

Copy
<%= ik_image_tag("/photo.jpg", transformation: [
  { width: 400, height: 300, crop: "at_max" },
  { rotation: 90 },
  { blur: 5, grayscale: true }
]) %>

Responsive images

Responsive images with srcset are enabled by default. The helper automatically generates multiple image sizes:

Copy
<!-- Automatic responsive images -->
<%= ik_image_tag("/photo.jpg", width: 800, sizes: "(max-width: 600px) 100vw, 800px") %>

<!-- Disable responsive images for specific cases -->
<%= ik_image_tag("/photo.jpg", responsive: false) %>

<!-- Advanced responsive setup with transformations -->
<%= ik_image_tag(@product.featured_image, 
  width: 800,
  sizes: "(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 800px",
  transformation: [{ quality: 85, format: "auto" }],
  alt: @product.name
) %>

Lazy loading

Images are lazy-loaded by default:

Copy
<!-- Default lazy loading -->
<%= ik_image_tag("/photo.jpg") %>

<!-- Eager loading for above-the-fold images -->
<%= ik_image_tag("/hero.jpg", loading: "eager") %>

Video tags

Use ik_video_tag for video content:

Copy
<!-- Basic video -->
<%= ik_video_tag("/video.mp4", controls: true) %>

<!-- With transformations -->
<%= ik_video_tag("/video.mp4", 
  transformation: [{ width: 640, height: 480 }],
  controls: true,
  autoplay: true,
  muted: true
) %>

Overlays

Add text or image overlays to your images:

Text overlay

Copy
<%= ik_image_tag("/background.jpg", transformation: [{
  overlay: {
    type: "text",
    text: "Hello World",
    transformation: [{ 
      fontSize: 50, 
      fontColor: "FFFFFF",
      fontFamily: "Arial",
      typography: "b"
    }]
  }
}]) %>

Image overlay

Copy
<%= ik_image_tag("/background.jpg", transformation: [{
  overlay: {
    type: "image",
    input: "logo.png",
    transformation: [{ width: 100, height: 100 }],
    position: { x: 10, y: 10 }
  }
}]) %>

Watermark example

Copy
<%= ik_image_tag("/product.jpg", transformation: [{
  overlay: {
    type: "image",
    input: "watermark.png",
    transformation: [{ width: 150, opacity: 70 }],
    position: { focus: "bottom_right" }
  }
}]) %>

AI transformations

Use ImageKit's AI-powered transformations:

Copy
<!-- Background removal -->
<%= ik_image_tag("/photo.jpg", transformation: [{ aiRemoveBackground: true }]) %>

<!-- Upscaling -->
<%= ik_image_tag("/small-photo.jpg", transformation: [{ aiUpscale: true }]) %>

<!-- AI drop shadow -->
<%= ik_image_tag("/logo.png", transformation: [{ aiDropShadow: true }]) %>

Signed URLs

Generate signed URLs for secure content delivery:

Copy
<!-- Image with signature that expires in 1 hour -->
<%= ik_image_tag("/private/photo.jpg", signed: true, expires_in: 3600) %>

<!-- Video with signature -->
<%= ik_video_tag("/private/video.mp4", signed: true, expires_in: 3600, controls: true) %>

Active Storage integration

ImageKit integrates seamlessly with Rails Active Storage, allowing you to store attachments in ImageKit while maintaining Active Storage's familiar API.

Configuration

Add ImageKit as a storage service in config/storage.yml:

Copy
imagekit:
  service: ImageKit

Override credentials per environment

By default, the Active Storage service uses credentials from your global configuration (config/initializers/imagekit.rb). You can optionally override these credentials in storage.yml to use different ImageKit accounts for different environments:

Copy
# Use global configuration (most common)
imagekit:
  service: ImageKit

# Override with environment-specific credentials
imagekit_production:
  service: ImageKit
  private_key: <%= ENV['IMAGEKIT_PRODUCTION_PRIVATE_KEY'] %>
  public_key: <%= ENV['IMAGEKIT_PRODUCTION_PUBLIC_KEY'] %>
  url_endpoint: <%= ENV['IMAGEKIT_PRODUCTION_URL_ENDPOINT'] %>

imagekit_staging:
  service: ImageKit
  private_key: <%= ENV['IMAGEKIT_STAGING_PRIVATE_KEY'] %>
  public_key: <%= ENV['IMAGEKIT_STAGING_PUBLIC_KEY'] %>
  url_endpoint: <%= ENV['IMAGEKIT_STAGING_URL_ENDPOINT'] %>

Then reference the specific service in your environment config:

Copy
# config/environments/production.rb
config.active_storage.service = :imagekit_production

# config/environments/staging.rb
config.active_storage.service = :imagekit_staging

Note: If credentials are provided in storage.yml, they take precedence over the global configuration. If not provided, the service falls back to the global configuration.

Set ImageKit as your storage service:

Copy
# config/environments/production.rb
config.active_storage.service = :imagekit

# config/environments/development.rb
config.active_storage.service = :local  # Keep local storage for development

File attachments

Use Active Storage's attachment methods in your models:

Copy
# app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
  has_many_attached :photos
end
Copy
# app/models/product.rb
class Product < ApplicationRecord
  has_one_attached :featured_image
  has_many_attached :gallery_images
end

Upload files

Create forms to upload files:

Copy
<!-- app/views/users/edit.html.erb -->
<%= form_with model: @user do |form| %>
  <div>
    <%= form.label :avatar, "Profile Picture" %>
    <%= form.file_field :avatar %>
  </div>
  <%= form.submit "Update Profile" %>
<% end %>

Handle uploads in controllers:

Copy
# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def update
    @user = current_user
    if @user.update(user_params)
      redirect_to @user, notice: "Profile updated!"
    else
      render :edit
    end
  end
  
  private
  
  def user_params
    params.require(:user).permit(:name, :avatar)
  end
end

Display attachments

Use ik_image_tag with Active Storage attachments:

Copy
<!-- User avatar with transformations -->
<%= ik_image_tag(@user.avatar, transformation: [
  { width: 200, height: 200, crop: "at_max" },
  { radius: "max" }
], alt: @user.name) %>

<!-- Product images -->
<% @product.gallery_images.each do |image| %>
  <%= ik_image_tag(image, transformation: [
    { width: 400, height: 400, crop: "at_max" },
    { quality: 85 }
  ]) %>
<% end %>

Getting URLs programmatically

For views, always use ik_image_tag (covered above). However, if you need raw URLs for non-view contexts like APIs, background jobs, mailers, or JSON responses, access the service directly:

Copy
# Get URL for an attachment
url = @user.avatar.service.url(@user.avatar.blob.key)
# => "https://ik.imagekit.io/your_id/abc123xyz"

# With transformations
url = @user.avatar.service.url(
  @user.avatar.blob.key,
  transformation: [{ width: 200, height: 200 }]
)
# => "https://ik.imagekit.io/your_id/abc123xyz?tr=w-200,h-200"

Example: In a JSON API response

Copy
# app/controllers/api/users_controller.rb
def show
  render json: {
    user: {
      name: @user.name,
      avatar_url: @user.avatar.service.url(
        @user.avatar.blob.key,
        transformation: [{ width: 150, height: 150, crop: "thumb" }]
      )
    }
  }
end

Example: In a mailer

Copy
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  def welcome_email(user)
    @avatar_url = user.avatar.service.url(
      user.avatar.blob.key,
      transformation: [{ width: 100, height: 100 }]
    )
    mail(to: user.email, subject: "Welcome!")
  end
end

Check if file is attached

Copy
<% if @user.avatar.attached? %>
  <%= ik_image_tag(@user.avatar, transformation: [{ width: 200, height: 200 }]) %>
<% else %>
  <%= ik_image_tag("/placeholder.jpg", transformation: [{ width: 200, height: 200 }]) %>
<% end %>

Delete attachments

Copy
# In your controller
@user.avatar.purge       # Delete immediately
@user.avatar.purge_later # Delete via background job (recommended)

Direct uploads

Active Storage's DirectUpload feature (client-side uploads) is not supported with ImageKit because ImageKit uses PUT requests while Active Storage uses multipart/form-data POST requests. Files must be uploaded through your Rails server.

Organizing files in folders

ImageKit stores files using their Active Storage keys as complete file paths. Each attachment automatically gets organized based on its model, attribute, and ID.

For example, a user's avatar is stored at a path like /active_storage/attachments/123/avatar-filename.jpg where the key becomes the complete file path in ImageKit.

This organization happens automatically and doesn't require any configuration. If you need custom folder organization, you can customize the Active Storage key generation in your Rails application.

Migrating from Active Storage variants

If you're migrating from local/S3 storage and currently using Active Storage's .variant() method, you should convert them to ImageKit transformations for better performance.

Why avoid variants with ImageKit?

While variants technically work with ImageKit, they're extremely inefficient:

  1. Downloads the original file from ImageKit to your server
  2. Processes it on your server (using ImageMagick/libvips)
  3. Re-uploads the processed version back to ImageKit

This wastes bandwidth, server resources, and time. ImageKit's transformations happen instantly on ImageKit's servers without any round-trips.

Migration examples

Convert your existing variant calls to ik_image_tag with transformations:

Copy
<!-- Before: Using variants (slow with ImageKit) -->
<%= image_tag @photo.variant(resize_to_fill: [400, 300]) %>
<%= image_tag @photo.variant(resize_to_limit: [800, 600]) %>
<%= image_tag @avatar.variant(resize_and_pad: [200, 200, background: [255, 255, 255]]) %>

<!-- After: Using ImageKit transformations (instant, no server processing) -->
<%= ik_image_tag(@photo, transformation: [{ width: 400, height: 300, crop: "fill" }]) %>
<%= ik_image_tag(@photo, transformation: [{ width: 800, height: 600 }]) %>
<%= ik_image_tag(@avatar, transformation: [{ 
  width: 200, 
  height: 200, 
  crop: "pad_resize",
  background: "FFFFFF"
}]) %>

Common variant conversions

Active Storage VariantImageKit Transformation
resize_to_fill: [w, h]{ width: w, height: h, crop: "fill" }
resize_to_limit: [w, h]{ width: w, height: h }
resize_to_fit: [w, h]{ width: w, height: h, crop: "at_max" }
resize_and_pad: [w, h, background: color]{ width: w, height: h, crop: "pad_resize", background: "RRGGBB" }

Important notes

  • Don't use .variant() with ImageKit attachments
  • Always use ik_image_tag instead of image_tag for ImageKit attachments
  • ImageKit transformations are applied on-the-fly at the CDN edge
  • No server processing or storage needed for transformed images

What's next