Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8b95cad
Astro SDK for Imagekit.io
SwarnimDoegar Apr 9, 2026
52ce71e
Merge branch 'main' of https://github.com/imagekit-developer/imagekit…
SwarnimDoegar Apr 9, 2026
9e04959
Fix CI issues
SwarnimDoegar Apr 9, 2026
443d20c
Update README
SwarnimDoegar Apr 9, 2026
e2be15f
Resolve Copilot review comments
SwarnimDoegar Apr 12, 2026
b79764d
1. Get rid IKImage Component
SwarnimDoegar Apr 14, 2026
8b19755
Rename components
SwarnimDoegar Apr 15, 2026
df9df62
Add external image service for astro imagekit url building
SwarnimDoegar Apr 16, 2026
9dce131
Update READMEs
SwarnimDoegar Apr 16, 2026
331077f
Add upload support
SwarnimDoegar Apr 17, 2026
6a0001b
Add upload example in test-app
SwarnimDoegar Apr 17, 2026
e359cef
Add function to scale dimensions for images over 25MP
SwarnimDoegar Apr 19, 2026
e0722ab
Remove tgz
SwarnimDoegar Apr 20, 2026
8644fd9
Minor improvements
SwarnimDoegar Apr 20, 2026
ebd15c7
Adds more tests
SwarnimDoegar Apr 21, 2026
cdd07d4
Get rid of getInt from codebase
SwarnimDoegar Apr 22, 2026
866a986
Fix claude comments
SwarnimDoegar Apr 22, 2026
e63ad2f
Add test mastix for astro 3 4 5 6
SwarnimDoegar Apr 22, 2026
e38fd9b
Add output type to test-app astro config
SwarnimDoegar Apr 22, 2026
80132cc
Do not fail because of upload missing keys in CI
SwarnimDoegar Apr 22, 2026
5331616
Split dependency installation command into 2
SwarnimDoegar Apr 22, 2026
10ae05b
use output: 'static' as 'hybrid' output is deprecated
SwarnimDoegar Apr 22, 2026
7640946
Use node 22 for CI
SwarnimDoegar Apr 22, 2026
0a1bac4
Remove debug log
SwarnimDoegar Apr 22, 2026
1d29fd4
Resolve copilot comments
SwarnimDoegar Apr 23, 2026
aaf5367
Fix snapshots
SwarnimDoegar Apr 23, 2026
c9c3d18
Fix bug with reading env vars
SwarnimDoegar Apr 24, 2026
099a8fa
Resolve comments
SwarnimDoegar Apr 29, 2026
01c4c0e
Allow user specific srcset override
SwarnimDoegar Apr 29, 2026
9c11fee
Fix types
SwarnimDoegar Apr 29, 2026
099c233
refactor: remove unused fixtures and tests, update image handling
manu4543 May 3, 2026
dd8b9a7
fix: add image layout configuration to astro.config.mjs
manu4543 May 3, 2026
488386a
feat(image-service): add getSrcSet and simplify transformation pipeline
manu4543 May 3, 2026
45d7b11
feat(video): pick up urlEndpoint from integration config via virtual …
manu4543 May 3, 2026
f5c18bd
refactor(astro-sdk): tighten config resolution, types, helpers; drop …
manu4543 May 4, 2026
1d72ce2
Updated snapshot with correct quality mapping as per Astro defaults
manu4543 May 4, 2026
815de3d
feat(integration): host-aware routing with sharp delegation for non-I…
manu4543 May 4, 2026
208a707
feat(ci): add CI workflow for build and E2E testing; remove old npm p…
manu4543 May 4, 2026
dbd1de4
feat(docs): add instructions for loading images from ImageKit Media L…
manu4543 May 4, 2026
ed2f88b
feat(og-image): introduce <OgImage> component for Open Graph meta tag…
manu4543 May 4, 2026
66713bc
fix(docs): clarify collection definition and filter image files in RE…
manu4543 May 4, 2026
67c1c31
feat(docs): update README to clarify collection definition and filter…
manu4543 May 4, 2026
8eea86b
refactor(docs): clean up styles in image and video test pages
manu4543 May 5, 2026
be915aa
Update snapshots for Markdown and Videos component tests to include d…
manu4543 May 5, 2026
b774a0c
fix(package): update default export path in package.json to point to …
manu4543 May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI

on: [push, pull_request]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version: [22.x]
astro-version: ["3", "4", "5", "6"]
include:
- astro-version: "3"
node-adapter: "@astrojs/node@^6"
- astro-version: "4"
node-adapter: "@astrojs/node@^8"
- astro-version: "5"
node-adapter: "@astrojs/node@^9"
- astro-version: "6"
node-adapter: "@astrojs/node@^10"

