CE.SDK can include assets from third-party libraries accessible via API. Search and browse images from Unsplash in the editor.

Prerequisites#
Before you begin, make sure you have the following:
- Node.js v20+ and npm installed locally – Download Node.js
- A supported browser – Chrome 114+, Edge 114+, Firefox 115+, Safari 15.6+
See Browser Support for the full list.
Get Started#
Create a new Next.js application with Unsplash Editor integration.
Step 1: Create a New Project#
npx create-next-app@latest your-project-name
cd your-project-namenpx create-next-app@latest your-project-name
cd your-project-namepnpm create next-app your-project-name
cd your-project-namepnpm create next-app your-project-name
cd your-project-nameyarn create next-app your-project-name
cd your-project-nameyarn create next-app your-project-name
cd your-project-nameStep 2: Clone the Starter Kit#
Clone the starter kit and copy the editor configuration to your project:
git clone https://github.com/imgly/starterkit-unsplash-asset-source-ts-web.git
cp -r starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imgly
rm -rf starterkit-unsplash-asset-source-ts-webgit clone https://github.com/imgly/starterkit-unsplash-asset-source-ts-web.git
cp -r starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imgly
rm -rf starterkit-unsplash-asset-source-ts-webnpx degit imgly/starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imglynpx degit imgly/starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imglyStep 3: Install Dependencies#
Install the required packages for the editor:
Core Editor#
Install the Creative Editor SDK:
npm install @cesdk/cesdk-jsnpm install @cesdk/cesdk-jspnpm add @cesdk/cesdk-jspnpm add @cesdk/cesdk-jsyarn add @cesdk/cesdk-jsyarn add @cesdk/cesdk-jsUnsplash Client#
Add the official Unsplash JavaScript client:
npm install unsplash-jsnpm install unsplash-jspnpm add unsplash-jspnpm add unsplash-jsyarn add unsplash-jsyarn add unsplash-jsBackground Removal#
Add AI-powered background removal:
npm install @imgly/background-removal onnxruntime-webnpm install @imgly/background-removal onnxruntime-webpnpm add @imgly/background-removal onnxruntime-webpnpm add @imgly/background-removal onnxruntime-webyarn add @imgly/background-removal onnxruntime-webyarn add @imgly/background-removal onnxruntime-webThe onnxruntime-web package provides the machine learning runtime required for client-side AI processing.
Step 4: Download Assets#
CE.SDK requires engine assets (fonts, icons, UI elements) to function. These must be served as static files from your project’s public/ directory.
curl -O https://cdn.img.ly/packages/imgly/cesdk-js/1.73.0/imgly-assets.zip
unzip imgly-assets.zip -d public/
rm imgly-assets.zipcurl -O https://cdn.img.ly/packages/imgly/cesdk-js/1.73.0/imgly-assets.zip
unzip imgly-assets.zip -d public/
rm imgly-assets.zipStep 5: Create the Editor Component#
Create a client-side React component using the official CE.SDK React wrapper (e.g., UnsplashEditor.tsx):
'use client';
import { initUnsplashEditor } from '../imgly';import CreativeEditor from '@cesdk/cesdk-js/react';
export default function UnsplashEditor() { return ( <CreativeEditor config={{ baseURL: '/assets' }} init={initUnsplashEditor} width="100vw" height="100vh" /> );}Step 6: Use the Component#
Import and use the Unsplash Editor component in your page:
import UnsplashEditor from './components/UnsplashEditor';
export default function Page() { return <UnsplashEditor />;}SSR Error#
If you encounter the error ReferenceError: window is not defined, it means the component is being rendered on the server. CE.SDK requires browser APIs and must run client-side only.
Use Next.js dynamic imports to disable SSR for the editor component:
'use client';
import dynamic from 'next/dynamic';
const UnsplashEditor = dynamic( () => import('./components/UnsplashEditor'), { ssr: false });
export default function Page() { return <UnsplashEditor />;}Get Started#
Integrate the Unsplash Editor into an existing Next.js application. This adds the editor configuration to your current project structure.
Step 1: Clone#
cd your-projectcd your-projectClone the starter kit and copy the editor configuration to your project:
git clone https://github.com/imgly/starterkit-unsplash-asset-source-ts-web.git
cp -r starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imgly
rm -rf starterkit-unsplash-asset-source-ts-webgit clone https://github.com/imgly/starterkit-unsplash-asset-source-ts-web.git
cp -r starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imgly
rm -rf starterkit-unsplash-asset-source-ts-webnpx degit imgly/starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imglynpx degit imgly/starterkit-unsplash-asset-source-ts-web/app/imgly ./app/imglyThe imgly/ folder contains the editor configuration:
imgly/├── config/│ ├── actions.ts # Export/import actions│ ├── features.ts # Feature toggles│ ├── i18n.ts # Translations│ ├── plugin.ts # Main configuration plugin│ ├── settings.ts # Engine settings│ └── ui/│ ├── canvas.ts # Canvas configuration│ ├── components.ts # Custom component registration│ ├── dock.ts # Dock layout configuration│ ├── index.ts # Combines UI customization exports│ ├── inspectorBar.ts # Inspector bar layout│ ├── navigationBar.ts # Navigation bar layout│ └── panel.ts # Panel configuration├── index.ts # Editor initialization function└── plugins/ └── unsplash.tsStep 2: Install Dependencies#
Install the required packages for the editor:
Core Editor#
Install the Creative Editor SDK:
npm install @cesdk/cesdk-jsnpm install @cesdk/cesdk-jspnpm add @cesdk/cesdk-jspnpm add @cesdk/cesdk-jsyarn add @cesdk/cesdk-jsyarn add @cesdk/cesdk-jsUnsplash Client#
Add the official Unsplash JavaScript client:
npm install unsplash-jsnpm install unsplash-jspnpm add unsplash-jspnpm add unsplash-jsyarn add unsplash-jsyarn add unsplash-jsBackground Removal#
Add AI-powered background removal:
npm install @imgly/background-removal onnxruntime-webnpm install @imgly/background-removal onnxruntime-webpnpm add @imgly/background-removal onnxruntime-webpnpm add @imgly/background-removal onnxruntime-webyarn add @imgly/background-removal onnxruntime-webyarn add @imgly/background-removal onnxruntime-webThe onnxruntime-web package provides the machine learning runtime required for client-side AI processing.
Step 3: Download Assets#
CE.SDK requires engine assets (fonts, icons, UI elements) to function. For Next.js projects, place these in your public/ directory which is served automatically.
curl -O https://cdn.img.ly/packages/imgly/cesdk-js/1.73.0/imgly-assets.zip
unzip imgly-assets.zip -d public/
rm imgly-assets.zipcurl -O https://cdn.img.ly/packages/imgly/cesdk-js/1.73.0/imgly-assets.zip
unzip imgly-assets.zip -d public/
rm imgly-assets.zipStep 4: Create the Editor Component#
Create a client-side React component using the official CE.SDK React wrapper (e.g., UnsplashEditor.tsx):
'use client';
import { initUnsplashEditor } from '../imgly';import CreativeEditor from '@cesdk/cesdk-js/react';
export default function UnsplashEditor() { return ( <CreativeEditor config={{ baseURL: '/assets' }} init={initUnsplashEditor} width="100vw" height="100vh" /> );}Step 5: Use the Component#
Import and use the Unsplash Editor component in your page:
import UnsplashEditor from './components/UnsplashEditor';
export default function Page() { return <UnsplashEditor />;}SSR Error#
If you encounter the error ReferenceError: window is not defined, it means the component is being rendered on the server. CE.SDK requires browser APIs and must run client-side only.
Use Next.js dynamic imports to disable SSR for the editor component:
'use client';
import dynamic from 'next/dynamic';
const UnsplashEditor = dynamic( () => import('./components/UnsplashEditor'), { ssr: false });
export default function Page() { return <UnsplashEditor />;}Set Up a Scene#
CE.SDK offers multiple ways to load content into the editor. Choose the method that matches your use case:
// Create a blank design canvas - starts with an empty design sceneawait cesdk.actions.run('scene.create');
// Load from a template archive - restores a previously saved projectawait cesdk.loadFromArchiveURL('https://example.com/template.zip');
// Load from an image URL - creates a new scene with the imageawait cesdk.createFromImage('https://example.com/image.jpg');
// Load from a scene file - restores a scene from JSONawait cesdk.loadFromURL('https://example.com/scene.json');The createDesignScene() method is ideal for design workflows, as it creates a blank canvas ready for content.
Customize Assets#
The Unsplash Editor uses asset source plugins to provide built-in libraries for templates, stickers, shapes, and fonts. The starter kit includes a curated selection—customize what’s included based on your needs.
Asset sources are added via plugins in app/imgly/index.ts. Enable or disable individual sources:
import { FiltersAssetSource, StickerAssetSource, TextAssetSource, VectorShapeAssetSource, EffectsAssetSource, // ...} from '@cesdk/cesdk-js/plugins';
// Add only the sources you needawait cesdk.addPlugin(new FiltersAssetSource());await cesdk.addPlugin(new StickerAssetSource());await cesdk.addPlugin(new TextAssetSource());await cesdk.addPlugin(new VectorShapeAssetSource());await cesdk.addPlugin(new EffectsAssetSource());// ...For production deployments, self-hosting assets is required—the IMG.LY CDN is intended for development only. See Serve Assets for downloading assets, configuring baseURL, and excluding unused sources to optimize load times.
Configure Actions#
Actions are functions that handle user interactions like exporting designs, saving scenes, and importing files. CE.SDK provides built-in actions that you can run directly or override with custom implementations.
Key built-in actions:
exportDesign– Export the current design to PNG, JPEG, PDF, or other formatssaveScene– Save the scene as a JSON string for later editingimportScene– Import a previously saved scene (supports.sceneand.cesdkformats)exportScene– Export the scene as a JSON file or.cesdkarchive with all assetsuploadFile– Handle file uploads with progress tracking
Use cesdk.actions.run() to execute any action:
// Run a built-in actionawait cesdk.actions.run('exportDesign', { mimeType: 'image/png' });Import from File Picker#
// Let users open images from their devicecesdk.actions.register('importImage', async () => { const blobURL = await cesdk.utils.loadFile({ accept: 'image/*', returnType: 'objectURL' }); await cesdk.createFromImage(blobURL);});Export and Save#
// Register export action that downloads the edited designcesdk.actions.register('exportDesign', async (exportOptions) => { const { blobs, options } = await cesdk.utils.export(exportOptions); await cesdk.utils.downloadFile(blobs[0], options.mimeType);});Upload to Your Backend#
// Override the built-in exportDesign action to send to your servercesdk.actions.register('exportDesign', async (exportOptions) => { const { blobs } = await cesdk.utils.export(exportOptions);
const formData = new FormData(); formData.append('design', blobs[0], 'design.png');
const response = await fetch('/api/upload', { method: 'POST', body: formData });
const { url } = await response.json(); console.log('Uploaded to:', url);});Unsplash Integration#
The Unsplash Editor replaces the default image library with Unsplash’s extensive collection of free photos.
How It Works#
The integration uses the official unsplash-js client to fetch images from Unsplash. A custom asset source translates Unsplash API responses to CE.SDK’s asset format.
// Add Unsplash image library integration// Requires: npm install unsplash-js// Configure: Pass unsplashApiUrl option or set VITE_UNSPLASH_API_URL env varawait cesdk.addPlugin(new UnsplashAssetSourcePlugin({ apiUrl: options.unsplashApiUrl}));Search and Browse#
Users can search Unsplash’s library or browse popular images:
- Search: Type keywords to find relevant photos
- Popular: Browse trending images when no search query is entered
- Pagination: Automatically loads more results as users scroll
Attribution#
Unsplash requires photographer attribution for all images. The integration automatically includes:
- Photographer name: Displayed with each image
- Profile link: Links to the photographer’s Unsplash profile
- UTM tracking: Proper referral tracking per Unsplash guidelines
Set Up Unsplash Proxy#
For production use, you must proxy Unsplash API requests through your server. This keeps your API key secure and prevents exposure in client-side code.
Why a Proxy?#
- Security: API keys should never be in frontend code
- Rate limiting: Control and monitor API usage
- Compliance: Required by Unsplash API guidelines
Proxy Implementation#
Create a proxy endpoint that adds your API key. The starter kit includes a complete example at api/unsplash-proxy-example.ts:
// Next.js API Routeimport { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) { const apiKey = process.env.UNSPLASH_ACCESS_KEY; const { searchParams } = new URL(request.url);
const response = await fetch(`https://api.unsplash.com/photos?${searchParams}`, { headers: { Authorization: `Client-ID ${apiKey}` } });
const data = await response.json(); return NextResponse.json(data);}Configure the Proxy URL#
Set the environment variable to point to your proxy:
NEXT_PUBLIC_UNSPLASH_API_URL=https://your-domain.com/api/unsplashThen pass it to the init function:
await initUnsplashEditor(cesdk, { unsplashApiUrl: process.env.NEXT_PUBLIC_UNSPLASH_API_URL});Customize (Optional)#
Theming#
CE.SDK supports light and dark themes out of the box, plus automatic system preference detection. Switch between themes programmatically:
// 'light' | 'dark' | 'system' | (() => 'light' | 'dark')cesdk.ui.setTheme('dark');See Theming for custom color schemes, CSS variables, and advanced styling options.
Localization#
Customize UI labels and add support for multiple languages. The i18n system supports translation keys for all UI elements:
// Override specific labelscesdk.i18n.setTranslations({ en: { 'libraries.unsplash.label': 'Unsplash', 'actions.export.image': 'Download Design', 'common.cancel': 'Cancel', 'common.apply': 'Apply' }});
// Add a new languagecesdk.i18n.setTranslations({ de: { 'libraries.unsplash.label': 'Unsplash Fotos', 'actions.export.image': 'Design herunterladen' }});
// Set the active localecesdk.i18n.setLocale('de');See Localization for supported languages, translation key reference, and right-to-left language support.
UI Layout#

