Edit in GitHubLog an issue

Embed SDK Full Editor tutorial

Learn how to integrate the Adobe Express Embed SDK into your web applications.

Introduction

Hi, developers! In this tutorial, we'll create an Embed SDK integration that leverages the Adobe Express full editor experience. Users will be able to create, edit, and export documents directly from your web application.

We'll look at a few configuration parameters, as well as the way to handle events, callbacks and manage files between your application and Adobe Express. Let's get started!

Full Editor

Prerequisites

Before we begin, make sure you have the following:

  • An Adobe account: use your existing Adobe ID or create one for free.
  • Embed SDK Credentials from the Adobe Developer Console; see the Quickstart Guide for more information.
  • Familiarity with HTML, CSS, JavaScript.
  • Node.js is installed on your development machine.

Running the sample project

Let's have a look at what we're going to build. First off, clone the embed-sdk-full-editor-tutorial sample from GitHub and navigate to the project directory. Locate the src/.env file and replace the placeholder string in the VITE_API_KEY with your Embed SDK API Key:

Copied to your clipboard
VITE_API_KEY="your-api-key-here!"

Now, you can install the dependencies and run the sample with the following two simple commands:

Copied to your clipboard
npm install
npm run start

The web application will be served at localhost:5555 on a secure HTTPS connection—which is always required for any Embed SDK integration. Open your browser and navigate to this address to see it in action.

Full Editor starting point

When clicking the Create New button, the Adobe Express full editor will launch with a predefined document size; users have the entire set of tools available to create their designs. Once they're done, they can Download the document, or Save it as an Image.

The sample project will handle the file transfer between Adobe Express and the web page hosting it, and the image will be displayed in lieu of the placeholder.

Full Editor displayed image

The Edit button (previously disabled) will open the Editor with the same document size and content as the one just created: the Project ID has been stored as part of the onPublish callback, as we'll see in due course. Users can modify the design and download or save it again.

Coding the Integration

You can just read the existing code in the sample, but it's always best to learn by doing! We suggest following along and typing the code in—even small mistakes can lead to important discoveries.

The sample project is a simple web application built with Vite, which takes care of the entire HTTPS setup and hot reloading.1 As customary, we'll work in the src folder with the simplest setup possible: HTML, JS, and CSS, one file each.

1. Importing and Initializing

The HTML content is not overly important; let's focus on the JavaScript side of things first. Open the project in your code editor of choice. In main.js, remove everything below the Spectrum import statements—we'll rebuild it from scratch.

Copied to your clipboard
import "./style.css";
// Importing theme and typography styles from Spectrum Web Components
import "@spectrum-web-components/styles/typography.css";
import "@spectrum-web-components/theme/express/theme-light.js";
import "@spectrum-web-components/theme/express/scale-medium.js";
import "@spectrum-web-components/theme/sp-theme.js";
// Importing Spectrum Web Components
import "@spectrum-web-components/button/sp-button.js";
import "@spectrum-web-components/button-group/sp-button-group.js";
import "@spectrum-web-components/divider/sp-divider.js";

The imports above allow us to style our web application with Spectrum Web Components and the Adobe Express theme. Let's begin by importing the Embed SDK:

Copied to your clipboard
// Importing the Adobe Express Embed SDK
await import("https://cc-embed.adobe.com/sdk/v4/CCEverywhere.js");
console.log("CCEverywhere loaded", window.CCEverywhere);

When the Embed SDK is imported, a CCEverywhere object is globally available and must be initialized. There are two sets of parameters that you can pass as option objects:

  • Host Information: containing the API key, Application name, etc.
  • Configuration: optional settings, like locale, delayed sign-in, etc.
Copied to your clipboard
// 👀 Required parameters for initializing the Embed SDK
const hostInfo = {
clientId: import.meta.env.VITE_API_KEY,
appName: "Embed SDK Sample",
};
// Optional parameters
const configParams = {
// Users can log in only when exporting/saving the document
loginMode: "delayed",
};
// Initializing the Adobe Express Embed SDK
const { editor } = await window.CCEverywhere.initialize(
hostInfo,
configParams
);