steps:
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build
run: pnpm build

- name: Pack the package
run: |
cd imagekit-astro
pnpm pack

- name: Setup test-app with packed package and target Astro version
run: |
cd test-app
pnpm remove @imagekit/astro || true
pnpm add ../imagekit-astro/imagekit-astro-*.tgz
pnpm add astro@${{ matrix.astro-version }}
pnpm add ${{ matrix.node-adapter }}

- name: Install Playwright
run: |
cd test-app
pnpm exec playwright install --with-deps

- name: Run E2E tests
run: |
cd test-app
pnpm test:e2e
env:
CI: true
ASTRO_VERSION: ${{ matrix.astro-version }}
52 changes: 52 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Publish

on:
release:
types: [published]

permissions:
contents: read
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Install
run: pnpm install --frozen-lockfile

- name: Build SDK
run: pnpm --filter @imagekit/astro build

- name: Stage README and LICENSE into package
run: |
cp README.md imagekit-astro/README.md
cp LICENSE imagekit-astro/LICENSE

- name: NPM Publish
working-directory: imagekit-astro
run: |
npm whoami
VERSION=$(node -p "require('./package.json').version")
# Stable versions go to "latest", pre-release versions go to "beta"
if [[ "$VERSION" =~ ^[^-]+$ ]]; then
NPM_TAG="latest"
else
NPM_TAG="beta"
fi
echo "Publishing $VERSION with $NPM_TAG tag."
npm publish --tag $NPM_TAG --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
CI: true
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Dependencies
node_modules/

# Build output
dist/

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Environment
.env
.env.local
.env.*.local

# Astro
.astro/

