Skip to content
EN

Build and install a simple UI plugin

Last updated

Starting with the files already provided in the Plugin Playground, you will create a Welcome widget, run it in the Viewer, and use its button to move the camera to Tokyo. You will then export the same widget as a ZIP file, install it in Re:Earth Visualizer, and add it to a scene. No local setup is needed.

The finished Welcome widget contains a short message and a Fly to Tokyo button. When the button is clicked, it sends a message to the plugin, which moves the camera to Tokyo and updates the widget’s status message. The completed plugin is exported as a ZIP file and installed in a Visualizer project.

The finished Welcome widget with the Fly to Tokyo button displayed in the Visualizer

  • A Re:Earth Visualizer account with at least one project open
  • A modern desktop browser
  • Basic familiarity with HTML and JavaScript
  • No local development tools are required

The Plugin Playground is a browser-based editor built into Re:Earth Visualizer. It lets you write, preview, and export plugins without installing anything locally.

  1. Open Re:Earth Visualizer and sign in.
  2. Navigate to EditorPlugin in the left sidebar.
  3. Click Plugin Playground to open the editor.
  4. In the Custom section of the file tree, select My Plugin. It already contains a reearth.yml manifest and example extension files. You will edit the existing manifest and widget file.

The Plugin Playground with My Plugin selected in the Custom section of the file tree

Click reearth.yml and replace its contents with the following:

id: welcome-widget-plugin
name: Welcome Widget
version: 1.0.0
extensions:
- id: demo-widget
type: widget
name: Welcome
description: A simple welcome widget
widgetLayout:
defaultLocation:
zone: outer
section: left
area: top

A Re:Earth plugin can contain one or more extensions. This tutorial creates a widget extension — a user-interface component displayed in the main Visualizer view whose position can be arranged using the Widget Align System. The manifest declares the extension, while the matching JavaScript file supplies its interface and behaviour. Here, the extension ID demo-widget corresponds to demo-widget.js — keep these names exactly as shown.

Learn more about plugin structure and extension types.

The Plugin Playground after editing reearth.yml to declare the Welcome widget extension

The manifest now declares one widget named Welcome. Its extension ID, demo-widget, matches the existing file demo-widget.js; keep these names exactly as shown so the widget can run.

Select demo-widget.js to open it in the Code panel. Keep the code in the JavaScript editor; the live Playground currently shows the HTML Editor control as disabled for this file.

Replace the contents with:

const html = `
<div style="font-family: sans-serif; padding: 16px; background: #1e1e2f; color: white; border-radius: 8px; width: 220px;">
<h2 style="margin: 0 0 8px;">👋 Welcome</h2>
<p id="status" style="margin: 0 0 12px; font-size: 13px;">Click the button to fly to Tokyo.</p>
<button id="flyBtn" style="background: #4f8cff; border: none; color: white; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Fly to Tokyo</button>
<script>
document.getElementById('flyBtn').addEventListener('click', () => {
parent.postMessage({ action: 'flyToTokyo' }, '*');
});
window.addEventListener('message', (e) => {
if (e.source !== parent) return;
if (!e.data || e.data.action !== 'flying') return;
document.getElementById('status').textContent = e.data.text;
});
<\/script>
</div>
`;
reearth.ui.show(html, { width: 250, height: 150 });
reearth.extension.on("message", (msg) => {
if (msg && msg.action === "flyToTokyo") {
reearth.camera.flyTo(
{ lat: 35.6764, lng: 139.65, height: 8000, heading: 0, pitch: -1.3, roll: 0 },
{ duration: 3 }
);
reearth.ui.postMessage({ action: "flying", text: "Flying to Tokyo… 🗼" });
}
});

The Plugin API is available through the global reearth object on the extension side. The widget interface runs separately inside an iframe, so the two sides exchange messages:

  1. reearth.ui.show(...) displays the HTML as the widget’s iframe.
  2. The button handler runs inside the iframe. Because the iframe cannot call the Plugin API directly, parent.postMessage(...) sends the flyToTokyo action to the extension.
  3. reearth.extension.on("message", ...) receives the action on the extension side.
  4. reearth.camera.flyTo(...) moves the Visualizer camera to Tokyo.
  5. reearth.ui.postMessage(...) sends the new status back to the iframe, where window.addEventListener("message", ...) updates the text.

Learn more in How the Plugin System works.

The Plugin Playground after adding the widget code to demo-widget.js

  1. Click Run (the triangular play button) in the Playground toolbar.
  2. Confirm that the Welcome card appears in the Playground viewer.
  3. Click Fly to Tokyo — the camera should animate to Tokyo and the status text should change to “Flying to Tokyo… 🗼”.

After changing the code, click Run again to load the latest version in the viewer.

The Welcome widget running in the Playground viewer with the camera flying to Tokyo

  1. Select My Plugin in the Playground.
  2. Click Export (the down-arrow icon at the top of the Plugins panel).
  3. Save the downloaded ZIP file without extracting it.

The ZIP contains reearth.yml and demo-widget.js at the root — the exact structure Re:Earth Visualizer expects. Re:Earth accepts plugin ZIP files up to 10 MB.

The Plugin Playground Export button highlighted in the Plugins panel

Step 6 — Install the ZIP in Re:Earth Visualizer

Section titled “Step 6 — Install the ZIP in Re:Earth Visualizer”
  1. Open your Visualizer project.
  2. Open Project settings and select Plugins.
  3. Open Personally Installed.
  4. Choose Upload ZIP File from PC.
  5. Select the ZIP exported from the Playground.
  6. Wait for the success notification.
  1. Return to the Visualizer editor.
  2. Open Widgets.
  3. Click Add widget.
  4. Select Welcome.
  5. Click Fly to Tokyo and confirm that the camera moves.

The Welcome widget added to a Visualizer scene with the camera flying to Tokyo

You have now completed the full plugin workflow: edit → preview → export → install → use.

Installation fails

  • Validate the indentation and spelling in reearth.yml.
  • Make sure the plugin ID is no more than 100 characters, uses only letters, numbers, _, or -, and does not contain reearth.
  • Make sure no installed plugin already uses the same ID.
  • Confirm that reearth.yml is at the plugin root and that the ZIP does not contain an extra outer directory.
  • Export the ZIP again if it may be malformed.

Widget does not appear after enabling

  • Confirm that the manifest extension ID is demo-widget.
  • Confirm that the exported JavaScript file is demo-widget.js.
  • Confirm that the scene has been saved.
  • Open the browser developer tools and check the Console for JavaScript errors.

Camera does not move

  • Confirm that the iframe sends the message with parent.postMessage(...).
  • Confirm that the plugin listens with reearth.extension.on("message", ...).
  • Check that both sides use the same action name: flyToTokyo.

Status text does not update

  • The window.addEventListener('message', ...) inside the <script> tag filters messages where e.source !== parent.
  • In the Playground preview this check passes automatically; in a deployed scene it also works because the plugin iframe’s parent is always the Visualizer host.

Manifest and JS filename mismatch

  • The extension id in reearth.yml must exactly match the JS filename (without .js). demo-widgetdemo-widget.js.
  • Clicking Run displays the Welcome widget in the Playground
  • The button starts moving the camera to Tokyo
  • The plugin exports as a ZIP file
  • The ZIP installs successfully
  • The Welcome widget can be added to a Visualizer scene