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!
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 clipboardVITE_API_KEY="your-api-key-here!"
📖 Instructions on how to obtain an API Key can be found on the Quickstart Guide.
Now, you can install the dependencies and run the sample with the following two simple commands:
Copied to your clipboardnpm installnpm 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.
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.
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.
Error: "Adobe Express is not available"
In case you get a popup when trying to launch the Adobe Express integration with the following message: "You do not have access to this service. Contact your IT administrator to gain access", please check to have entered the correct API Key in the src/.env
file as described here.
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 clipboardimport "./style.css";// Importing theme and typography styles from Spectrum Web Componentsimport "@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 Componentsimport "@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 SDKawait import("https://cc-embed.adobe.com/sdk/v4/CCEverywhere.js");console.log("CCEverywhere loaded", window.CCEverywhere);
There are several ways to import CCEverywhere.js
: for more information, please refer to the Quickstart Guide.
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 SDKconst hostInfo = {clientId: import.meta.env.VITE_API_KEY,appName: "Embed SDK Sample",};// Optional parametersconst configParams = {// Users can log in only when exporting/saving the documentloginMode: "delayed",};// Initializing the Adobe Express Embed SDKconst { 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
.
The appName
must match the name of your application, and it will be displayed in the Adobe Express UI as a folder where users can store their documents.
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 Document that will be created (e.g., its size).
- The Adobe Express Application itself (e.g., the callbacks).
- The allowed Export Options.
- The Container (modal dialog) of the Adobe Express application.
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// Documentconst docConfig = { canvasSize: "BusinessCard" };// Applicationconst appConfig = {selectedCategory: "media",callbacks: {onCancel: () => {},onPublish: (intent, publishParams) => { /* ... */ },onError: (err) => { /* ... */ }};// Export Optionsconst 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 clipboarddocument.getElementById("createDesign").onclick = async () => {editor.create(docConfig, appConfig, exportConfig);};
Please don't be scared by the red warning toast at the bottom of the screen: it is just a reminder that the Embed SDK is providing access via your credentials, but you must submit the integration and request approval from Adobe before you can go live. Please check the Submission and Review section to learn more.
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
: anOutputAsset
object, with several interesting properties likedata
—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 elementvar expressImage = document.getElementById("savedImage");// Callbacks to be used when creating or editing a documentconst callbacks = {// ... other callbacksonPublish: (intent, publishParams) => { // 👈expressImage.src = publishParams.asset[0].data; // 👈console.log("Image data", publishParams.asset[0].data); // 👈}};
Copied to your clipboard<!-- ... rest of the page --><img id="savedImage"src="https://placehold.co/300x300?text=Placeholder+Image&font=source-sans-pro"alt="Your design will appear here." /><!-- ... rest of the page -->
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.
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 savedvar existingProjectId = null; // 👈// Callbacks to be used when creating or editing a documentconst callbacks = {// ... other callbacksonPublish: (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 buttondocument.getElementById("editBtn").onclick = async () => {// Opening the existing project by IDlet 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.
Final project
We have all the required bits in place, but some simple refactoring is needed to keep the code clean.
- The
appConfig
andexportConfig
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 simpleonError
that logs a message, and nowonPublish
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 clipboardimport "./style.css";// Importing theme and typography styles from Spectrum Web Componentsimport "@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 Componentsimport "@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 SDKawait import("https://cc-embed.adobe.com/sdk/v4/CCEverywhere.js");console.log("CCEverywhere loaded", window.CCEverywhere);// Parameters for initializing the Adobe Express Embed SDKconst hostInfo = {clientId: import.meta.env.VITE_API_KEY,appName: "Embed SDK Sample",};// Prompts the user to log in only when exporting/saving the documentconst configParams = {loginMode: "delayed",};// Initializing the Adobe Express Embed SDKconst { editor } = await window.CCEverywhere.initialize(hostInfo, configParams);// Will hold the project ID when a document is saved on Adobe Expressvar existingProjectId = null;var expressImage = document.getElementById("savedImage");// Callbacks to be used when creating or editing a documentconst 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 buttondocument.getElementById("editBtn").disabled = false;},onError: (err) => {console.error("Error!", err.toString());},};// Configuration for the app, shared by both Create and Edit flowsconst appConfig = { selectedCategory: "media", callbacks };// Configuration for the export options made available// to the user when creating or editing a documentconst 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 buttondocument.getElementById("createBtn").onclick = async () => {// Presetting the canvas sizelet docConfig = { canvasSize: "BusinessCard" };// Using the global appConfig and exportConfigeditor.create(docConfig, appConfig, exportConfig);};// Click handler for the Edit Design buttondocument.getElementById("editBtn").onclick = async () => {// Opening the existing project by IDlet docConfig = { documentId: existingProjectId };// Using the global appConfig and exportConfigeditor.edit(docConfig, appConfig, exportConfig);};
Copied to your clipboard<body><sp-theme scale="medium" color="light" system="express"><div class="container"><header><h1>Adobe Express Embed SDK</h1><sp-divider size="l"></sp-divider><h2>Full Editor Sample</h2><p>The <b>Create New</b> button launches a blanknew project in a full editor instance. <br />Once you have published/saved a project, use the<b>Edit</b> button to resume editing the same project.</p></header><main><img id="savedImage"src="https://placehold.co/300x300?text=Placeholder+Image"alt="Your design will appear here." /><sp-button-group><sp-button id="createBtn">Create New</sp-button><sp-button id="editBtn" disabled>Edit</sp-button></sp-button-group></main></div></sp-theme><script type="module" src="./main.js"></script></body>
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.
- 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.↩