We're using the asynchronous initialize() method, that returns a promise resolving to an object with three properties. Here, we want to implement the full editor; hence, among them, we destructure just the editor.

The hostInfo object is required: the clientId contains your API Key (here, retrieved by Vite from the .env file) and the appName.

All configParams are optional, instead: here, loginMode tells Adobe Express to delay the login until artworks are exported.

2. Creating the Editor

Excellent! We have this editor: now what? We'll use it to spawn a new Adobe Express instance via the editor.create() method—which, in turn, accepts four option objects able to configure:

The links above point to the respective SDK Reference pages. They are all optional—our sample makes use of the first three of them:

Copied to your clipboard
// Document
const docConfig = { canvasSize: "BusinessCard" };
// Application
const appConfig = {
selectedCategory: "media",
callbacks: {
onCancel: () => {},
onPublish: (intent, publishParams) => { /* ... */ },
onError: (err) => { /* ... */ }
};
// Export Options
const exportConfig = [
{
id: "download",
label: "Download",
action: { target: "download" },
style: { uiType: "button" },
},
{
id: "save-modified-asset",
label: "Save image",
action: { target: "publish" },
style: { uiType: "button" },
},
];

As you can see, we are:

  • Creating by default a document using the "BusinessCard" template.
  • Launching Adobe Express with the Media panel open on the left.
  • Setting a series of Callbacks that will fire when the user Cancels, Saves (that would be onPublish), or when something goes wrong.
  • Defining two ways for users to export content: download the file locally and save it in the user's Adobe Express folder and pass it back to the web application.

On the Create New button click, Adobe Express is launched:

Copied to your clipboard
document.getElementById("createDesign").onclick = async () => {
editor.create(docConfig, appConfig, exportConfig);
};

Launching the Full Editor

As you can see, integrating the full editor doesn't take much time! You can customize it to a great extent; even using all the default options, the result is brilliant.

3. Managing images

The exportConfig array we've just written adds a Save image button to Adobe Express, allowing users to store their image; we'd like our web application to capture and display it on the HTML page.

We need to write a simple function in the callbacks to implement this feature, precisely the onPublish. It is triggered when the user clicks the Save image button, and it receives a PublishParams argument, with three crucial properties:

  • documentId: a unique identifier for the asset that has been created or modified.
  • exportButtonId: the identifier of the export button that has been clicked.
  • asset: an OutputAsset object, with several interesting properties like data—a Base64 string representation of the saved image.

The data property sounds promising! The plan is to have an <img> element (in this example, it starts as a placeholder), which src attribute will be filled with the Base64 string coming from Adobe Express.

Copied to your clipboard
// Storing the image element
var expressImage = document.getElementById("savedImage");
// Callbacks to be used when creating or editing a document
const callbacks = {
// ... other callbacks
onPublish: (intent, publishParams) => { // 👈
expressImage.src = publishParams.asset[0].data; // 👈
console.log("Image data", publishParams.asset[0].data); // 👈
}
};

Please note that asset is an array; we're getting just the first item here. If you open the Console, you'll see the Base64 string logged.

Logging Base64 data

4. Editing projects

The last step is implementing the Edit button feature, which should launch Adobe Express and open the project that was saved before. As we've seen earlier, when a document is saved, we receive a PublishParams that contains documentId. We can store it for reference and use in the docConfig option object to open it again:

Copied to your clipboard
// Will hold the project ID when a document is saved
var existingProjectId = null; // 👈
// Callbacks to be used when creating or editing a document
const callbacks = {
// ... other callbacks
onPublish: (intent, publishParams) => {
existingProjectId = publishParams.projectId; // 👈
console.log("Project ID", existingProjectId); // 👈
expressImage.src = publishParams.asset[0].data;
console.log("Image data", publishParams.asset[0].data);
}
};
// Click handler for the Edit Design button
document.getElementById("editBtn").onclick = async () => {
// Opening the existing project by ID
let docConfig = { documentId: existingProjectId };
// ...
editor.edit(docConfig, appConfig, exportConfig);
};

Above, we're using existingProjectId to hold the project reference, collected in the onPublish callback every time the document is saved. Later, in the editBtn click handler, we're creating a new docConfig object passing the ID in the documentId property. This tells Adobe Express to look for an existing project and open it right away.

Logging the Project ID

Final project

We have all the required bits in place, but some simple refactoring is needed to keep the code clean.

  • The appConfig and exportConfig option objects are stored in constants, as they're shared in both the Create new and Edit buttons.
  • The callbacks follow suit; we've added a simple onError that logs a message, and now onPublish also enables the Edit button—that starts disabled.

You can check the entire embed-sdk-full-editor-tutorial project code as part of the dedicated embed-sdk-samples repository. Find the most relevant files below for reference.

Copied to your clipboard
import "./style.css";
// Importing theme and typography styles from Spectrum Web Components
import "@spectrum-web-components/styles/typography.css";
import "@spectrum-web-components/theme/express/theme-light.js";
import "@spectrum-web-components/theme/express/scale-medium.js";
import "@spectrum-web-components/theme/sp-theme.js";
// Importing Spectrum Web Components
import "@spectrum-web-components/button/sp-button.js";
import "@spectrum-web-components/button-group/sp-button-group.js";
import "@spectrum-web-components/divider/sp-divider.js";
// Importing the Adobe Express Embed SDK
await import("https://cc-embed.adobe.com/sdk/v4/CCEverywhere.js");
console.log("CCEverywhere loaded", window.CCEverywhere);
// Parameters for initializing the Adobe Express Embed SDK
const hostInfo = {
clientId: import.meta.env.VITE_API_KEY,
appName: "Embed SDK Sample",
};
// Prompts the user to log in only when exporting/saving the document
const configParams = {
loginMode: "delayed",
};
// Initializing the Adobe Express Embed SDK
const { editor } = await window.CCEverywhere.initialize(
hostInfo, configParams
);
// Will hold the project ID when a document is saved on Adobe Express
var existingProjectId = null;
var expressImage = document.getElementById("savedImage");
// Callbacks to be used when creating or editing a document
const callbacks = {
onCancel: () => {},
onPublish: (intent, publishParams) => {
existingProjectId = publishParams.projectId;
console.log("Project ID", existingProjectId);
expressImage.src = publishParams.asset[0].data;
console.log("Image data", publishParams.asset[0].data);
// enable the editDesign button
document.getElementById("editBtn").disabled = false;
},
onError: (err) => {
console.error("Error!", err.toString());
},
};
// Configuration for the app, shared by both Create and Edit flows
const appConfig = { selectedCategory: "media", callbacks };
// Configuration for the export options made available
// to the user when creating or editing a document
const exportConfig = [
{
id: "download",
label: "Download",
action: { target: "download" },
style: { uiType: "button" },
},
{
id: "save-modified-asset",
label: "Save image",
action: { target: "publish" },
style: { uiType: "button" },
},
];
// Click handler for the Create Design button
document.getElementById("createBtn").onclick = async () => {
// Presetting the canvas size
let docConfig = { canvasSize: "BusinessCard" };
// Using the global appConfig and exportConfig
editor.create(docConfig, appConfig, exportConfig);
};
// Click handler for the Edit Design button
document.getElementById("editBtn").onclick = async () => {
// Opening the existing project by ID
let docConfig = { documentId: existingProjectId };
// Using the global appConfig and exportConfig
editor.edit(docConfig, appConfig, exportConfig);
};

Next steps

Congratulations! You've implemented a Full Editor integration with the Adobe Express Embed SDK. You've learned how to create, edit, and let users export documents, as well as how to manage images between Adobe Express and your web application. What's next for you?

  • The Embed SDK offers a wide range of features and customization options; you can explore them in the API Reference.
  • Visit the changelog page to keep up with the latest updates and improvements.
  • If you're looking for more tutorials, check out here.
  • Finally, if you get stuck or you just want to share your experience, visit the Adobe Express Embed SDK Community Forum.

  1. A Webpack setup is entirely possible, but it requires manual (or semi-automated) steps to integrate the mkcert CLI and ensure proper HTTPS handling. We've chosen Vite to keep that out of the way and focus on the actual integration code.
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2024 Adobe. All rights reserved.