Overview
The set_multiple_text_contents tool updates multiple text nodes in a single operation. It’s optimized for bulk text updates with automatic chunking, progress tracking, and error handling for individual failures.
Parameters
The ID of the parent node containing the text nodes to replace
Array of objects specifying which text nodes to update and their new contentEach object must contain:
nodeId (string, required) - The ID of the text node to update
text (string, required) - The new text content
Response
Returns an object containing:
success (boolean) - Overall operation success
nodeId (string) - Parent node ID
replacementsApplied (number) - Number of successful updates
replacementsFailed (number) - Number of failed updates
totalReplacements (number) - Total number of replacements attempted
completedInChunks (number) - Number of batches processed
results (array) - Detailed results for each text node:
success (boolean) - Whether this specific update succeeded
nodeId (string) - The text node ID
error (string, optional) - Error message if update failed
originalText (string, optional) - Original text content
translatedText (string, optional) - New text content
Batch Processing
The tool automatically processes text updates in batches:
- Batch Size: Processes 5 nodes at a time
- Progress Updates: Real-time updates after each batch
- Partial Success: Continues processing even if some nodes fail
- Error Isolation: Failures in one node don’t affect others
Progress Tracking
During processing, you’ll receive progress updates showing:
- Current batch being processed (e.g., “Processing batch 3 of 10”)
- Number of nodes processed so far
- Percentage complete
- Any errors encountered
Example
const result = await set_multiple_text_contents({
nodeId: "parent-frame-id",
text: [
{ nodeId: "heading-1", text: "Welcome to Our App" },
{ nodeId: "subtitle-1", text: "Get started in minutes" },
{ nodeId: "button-1", text: "Sign Up Free" },
{ nodeId: "description-1", text: "No credit card required" }
]
});
console.log(`Updated ${result.replacementsApplied} of ${result.totalReplacements} nodes`);
console.log(`Completed in ${result.completedInChunks} batches`);
// Check for failures
if (result.replacementsFailed > 0) {
const failures = result.results.filter(r => !r.success);
failures.forEach(f => console.log(`Failed: ${f.nodeId} - ${f.error}`));
}
Use Cases
Localization/Translation
Translate all text in a design to a different language.
// First, scan to get all text nodes
const textNodes = await scan_text_nodes({ nodeId: "screen-id" });
// Prepare translations
const translations = textNodes.textNodes.map(node => ({
nodeId: node.id,
text: translateToSpanish(node.characters)
}));
// Apply all translations in one batch
await set_multiple_text_contents({
nodeId: "screen-id",
text: translations
});
Content Population
Populate a design template with real data from an API.
const userData = await fetchUserData();
const updates = [
{ nodeId: "name-field", text: userData.fullName },
{ nodeId: "email-field", text: userData.email },
{ nodeId: "role-field", text: userData.role },
{ nodeId: "join-date", text: formatDate(userData.joinedAt) }
];
await set_multiple_text_contents({
nodeId: "profile-card",
text: updates
});
Table Data Updates
Update multiple rows in a table design.
const tableData = [
{ id: "row-1-col-1", text: "Alice" },
{ id: "row-1-col-2", text: "Engineer" },
{ id: "row-1-col-3", text: "$120,000" },
{ id: "row-2-col-1", text: "Bob" },
{ id: "row-2-col-2", text: "Designer" },
{ id: "row-2-col-3", text: "$110,000" }
];
const updates = tableData.map(cell => ({
nodeId: cell.id,
text: cell.text
}));
await set_multiple_text_contents({
nodeId: "data-table",
text: updates
});
A/B Testing Variants
Quickly create text variations for testing.
// Variant A: Action-oriented copy
const variantA = [
{ nodeId: "hero-text", text: "Start Building Today" },
{ nodeId: "cta-button", text: "Get Started Now" }
];
// Variant B: Benefit-focused copy
const variantB = [
{ nodeId: "hero-text", text: "Save 10 Hours Per Week" },
{ nodeId: "cta-button", text: "See How It Works" }
];
// Apply variant
await set_multiple_text_contents({
nodeId: "landing-page",
text: variantA
});
Performance Considerations
Batch Size
The default batch size of 5 nodes balances performance and responsiveness:
- Smaller batches (1-3): More progress updates, slower overall
- Default batches (5): Good balance for most use cases
- Larger batches would be faster but with less granular progress
Processing Time
Expect approximately:
- 1-10 nodes: < 1 second
- 10-50 nodes: 2-5 seconds
- 50-200 nodes: 10-20 seconds
- 200+ nodes: 30+ seconds with continuous progress updates
Font Loading
The first update to a node may be slower if Figma needs to load the font. Subsequent updates with the same font are faster.
Error Handling
The tool is designed to be resilient:
const result = await set_multiple_text_contents({
nodeId: "container",
text: [
{ nodeId: "valid-node", text: "Success" },
{ nodeId: "invalid-node", text: "Will fail" },
{ nodeId: "another-valid", text: "Also succeeds" }
]
});
// Result shows partial success:
// replacementsApplied: 2
// replacementsFailed: 1
// results[1].error: "Node not found" or "Not a text node"
Common Errors
- “Node not found”: The specified nodeId doesn’t exist
- “Not a text node”: The node is a different type (frame, rectangle, etc.)
- “Font loading failed”: The required font isn’t available
- “No text provided”: Empty text array passed
Best Practices
1. Validate Before Updating
// Scan first to ensure nodes exist
const textNodes = await scan_text_nodes({ nodeId: "frame-id" });
const validIds = new Set(textNodes.textNodes.map(n => n.id));
// Filter updates to only valid IDs
const updates = proposedUpdates.filter(u => validIds.has(u.nodeId));
await set_multiple_text_contents({
nodeId: "frame-id",
text: updates
});
2. Handle Partial Failures
const result = await set_multiple_text_contents({ nodeId, text: updates });
if (result.replacementsFailed > 0) {
// Retry failed updates
const failed = result.results
.filter(r => !r.success)
.map(r => ({ nodeId: r.nodeId, text: getRetryText(r.nodeId) }));
await set_multiple_text_contents({ nodeId, text: failed });
}
3. Chunk Large Updates
For 500+ nodes, consider splitting into multiple calls:
const chunkSize = 100;
for (let i = 0; i < allUpdates.length; i += chunkSize) {
const chunk = allUpdates.slice(i, i + chunkSize);
await set_multiple_text_contents({
nodeId: "parent-id",
text: chunk
});
console.log(`Completed chunk ${i / chunkSize + 1}`);
}
4. Verify Critical Updates
await set_multiple_text_contents({ nodeId, text: updates });
// Verify critical nodes were updated
for (const critical of criticalNodeIds) {
const info = await get_node_info({ nodeId: critical });
console.log(`Verified: ${info.name} = ${info.characters}`);
}
Workflow Example: Content Localization
// 1. Clone the design for the new language
const cloned = await clone_node({
nodeId: "original-screen",
x: 1000,
y: 0
});
// 2. Scan all text in the clone
const textNodes = await scan_text_nodes({ nodeId: cloned.id });
// 3. Prepare translations
const translations = await Promise.all(
textNodes.textNodes.map(async node => ({
nodeId: node.id,
text: await translateText(node.characters, 'es')
}))
);
// 4. Apply all translations in batches
const result = await set_multiple_text_contents({
nodeId: cloned.id,
text: translations
});
// 5. Verify and export
if (result.replacementsApplied === translations.length) {
await export_node_as_image({
nodeId: cloned.id,
format: "PNG",
scale: 2
});
}
Related Tools