# Test artifacts
test-results/
playwright-report/
coverage/
imagekit-astro/imagekit-astro-*.tgz
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) ImageKit Private Limited 2025

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
128 changes: 127 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,127 @@
Imagekit Astro
[<img width="250" alt="ImageKit.io" src="https://raw.githubusercontent.com/imagekit-developer/imagekit-javascript/master/assets/imagekit-light-logo.svg"/>](https://imagekit.io)

# ImageKit.io Astro SDK

[![npm version](https://img.shields.io/npm/v/@imagekit/astro)](https://www.npmjs.com/package/@imagekit/astro)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Twitter Follow](https://img.shields.io/twitter/follow/imagekitio?label=Follow&style=social)](https://twitter.com/ImagekitIo)

## Introduction

ImageKit Astro SDK plugs ImageKit.io into Astro's built-in image pipeline. It allows you to:

- Render images with Astro's `<Image />` and `<Picture />` components, served from ImageKit with automatic optimization, responsive `srcset`, and lazy loading.
- Apply real-time transformations (resize, crop, focus, quality, format) using URL parameters.
- Apply AI-powered transformations such as background removal, generative fill, and smart cropping via the `transformation` prop.
- Render optimized `<Video />` tags backed by ImageKit.
- Generate OpenGraph / Twitter Card meta tags pointing to ImageKit URLs with the `<OgImage>` component (or the `getOgImageUrl()` helper for custom layouts).
- Generate server-side upload authentication parameters with `getUploadAuthParams()`.

## How it works

The SDK ships as an Astro **integration** that registers a custom **image service**. Once added to `astro.config.mjs`, it takes over Astro's image pipeline for the whole site — `<Image />`, `<Picture />`, `getImage()`, and even markdown `![]()` images all flow through it.

The service is **host-aware**. For each image, it inspects the `src` and routes the request to one of two backends:

1. **ImageKit fast-path** — when `src` is an ImageKit URL (your `urlEndpoint` host, any `additionalEndpoints` host, or a bare path like `"folder/photo.jpg"`), the service builds an ImageKit URL with the requested transformations and points the browser at `https://ik.imagekit.io/...` directly. No server processing, no `/_image` round-trip — just a CDN-cached URL with `?tr=...` parameters.

2. **Sharp fallback** — when `src` is a local Astro asset (`import` of an image, or markdown `![](../foo.jpg)`) or an absolute URL on a non-ImageKit host (e.g. an allow-listed third-party domain), the service delegates to Astro's bundled sharp service. The image is processed at build time (or on-demand by Astro's `/_image` endpoint in SSR) exactly as if you had no integration installed.

This means you can drop the integration into an existing Astro project without breaking any of its existing local-asset usage. Local assets keep working via sharp; ImageKit URLs get the full ImageKit treatment.

## Installation

```bash
npm install @imagekit/astro
```

If you call `upload()` (or other helpers) from `@imagekit/javascript` directly in your code, also add it to your project so strict package managers (e.g. pnpm) can resolve it:

```bash
npm install @imagekit/javascript
```

## TypeScript support

The SDK is written in TypeScript and ships with full type definitions. The integration uses Astro's [`injectTypes()`](https://docs.astro.build/en/reference/integrations-reference/#injecttypes-option) helper to register ImageKit-specific props (`urlEndpoint`, `transformation`, `queryParameters`, `transformationPosition`) on the `Astro.CustomImageProps` namespace, so `<Image />`, `<Picture />`, and `getImage()` get full autocomplete and type-checking for these props.

Run `astro sync` (or start the dev server) once after installing so Astro picks up the injected types. For editor support in `.astro` files, install the [Astro VS Code extension](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode); for type-checking from the CLI, use [`@astrojs/check`](https://www.npmjs.com/package/@astrojs/check).

## Loading images from your ImageKit Media Library

You can use [Astro Content Collections](https://docs.astro.build/en/guides/content-collections/) together with the [`@imagekit/nodejs`](https://www.npmjs.com/package/@imagekit/nodejs) SDK to power gallery/listing pages directly from your ImageKit Media Library, without hand-maintaining a list of URLs.

Install the Node SDK as a dev dependency (it's only used at build time):

```bash
npm install -D @imagekit/nodejs
```

Define a collection backed by `client.assets.list()`. The Node SDK returns an array of `File | Folder` objects directly, so pass `type: 'file'` to exclude folders and `fileType: 'image'` to limit results to images. Shape each entry as `{ id, ...data }` — Astro's content layer treats the top-level `id` as the entry key and validates everything else against your `schema`:

```ts
// src/content.config.ts
import { defineCollection } from 'astro:content';
import { z } from 'astro/zod';
import ImageKit from '@imagekit/nodejs';
import type { Files } from '@imagekit/nodejs/resources/files/files';

const client = new ImageKit({
privateKey: import.meta.env.IMAGEKIT_PRIVATE_KEY,
});

const gallery = defineCollection({
loader: async () => {
const assets = await client.assets.list({
type: 'file', // exclude folders
fileType: 'image', // only image files
skip: 0,
limit: 50,
});

return assets
.filter((asset): asset is Files.File =>
asset.type === 'file' && !!asset.fileId && !!asset.url
)
.map((asset) => ({
id: asset.fileId ?? '',
url: asset.url ?? '',
width: asset.width ?? 0,
height: asset.height ?? 0,
name: asset.name ?? '',
tags: asset.tags ?? [],
}));
},
schema: z.object({
url: z.string().url(),
width: z.number(),
height: z.number(),
name: z.string(),
tags: z.array(z.string()),
}),
});

export const collections = { gallery };
```

After adding the collection, run `astro sync` (or start the dev server) so Astro generates the collection types used by `getCollection()`.

Render with `<Image>` from `astro:assets` — the integration's image service generates the IK CDN URL with the correct transformations:

```astro
---
import { Image } from 'astro:assets';
import { getCollection } from 'astro:content';

const photos = await getCollection('gallery');
---
{photos.map(({ data }) => (
<Image src={data.url} width={data.width} height={data.height} alt={data.name} />
))}
```

> Keep your `privateKey` in a server-only env var (e.g. `IMAGEKIT_PRIVATE_KEY` in `.env`, never prefixed with `PUBLIC_`). Collection loaders run at build time (or in SSR endpoints), never in the browser.

## Documentation

Refer to the ImageKit [official documentation](https://imagekit.io/docs/integration/astro) for setup instructions, configuration options, and the full API reference.
6 changes: 6 additions & 0 deletions imagekit-astro/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Build output
dist/

# Staged at publish time from monorepo root
README.md
LICENSE
13 changes: 13 additions & 0 deletions imagekit-astro/astro.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// <reference types="astro/client" />

declare module '*.astro' {
const component: (props: any) => any;
export default component;
}

declare module 'virtual:@imagekit/astro/config' {
export const urlEndpoint: string;
export const transformationPosition: 'path' | 'query';
const config: { urlEndpoint: string; transformationPosition: 'path' | 'query' };
export default config;
}
9 changes: 9 additions & 0 deletions imagekit-astro/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Components
export { default as Video } from './src/components/Video.astro';
export { default as OgImage } from './src/components/OgImage.astro';

// Helpers
export { getOgImageUrl } from './src/helpers';

// Types - Astro SDK types
export type { OgImageProps, OgImageUrlOptions, VideoProps } from './src/types/index';
Loading
Loading