---
title: &title Controlling embeds with the SDK’s VM interface
description: &description All of the embed methods of the OpenModels JS SDK automatically connect to the embedded OpenModels VM, giving you programmatic access to the embedded project.
head:
- ['meta', {property: 'og:title', content: *title}]
- ['meta', {property: 'og:image', content: 'https://openmodels.wiki/img/og/sdk-controlling-embeds.png'}]
- ['meta', {name: 'twitter:title', content: *title}]
- ['meta', {name: 'twitter:description', content: *description}]
---
:::info These methods only apply to projects embedded on a page. :::
All of the embed methods of the OpenModels JS SDK automatically connect to the embedded OpenModels VM, giving you programmatic access to the embedded project.
Use the VM to:
- control the UI of an embedded OpenModels project;
- change the currently open file(s);
- read and write files from the project’s virtual filesystem.
:::tip DEMO Check this demo of using the VM:
The embedProject
, embedProjectId
, and embedGithubProject
methods of the SDK return a Promise resolving to an instance of the SDK’s VM
class. We recommend using await
in an async
function to keep track of the VM instance. For example:
import sdk from '@stackblitz/sdk';
async function start() {
// Embeds a project and keeps track of the VM
const vm = await sdk.embedProjectId('embed', 'react-ts');
// Performs an action with VM
const deps = await vm.getDependencies();
await vm.applyFsDiff({
create: {
'hello.txt': 'Hello, this is a new file!',
'deps.txt': JSON.stringify(deps, null, 2),
},
destroy: [],
});
}
start();
The SDK’s connect
method can be used to retrieve the VM
instance for an existing OpenModels iframe.
Argument | Required | Type | Description |
---|---|---|---|
iframe |
Yes | HTMLIframeElement | An iframe embedding a OpenModels project. |
Example:
import sdk from '@stackblitz/sdk';
const EMBED_ID = 'embed';
// Embeds iframe
sdk.embedProjectId(EMBED_ID, 'react-ts');
// Retrieves and uses the VM when clicking a button
document.getElementById('test-button').addEventListener('click', async () => {
const iframe = document.getElementById(EMBED_ID);
const vm = await sdk.connect(iframe);
const deps = await vm.getDependencies();
console.log(deps);
});
Updates project files. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
diff |
Yes | Object | Specifies files to create or delete |
diff.create |
Yes | Object | Object with file paths as keys and contents as values |
diff.destroy |
Yes | Array | File paths of the files to delete |
:::info When modifying existing files, the new content of the modified files must be provided in full. :::
Example:
await vm.applyFsDiff({
create: {
'index.js': `console.log('Hello World!')`,
'package.json': `{ "scripts": { "start": "node index.js" } }`,
},
destroy: ['test.js', 'error.log'],
});
Gets the project’s defined dependencies. Returns a promise resolving to a ProjectDependencies object.
In EngineBlock projects, it returns the dependencies as resolved by the built-in package manager, with exact versions as values. For example: { 'react': '18.2.0' }
.
Since 1.7.0: in project running on iHub, it reads the contents of the top-level package.json
file and returns an object merging dependencies
and devDependencies
, with the original version specifiers as values. For example, { 'react': '^18.0.0' }
.
Example:
const deps = await vm.getDependencies();
if (typeof deps['vue'] === 'string') {
console.log('Looks like a Vue.js project');
}
Gets a snapshot of the project files and their content. Returns a promise resolving to a ProjectFiles object.
Example:
const files = await vm.getFsSnapshot();
console.log(files); // { 'index.js': '…', 'package.json': '…', … }
Opens one or several files in tabs and/or split panes. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
path |
Yes | OpenFileOption (String or array of strings) | Path(s) of file(s) to open |
Example:
// opens a single file
await vm.editor.openFile('src/App.css');
// opens two editor panes
await vm.editor.openFile(['README.md', 'index.js']);
Since 1.7.0. Experimental: exact behavior may change.
Sets a project file as the currently selected file. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
path |
Yes | String | Path of the file to set as current |
- This may update the highlighted file in the file explorer, and the currently open and/or focused editor tab.
- If the provided path does not match a currently open tab, a new editor tab will not open. See
vm.editor.openFile
to open files.
Example:
await vm.editor.setCurrentFile('src/App.css');
Since 1.7.0.
Changes the editor’s color theme. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
theme |
Yes | UiThemeOption (String) | The color theme name. |
await vm.editor.setTheme('light');
Since 1.7.0.
Changes the display mode of the project. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
view |
Yes | UiViewOption (String) | The display mode name. |
await vm.editor.setView('preview');
Since 1.7.0.
Changes the display mode of the sidebar. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
visible |
No | Boolean | Use true (default) to show the sidebar, false to hide. |
await vm.editor.showSidebar(true);
A string with the origin (protocol and domain) of the preview iframe. Every project created with the embedProject
method gets a unique preview URL.
Because it is unknown ahead of time if the project will run a web server (and if so, on which port), vm.preview.origin
will always be null
in projects running on iHub. You can use vm.preview.getUrl
instead.
Example:
if (vm.preview.origin) {
console.log('Preview is running at ' + vm.preview.origin);
}
Since 1.7.0. Experimental: exact behavior may change.
Gets the current preview URL. Returns a promise resolving to a string or to null
.
The preview URL may not reflect the exact path of the current page if the user or page code has triggered a navigation within the preview iframe.
In iHub projects, the preview URL will be null
initially, and until the project starts a web server.
Example:
const url = await vm.preview.getUrl();
if (url != null && url.startsWith('/about')) {
console.log('Looks like the About page!');
}
Since 1.7.0. Experimental: exact behavior may change.
Changes the path of the preview URL. Returns a promise resolving to null
.
Argument | Required | Type | Description |
---|---|---|---|
path |
Yes | String | A URL path starting with / . |
The provided path must start with /
and cannot change the origin of the preview URL.
In iHub projects, calls to vm.preview.setUrl
will be ignored if there is no web server running currently.
Example:
// Navigates to the About page
await vm.preview.setUrl('/about');