Control Jitter (jitter.video) for exporting animations, replacing assets, and modifying text programmatically via Playwriter.
Control Jitter (jitter.video) for exporting animations, replacing assets, and modifying text.
Load utils before interacting with Jitter:
// Load once per page (before navigation or via addInitScript)
await page.addInitScript({ path: './skills/jitter/dist/jitter-utils.js' })
// Navigate to project
await page.goto('https://jitter.video/file/?id=YOUR_FILE_ID')
// Wait for app to be ready
await page.evaluate(() => jitterUtils.waitForApp())
| Function | Description |
|---|---|
findNodeById(id) | Find node by ID |
findAllMediaNodes() |
| Get all images/SVGs/videos/GIFs |
findAllTextNodes() | Get all text nodes |
getArtboards() | Get all artboards with dimensions |
findNodesByType(type) | Find nodes by layer type |
findNodesByName(name) | Find nodes by name (partial match) |
flattenTree() | Get all nodes as flat array |
| Function | Description |
|---|---|
replaceAssetUrl(nodeId, url) | Replace image/SVG/video URL |
replaceText(nodeId, text) | Replace text content |
updateNode(nodeId, props) | Update any node properties |
batchReplace(replacements) | Batch update multiple nodes |
selectNodes(nodeIds) | Select nodes by ID |
removeNodes(nodeIds) | Remove nodes |
undo() / redo() | Undo/redo actions |
| Function | Description |
|---|---|
generateExportUrl(opts) | Generate export URL with options |
generateExportUrlFromCurrentProject(opts) | Export URL for current project |
parseJitterUrl(url) | Parse file/node IDs from URL |
getFileMeta() | Get current file metadata |
| Function | Description |
|---|---|
createSnapshot(nodeIds) | Save node states |
restoreFromSnapshot(snapshot) | Restore saved states |
duplicateProject() | Clone current project |
withTemporaryChanges(nodeIds, changes, callback) | Apply temp changes, run callback, restore |
| Function | Description |
|---|---|
waitForApp(timeout?) | Wait for app to load |
waitForSync(delay?) | Wait for server sync |
waitForNode(nodeId, timeout?) | Wait for node to exist |
isAppReady() | Check if app is ready |
// Get all media nodes
const media = await page.evaluate(() => jitterUtils.findAllMediaNodes())
// Replace specific assets
await page.evaluate(() => {
jitterUtils.batchReplace([
{ nodeId: 'abc123', data: { url: 'https://example.com/new-image.svg' } },
{ nodeId: 'def456', data: { url: 'https://example.com/new-photo.jpg' } },
])
})
// Wait for sync then export
await page.evaluate(() => jitterUtils.waitForSync())
const exportUrl = await page.evaluate(() =>
jitterUtils.generateExportUrlFromCurrentProject({ profile: 'lottie' }),
)
await page.goto(exportUrl)
await page.evaluate(async () => {
const nodeIds = ['node1', 'node2']
const changes = {
node1: { url: 'https://temp-asset.svg' },
node2: { text: 'Temporary Text' },
}
await jitterUtils.withTemporaryChanges(nodeIds, changes, async () => {
// Changes applied here, will be restored after
const url = jitterUtils.generateExportUrlFromCurrentProject()
// ... navigate to export URL and download
})
// Original values automatically restored
})
const textNodes = await page.evaluate(() => jitterUtils.findAllTextNodes())
// [{ id, name, text, fontSize, fontFamily }, ...]
await page.evaluate(() => {
jitterUtils.replaceText('textNodeId', 'New headline')
})
| Profile | Output |
|---|---|
lottie | Lottie JSON (vector animation) |
mp4 | H.264 video |
gif | Animated GIF |
webm | WebM video |
prores4444 | ProRes 4444 (with alpha) |
pngs | PNG sequence |
Workaround: Always modify assets in Jitter before export using replaceAssetUrl().
*WithUndo actions can be undone with Ctrl+Z?nodeId=xxx