Customize the editor interface by modifying the dock, inspector bar, navigation bar, and canvas menu. CE.SDK provides Order APIs to control which components appear and in what sequence.
// Get current navigation bar componentsconst navOrder = cesdk.ui.getNavigationBarOrder();
// Add a custom button to the navigation barcesdk.ui.insertNavigationBarOrderComponent( 'ly.img.spacer', { id: 'my-custom-action' }, 'after');
// Rearrange dock itemscesdk.ui.setDockOrder([ 'ly.img.assetLibrary.dock', 'ly.img.separator', 'my-custom-dock-item']);
// Customize the inspector barcesdk.ui.setInspectorBarOrder([ 'ly.img.fill.inspectorBar', 'ly.img.separator', 'ly.img.filter.inspectorBar']);The Order API methods follow a consistent pattern across all UI areas:
get*Order()– Retrieve the current component orderset*Order()– Replace the entire orderinsert*OrderComponent()– Add components relative to existing ones
See Dock, Inspector Bar, Navigation Bar, Canvas Menu, and Canvas for detailed layout customization options.
Custom Components#
Build custom UI components using the builder system and integrate them in the editor. Custom components receive reactive state updates and can interact with the engine API.
// Register a custom componentcesdk.ui.registerComponent('my-custom-button', ({ builder, engine }) => { const selectedBlocks = engine.block.findAllSelected();
builder.Button('apply-effect', { label: 'Apply Effect', isDisabled: selectedBlocks.length === 0, onClick: () => { // Apply custom logic to selected blocks } });});
// Add the component to the navigation barcesdk.ui.insertNavigationBarOrderComponent( 'ly.img.spacer', 'my-custom-button', 'after');Custom components automatically re-render when the engine state they depend on changes—no manual subscription management required.
See Register New Component for the complete builder API and component patterns.
Settings & Features#
Fine-tune editor behavior through settings and features.
Settings configure core engine behavior—rendering, input handling, and history management:
cesdk.engine.editor.setSettingBool('page/dimOutOfPageAreas', true);cesdk.engine.editor.setSettingBool('mouse/enableZoomControl', true);cesdk.engine.editor.setSettingBool('features/undoHistory', true);Features toggle which editing tools and panels appear in the UI:
// Toggle editor featurescesdk.feature.enable('ly.img.crop', true);cesdk.feature.enable('ly.img.filter', true);cesdk.feature.enable('ly.img.adjustment', true);See Settings and Features for the complete reference.
Explore Plugins#
CE.SDK has a rich plugin ecosystem that extends the editor with powerful capabilities. Plugins can add new features, integrate third-party services, or customize editor behavior.
Background Removal#
Add AI-powered background removal that runs entirely in the browser without sending data to external servers.
import BackgroundRemovalPlugin from '@imgly/plugin-background-removal';
// Add background removal capabilityawait cesdk.addPlugin(BackgroundRemovalPlugin());See Background Removal for setup instructions and configuration options.
Print Ready PDF#
Export print-ready PDF/X-3 files with CMYK color profiles for professional printing workflows.
import PrintReadyPDFPlugin from '@imgly/plugin-print-ready-pdf';
// Add print-ready PDF export capabilityawait cesdk.addPlugin(PrintReadyPDFPlugin());See Print Ready PDF for setup instructions and configuration options.
AI Integration#
Extend the editor with generative AI capabilities for text-to-image generation, image enhancement, and intelligent editing features. CE.SDK integrates with various AI providers.
import AIPlugin from '@imgly/plugin-ai-generation';
// Configure AI generationawait cesdk.addPlugin(AIPlugin({ provider: 'your-ai-provider', apiKey: 'your-api-key'}));See AI Integration for provider setup and supported AI features.
Discover More Plugins#
Explore the full plugin ecosystem in the IMG.LY plugins repository. Available plugins include:
- Vectorizer – Convert raster images to vectors
- Design Presets – Pre-built design templates
- Social Media Templates – Platform-specific sizing
- And more – Check the repository for the latest additions
Key Capabilities#
The Unsplash Editor combines professional design tools with free stock photography.
Unsplash Integration
Search and use millions of free high-quality photos with automatic attribution handling.
Background Removal
AI-powered background removal that runs entirely in the browser.
Professional Filters
Apply color grading with LUT filters, duotone effects, and image adjustments.
Text & Typography
Add styled text with typography controls, fonts, and visual effects.
Multi-Page Documents
Create presentations, brochures, and multi-page designs.
Export Options
Export to PNG, JPEG, and PDF with quality and size controls.
Troubleshooting#
Unsplash images don’t load#
- Check proxy URL: Verify you’ve configured the Unsplash API proxy URL correctly
- Check console errors: Look for network errors or CORS issues
- Test proxy directly: Ensure your proxy server is running and accessible
”Unsplash API URL not configured” warning#
- Set environment variable: Set
NEXT_PUBLIC_UNSPLASH_API_URLin your.env.localfile - Pass to init function: Pass
unsplashApiUrltoinitUnsplashEditor() - For development: The demo proxy is used automatically if no URL is provided
Rate limiting errors#
- Check Unsplash rate limits: Free tier allows 50 requests per hour
- Monitor
X-Ratelimit-Remainingheader: Your proxy should forward these headers - Upgrade to production: Apply for production access at unsplash.com/developers for higher limits
Editor doesn’t load#
- Check the container element exists: Ensure your container element is in the DOM before calling
create() - Verify the baseURL: Assets must be accessible from the CDN or your self-hosted location
- Check console errors: Look for CORS or network errors in browser developer tools
Watermark appears in production#
- Add your license key: Set the
licenseproperty in your configuration - Sign up for a trial: Get a free trial license at img.ly/forms/free-trial
Next Steps#
- Custom Asset Sources – Learn how asset sources work
- Theming – Customize colors and appearance
- Localization – Add translations
- Actions – Build custom export workflows