Appearance
Getting Started with Topol Landing Page Editor
Embedding the Landing Page Editor takes two steps: create an API token, then add a container element and a short script to your page. Everything else is optional and can be layered on later.
Using React, Vue, or another framework?
Step 1 applies to every integration. Step 2 does not; follow NPM & Frameworks instead.
Step 1: Create your API token
Log into your Topol Account, open the API Tokens tab and click + New API Token. The page that opens creates the token that authorizes the Landing Page Editor in your application.

The token comes with two keys, shown in the API Keys tab: the Public API key goes into the editor configuration in your page, and the Secret key authorizes server-side calls to the Topol API and must never be exposed in client-side code.
With the token created, switch to the Configuration tab and add every domain where the editor will run to the Allowed domains list.

WARNING
The token only works on the domains listed in its configuration. Loading the editor from an unlisted domain fails authorization.
Step 2: Add the editor to your application
With the API key ready, the editor goes into your page in two pieces: a container element and a script that configures and starts it. (In a framework app, the NPM packages replace this setup.)
One difference from the Topol Email Editor: the Landing Page Editor is instantiated via the LandingPageEditor() factory, and callbacks are passed as top-level properties next to config, not inside a callbacks object.
Let an AI agent do the wiring
TOPOL-io/skills has two skills for coding agents, written as plain markdown. topol-editor-integration sets up either editor in a new project and topol-v1-upgrade moves an existing NPM integration from 0.x to v1. They install as a Claude Code plugin (/plugin marketplace add TOPOL-io/skills) or into any agent with npx skills@latest add TOPOL-io/skills.
First, add this HTML where you want the editor to appear. The container needs an explicit width and height, otherwise the editor has no space to render:
html
<!-- Container where the Landing Page Editor will be rendered -->
<div id="landing-page-editor" style="width: 100%; height: 100vh;"></div>Next, load the editor script and initialize it. The editor runs inside its own iframe, isolated from your application's styling and scripts:
html
<!-- Load the Topol Landing Page Editor script -->
<script
src="https://v1.page-assets.topol.io/loader/build.js"
type="text/javascript"
></script>
<!-- Configure and initialize the Landing Page Editor -->
<script>
const TOPOL_OPTIONS = {
authorize: {
apiKey: "YOUR_API_KEY", // Replace with your actual API key from step 1
userId: "user-123", // Any unique ID for your user
},
};
// Initialize the Landing Page Editor.
// Callbacks are top-level properties, passed next to `config`.
const LPE = LandingPageEditor({
config: TOPOL_OPTIONS,
onSave: function ({ json, html }) {
// Runs when the user saves.
// `json` is the template definition, `html` is the rendered page.
console.log("Saved landing page:", json, html);
},
onInit: function () {
// Runs once the editor is initialized and ready
console.log("Landing Page Editor is ready");
},
});
// Render the editor into the container
LPE.render("#landing-page-editor");
// Optional: Load a template into the editor on start
// Replace the URL with your own template, or remove this to start with an empty page
fetch("https://example.com/your-template.json")
.then((response) => response.json())
.then((template) => {
LPE.load(template);
})
.catch((error) => {
console.error("Failed to load template:", error);
});
</script>Important notes:
- The
apiKeyis the Public API key from Step 1. - The
userIdis a uniquestringornumberthat identifies the current user. It counts as one unique user for monthly billing and determines where that user's images are stored. Typically, oneuserIdcorresponds to one client of your app, CRM, or platform. - The
onSave({ json, html })callback receives the page JSON definition and the rendered HTML on every save. Store both: the JSON to load back into the editor later, the HTML to publish the page. Every callback gets a single payload object like this one, see the Callbacks Reference. onInit()fires once the editor is initialized and ready, which makes it the place to hide loaders or start tracking. A separateonLoaded()callback fires after a template passed toload()has been applied.
Loading and saving landing pages
Loading a page programmatically means passing its JSON definition into the load() method:
javascript
const template = {
// Your landing page JSON structure
};
LPE.load(template);A save can also be triggered from your application code:
javascript
LPE.save();Calling save() renders the page server-side and then triggers the onSave({ json, html }) callback. If the rendering request fails, the editor shows an error notification and onSave is not called.
Next steps
With the editor embedded, the integration grows through options:
- Configure the editor's appearance to match your brand
- Set up authorization and API endpoints for backend integration
- Explore editor options for advanced customization
- Learn about available editor methods for programmatic control
INFO
Running into trouble while implementing the Landing Page Editor? Contact our support team here and we'll help you get it working.
