Search
Loading...
Skip to content

New React Project without UI

This guide takes you through integrating CreativeEditor SDK (CE.SDK) Engine into a React application in “headless mode” - without the default user interface. You’ll use the powerful CE.SDK Engine directly to programmatically create and manipulate designs.

Who Is This Guide For?#

This guide is for developers who:

  • Want to build a custom UI instead of using CE.SDK’s default interface.
  • Need to use CE.SDK in automation workflows, without displaying a user-facing editor.
  • Have already followed one of the Getting Started with CE.SDK in React tutorials and want to extend their integration.

What You’ll Achieve#

  • Initialize CE.SDK’s headless engine inside a React component.
  • Programmatically create and manipulate a scene.
  • (Optionally) attach the CE.SDK canvas for rendering visuals while using your own controls.

Prerequisites#

Before you begin, ensure you meet these prerequisites:

Step 1: Set Up a New React Project#

Using a build tool like Vite, Parcel, or RSBuild is the recommended way to initialize a new React project. In this guide, you’ll use Vite.

Run the following Vite command to create a new blank React project called my-react-app:

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

Or, equivalently, on Windows:

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

A new React project will be created in the my-react-app folder. Move into the project folder in the terminal:

Terminal window
cd my-react-app

This is the file structure it should contain:

my-react-app/
├── public/ # Static assets
│ └── vite.svg # Default Vite logo
├── src/ # Source code
│ ├── assets/ # Additional static assets
│ │ └── react.svg # React logo
│ │
│ ├── App.css # Styles for the main App component
│ ├── App.jsx # Main React component
│ ├── index.css # Global styles
│ └── main.jsx # Entry point for the React app
├── .gitignore # Git ignore rules
├── eslint.config.js # ESLint configuration
├── index.html # Main HTML file (Vite entry point)
├── package.json # Project dependencies and scripts
├── README.md # Project documentation
└── vite.config.js # Vite configuration

Install the project’s dependencies via NPM with:

Terminal window
npm install

Step 2: Install the cesdk/engine package#

Add CreativeEditor SDK to your project’s dependencies by installing the @cesdk/engine NPM package:

Terminal window
npm install @cesdk/engine

Step 3: Create Your Custom Editor Component#

In the src/ folder of your new React project, create a new file named CustomEditor.jsx defining the following component:

import CreativeEngine from '@cesdk/engine';
import { useCallback, useEffect, useRef } from 'react';
const config = {
license: '<YOUR_LICENSE_KEY>', // ⚠️ REPLACE WITH YOUR ACTUAL LICENSE KEY
};
export default function CustomEditor() {
// Reference to store the DOM container where the CreativeEngine canvas will be attached
const canvasRef = useRef(null);
// Reference to store the CreativeEngine instance
const engineRef = useRef(null);
// Reference to store the the ID of the image block added to the scene
const imageBlockIdRef = useRef(null);
useEffect(() => {
CreativeEngine.init(config).then(engine => {
// Avoid initializing CreativeEngine twice in strict mode
if (!engineRef.current) {
engineRef.current = engine;
// Append CE.SDK canvas to the DOM
if (canvasRef.current) {
canvasRef.current.appendChild(engine.element);
}
// Get the current scene or create a new one
let scene = engine.scene.get();
if (!scene) {
scene = engine.scene.create();
const page = engine.block.create('page');
engine.block.appendChild(scene, page);
}
// Get the first page block
const [page] = engine.block.findByType('page');
// Append a block to show an image on the page
const imageBlockId = engine.block.create('graphic');
imageBlockIdRef.current = imageBlockId;
engine.block.setShape(imageBlockId, engine.block.createShape('rect'));
// Fill the block with an image from a public source
const imageFill = engine.block.createFill('image');
engine.block.setSourceSet(imageFill, 'fill/image/sourceSet', [
{
uri: 'https://img.ly/static/ubq_samples/sample_1_1024x683.jpg',
width: 1024,
height: 683,
},
]);
engine.block.setFill(imageBlockId, imageFill);
engine.block.appendChild(page, imageBlockId);
// Zoom to fit the page in the editor view
engine.scene.zoomToBlock(page);
}
});
// Dispose of the CreativeEngine instance when the component unmounts
return () => {
engineRef.current?.dispose();
engineRef.current = null;
};
}, []);
const changeOpacity = useCallback(() => {
const engine = engineRef.current;
const imageBlockId = imageBlockIdRef.current;
if (engine && imageBlockId != null) {
const currentOpacity = engine.block.getOpacity(imageBlockId);
engine.block.setOpacity(imageBlockId, currentOpacity * 0.8);
}
}, [engineRef, imageBlockIdRef]);
return (
<div style={{ width: '100vw', height: '100vh', position: 'relative' }}>
<div ref={canvasRef} style={{ width: '100%', height: '100%' }} />
<div style={{ position: 'absolute', top: 20, left: 20 }}>
<button onClick={changeOpacity}>Reduce Opacity</button>
</div>
</div>
);
}

Step 4: Use the Custom Editor Component#

Import CustomEditor in the App.jsx file:

import { default as CustomEditor } from './CustomEditor';

Then, you can render the component on the page by adding it to the JSX as follows:

<CustomEditor />

App.jsx will contain:

// other imports...
import { default as CustomEditor } from './CustomEditor';
function App() {
// state management ...
return (
<>
{/* other components.. */}
<CustomEditor />
{/* other components.. */}
</>
);
}
export default App;

Step 5: Serve the React Project Locally#

Run the project locally using the development server provided by Vite. Starting the local server with the following command:

Terminal window
npm run dev

By default, the React app will be accessible on your localhost at http://localhost:5173/.

Step 6: Test the Integration#

  1. Open http://localhost:5173/ in your browser.
  2. You should see:
    • A canvas showing the programmatically created image
    • A “Reduce Opacity” button in the top-left corner (your custom UI)
    • No default editor interface or toolbars (this is headless mode)
  3. Click the “Reduce Opacity” button to test programmatic manipulation.

Troubleshooting & Common Errors#

❌ Error: The requested module '/src/CustomEditor.jsx' does not provide an export named 'CustomEditor'

❌ Error: The following dependencies are imported but could not be resolved: @cesdk/engine

  • Check that you’ve correctly installed CE.SDK using npm install @cesdk/engine.

❌ Error: The License Key (API Key) you are using to access the IMG.LY SDK is invalid.

  • Double-check that your CE.SDK license key is valid and hasn’t expired.

❌ Editor does not load

  • Check the browser console for any errors.
  • Verify that your component paths and imports are correct.

Next Steps#

Congratulations! You’ve successfully integrated CE.SDK into a new React project. Now, take some time to explore the SDK and proceed to the next steps whenever you’re ready: