figma-use について
figma-useは、`use_figma`ツールでPlugin APIのJavaScriptを実行し、Figmaファイルを操作するスキルです。Figmaデザインを扱うエージェント向けに、段階的な変更、API資料の確認、対象ノードIDの返却を重視します。
主な機能
- 01`use_figma`によるPlugin API JavaScriptの実行
- 02API型定義とドキュメントの参照
- 03段階的なキャンバス編集
- 04テキストと変数の編集ガイド
- 05ページ単位の操作ルール
活用シーン
- 01Figmaノードの確認や変更
- 02Figmaレイアウトの作成や更新
- 03テキストやデザイン変数の編集
MCP 対応
このスキルは`use_figma`ツールの利用方法と、Figma MCPツールが遅延読み込みされる場合のスキーマ読み込みについて説明します。MCPツールが提供する具体的な機能は記載されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedesignproject/ agent-skills --skill figma-useインストール後、Claude Code で/figma-useを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-reference.mdcommon-patterns.mdcomponent-patterns.mdeffect-style-patterns.mdgotchas.mdplugin-api-patterns.mdplugin-api-standalone.d.tsplugin-api-standalone.index.mdtext-style-patterns.mdvalidation-and-recovery.mdvariable-patterns.mdreferences/working-with-design-systems/wwds-components--creating.mdwwds-components--using.mdwwds-components.mdwwds-effect-styles.mdwwds-text-styles.mdwwds-variables--creating.mdwwds-variables--using.mdwwds-variables.mdwwds.md詳細
use_figma — Figma Plugin API スキル
use_figma ツールを使用して、Plugin API 経由で Figma ファイル内の JavaScript を実行します。詳細なリファレンスドキュメントはすべて references/ にあります。
use_figma を呼び出すときは、必ず skillNames: "figma-use" を渡してください。 これはスキルの使用状況を追跡するためのログ用パラメーターであり、実行には影響しません。
Figma MCP ツールが遅延ツールとして表示される場合は、select: 構文を使用して、すべてのスキーマを 1 回の ToolSearch 呼び出しでまとめて読み込んでください。例:ToolSearch query="select:use_figma,get_screenshot,get_metadata,create_new_file"。6 回に分けて呼び出すより、1 回で済ませるほうが効率的です。
コードから Figma のページ全体、画面全体、または複数セクションのレイアウトを構築または更新するタスクの場合は、figma-generate-design も読み込んでください。これには、search_design_system でデザインシステムのコンポーネントを見つけてインポートし、画面を段階的に組み立てるワークフローが記載されています。2 つのスキルは連携して機能します。こちらは API のルールを扱い、もう一方は画面構築のワークフローを扱います。
Figma でコンポーネントを作成または構築するタスクの場合(単一のコンポーネントであっても)、figma-generate-library も読み込んでください。これには、変数の基盤、バリアントセット、デザイントークンのバインディングなど、figma-use だけでは扱えないコンポーネント作成のワークフローが記載されています。
最初に、plugin-api-standalone.index.md を読み込んで、何が可能かを把握してください。Plugin API コードの作成を依頼された場合は、この情報をもとに plugin-api-standalone.d.ts を検索し、関連する型、メソッド、プロパティを確認してください。これは API の仕様を網羅した信頼できる唯一の情報源です。型定義ファイルは大きいため、一度にすべて読み込まず、必要に応じて関連するセクションを検索してください。
重要:デザインシステムを扱う場合は必ず、まず working-with-design-systems/wwds.md を読み込み、Figma でデザインシステムを扱うための重要な概念、プロセス、ガイドラインを理解してください。その後、必要に応じてコンポーネント、変数、テキストスタイル、エフェクトスタイルの詳細なリファレンスを読み込んでください。
1. 重要なルール
- データを返すには
returnを使用してください。 戻り値は自動的に JSON にシリアライズされます(オブジェクト、配列、文字列、数値)。figma.closePlugin()を呼び出したり、コードを非同期 IIFE で囲んだりしないでください。これらは自動的に処理されます。 - トップレベルの
awaitとreturnを使って、通常の JavaScript を記述してください。 コードは自動的に非同期コンテキストでラップされます。(async () => { ... })()で囲まないでください。 figma.notify()は 「not implemented」をスローします。絶対に使用しないでください。 3a.getPluginData()/setPluginData()はuse_figmaで サポートされていません。使用しないでください。代わりにgetSharedPluginData()/setSharedPluginData()を使用してください(こちらはサポートされています)。または、ノード ID を返し、後続の呼び出しに渡して追跡してください。console.log()の出力は返されません。出力にはreturnを使用してください。- 小さなステップで段階的に作業してください。 大きな操作は複数の
use_figma呼び出しに分割します。各ステップの後に検証してください。これは、バグを避けるために最も重要な実践方法です。 - 色の値は 0~1 の範囲です(0~255 ではありません)。
{r: 1, g: 0, b: 0}は赤です。 - 塗りと線は 読み取り専用の配列です。複製して変更し、再代入してください。
- すべてのテキスト編集では、標準手順に従ってください。フォントを読み込む →
await→ 変更 → 影響を受けたノード ID を返す、の順です。 フォントの読み込みを省略すると、Cannot write to node with unloaded font "<family> <style>"がスローされます。このルールはcharacters以外にも適用されます。未読み込みのフォントを含むノードに対するあらゆる操作(テキストを扱うfindAllコールバック内のappendChild、insertChild、setBoundVariable、setExplicitVariableModeForCollection、setValueForModeなど)に適用されます。既存のテキストを変更するときは、ハードコードされたデフォルト値ではなく、getStyledTextSegments(['fontName'])を使ってノードの 現在の フォントを読み込んでください。多くの環境では Inter が事前に読み込まれているため、他のフォントファミリーではこの問題が発生しやすくなります。どのフォントでも手順は同じです。スタイル文字列が未確認の場合は、まずawait figma.listAvailableFontsAsync()を使用してください。テキスト編集の標準手順を参照してください。 - ページは段階的に読み込まれます。
await figma.setCurrentPageAsync(page)を使ってページを切り替え、コンテンツを読み込んでください。同期セッターfigma.currentPage = pageは 機能せず、エラーをスローします(以下の「ページに関するルール」を参照)。 setBoundVariableForPaintは 新しい ペイントを返すため、受け取って再代入する必要があります。createVariableには、コレクションの オブジェクトまたは ID 文字列を渡せます(オブジェクトを推奨)。layoutSizingHorizontal/Verticalの値は構造上のコンテキストによって制限されます。FIXEDは常に機能しますが、HUGとFILLは機能しません。'HUG'が有効なのは、自動レイアウトフレーム自体、またはそのフレームの テキスト子ノードのみです。'FILL'が有効なのは、自動レイアウトフレームの子ノードであり、かつ絶対位置指定されておらず、不変フレームの内側にもキャンバスグリッドの子ノードにもなっていない場合のみです。実際には、まず自動レイアウトの親に追加してからHUG/FILLを設定してください。新規作成されたノードや親を持たないノードは、まだこのルールを満たせません。プロパティ自体はすべてのSceneNodeに存在します。エラーは「そのプロパティが存在しない」ためではなく、値が許可されないために発生します。注意事項を参照してください。 12a. 関連する子ノードを含むコンテナーには、自動レイアウトを使用してください。 子ノードに積み重ね、横並び、整列、間隔、内容に合わせたサイズ調整などの構造的な関係がある場合は、絶対位置のx/yを使ったfigma.createFrame()ではなく、figma.createAutoLayout()で囲んでください。絶対座標はキャンバス上でコンテナーを配置する場所を制御し、自動レイアウトはコンテナー内の子ノード同士の関係を制御します。コンテナーを省略すると、テキストの再フロー、コンテンツの変更、重なりを防ぐ手段がなくなります。- ページ直下に新しく作成するノードは、(0,0) から離れた位置に配置してください。 ページに直接追加されたノードの既定位置は (0,0) です。
figma.currentPage.childrenを調べて、空いている位置(例:最も右にあるノードの右側)を見つけてください。これはページ直下のノードにのみ適用されます。他のフレームや自動レイアウトコンテナー内にネストされたノードの位置は、親によって決まります。注意事項を参照してください。 use_figmaでエラーが発生したら、いったん停止してください。すぐに再試行しないでください。 失敗したスクリプトは アトミックです。スクリプトでエラーが発生した場合、スクリプトはまったく実行されず、ファイルにも変更は加えられません。エラーメッセージを注意深く読み、スクリプトを修正してから再試行してください。エラーからの復旧を参照してください。- 作成または変更したノード ID は、必ずすべて
returnしてください。 スクリプトでキャンバスに新しいノードを作成するか既存のノードを変更するときは、影響を受けたノード ID をすべて収集し、構造化オブジェクトで返してください(例:return { createdNodeIds: [...], mutatedNodeIds: [...] })。後続の呼び出しでノードを参照、検証、またはクリーンアップするために欠かせません。 - 変数を作成するときは、必ず
variable.scopesを明示的に設定してください。 既定のALL_SCOPESはすべてのプロパティピッカーに表示されてしまい、ほとんどの場合、望ましい設定ではありません。背景には["FRAME_FILL", "SHAPE_FILL"]、テキストカラーには["TEXT_FILL"]、間隔には["GAP"]など、具体的なスコープを使用してください。全リストは variable-patterns.md を参照してください。 - すべての Promise を
awaitしてください。 Promise をawaitせずに残さないでください。未処理の非同期呼び出し(例:figma.loadFontAsync(...)やfigma.setCurrentPageAsync(page)をawaitなしで呼び出す場合)は、完了を待たずに実行されるため、気付かないまま失敗したり、競合状態が発生したりします。非同期処理が完了する前にスクリプトが戻り、データが欠落したり変更が半端に適用されたりする可能性があります。
各ルールの誤った例/正しい例について詳しくは、よくある落とし穴と間違いをご覧ください。
2. ページのルール(重要)
use_figma の呼び出しごとにページのコンテキストはリセットされます — 毎回、figma.currentPage は最初のページから始まります。
ページの切り替え
await figma.setCurrentPageAsync(page) を使用してページを切り替え、そのコンテンツを読み込みます。同期セッターの figma.currentPage = page は機能しません — use_figma では "Setting figma.currentPage is not supported" がスローされます。必ず非同期メソッドを使用してください。
// Switch to a specific page (loads its content)
const targetPage = figma.root.children.find((p) => p.name === "My Page");
await figma.setCurrentPageAsync(targetPage);
// targetPage.children is now populated
setCurrentPageAsync の呼び出しは use_figma の実行ごとに最大1回にし、複数ページの作業は並列に分割する
1つのスクリプトでページを切り替えるのは最大1回までです。 figma.root.children をループして、その中でページを切り替えることは絶対にしないでください。
作業が複数ページにまたがる場合は、N 個の use_figma 呼び出し(対象ページごとに1つ)に分割し、並列に実行してください — N 個の use_figma ツール使用ブロックを含む単一のアシスタントメッセージを送信します。ハーネスがこれらを並行して実行し、各スクリプトは currentPage を正確に1回設定します。
明示的な指示: 分割して実行する場合、N 個のツール呼び出しを1つのメッセージで必ず発行してください。複数のターンに分けて送信しないでください。次の呼び出しを発行する前に1つ目の完了を待たないでください。ページごとに順次呼び出すと、このルールが置き換えるループ内のパターンより遅くなり、分割によるメリットがすべて失われます。
// AVOID — switches pages N times in one script, reloads the file each time
for (const page of figma.root.children) {
await figma.setCurrentPageAsync(page);
// ... touch this page ...
}
// PREFER — read-only discovery call to get page IDs, then in the NEXT message
// emit N parallel use_figma tool calls (one per page), each setting currentPage once.
複数ページにわたる作業では、読み取り、書き込みのどちらも、デフォルトで並列に分割して実行してください。詳しい理由は、gotchas.md → use_figma の呼び出しごとにページを1回だけ設定するをご覧ください。
スクリプト実行をまたぐ場合
use_figma の呼び出しを開始するたびに、figma.currentPage は最初のページにリセットされます。ワークフローが複数の呼び出しにまたがり、デフォルト以外のページを対象とする場合は、各呼び出しの冒頭で await figma.setCurrentPageAsync(page) を呼び出してください。
use_figma を複数回呼び出してファイルの状態を段階的に構築したり、別のスクリプトを実行する前に情報を取得したりできます。たとえば、既存のノードに関するメタデータを取得するスクリプトを作成し、そのデータを return してから、後続のスクリプトでそのノードを変更する際に使用します。
3. return が出力チャネルです
エージェントに見えるのは、return した値のみです。それ以外はすべて見えません。
- ID の返却(重要):キャンバスノードを作成または変更するすべてのスクリプトは、影響を受けたノードの ID を必ずすべて返す必要があります — 例:
return { createdNodeIds: [...], mutatedNodeIds: [...] }。これは必須要件であり、任意ではありません。 - 進捗の報告:
return { createdNodeIds: [...], count: 5, errors: [] } - エラー情報:スローされたエラーは自動的に捕捉され、返されます — そのまま伝播させるか、明示的に
throwしてください。 console.log()の出力がエージェントに返されることはありません- 後続の呼び出しで作成済みのオブジェクトを参照できるよう、常に実行可能なデータ(ID、件数、ステータス)を返してください
4. エディターモード
use_figma はデザインモード(editorType "figma"、デフォルト)で動作します。FigJam("figjam")と Slides("slides")では利用可能なノードタイプが異なります。FigJam ではほとんどのデザインノードがブロックされ、Slides では FigJam 専用ノードがブロックされます。
URL でエディターを確認してください: Design = figma.com/design/...、FigJam = figma.com/board/...、Slides = figma.com/slides/...。API が利用可能だと決めつける前に確認してください。
デザインモードで利用可能:Rectangle、Frame、Component、Text、Ellipse、Star、Line、Vector、Polygon、BooleanOperation、Slice、Page、Section、TextPath。
デザインモードでブロックされるもの:Sticky、Connector、ShapeWithText、CodeBlock、Slide、SlideRow、SlideGrid、InteractiveSlideElement、Webpage。
Slides モードで利用可能:Rectangle、Frame、Component、Text、Ellipse、Star、Line、Vector、Polygon、BooleanOperation、Slice、Section、TextPath、Slide、SlideRow、SlideGrid、InteractiveSlideElement。
Slides モードでブロックされるもの:Sticky、Connector、ShapeWithText、CodeBlock、Webpage、Page。
デザイン専用 API(ノードタイプに限りません): figma.createPage() は Design ファイル(figma.com/design/...)でのみ利用できます。FigJam(figma.com/board/...)と Slides(figma.com/slides/...)では、TypeError: figma.createPage no such property 'createPage' on the figma global object がスローされます。FigJam または Slides のワークフローでは figma.createPage() を出力しないでください。
Slides に関する注意: Slides ファイル専用の読み取りツールはまだありません。読み取り専用スクリプトで
use_figmaを使って確認してください(Section 6「まず確認する」パターンを参照)。また、視覚的なコンテキストにはget_screenshot/await node.screenshot()を使ってください。Slides 固有の API ガイダンスについては、figma-use-slides スキルを読み込んでください。
5. 効率的な API — 冗長な代替手段よりこちらを優先
これらの API を使うと、定型コードを減らし、順序の誤りをなくし、トークン出力を圧縮できます。冗長な代替手段より、常にこれらを優先してください。
node.query(selector) — CSS のようなノード検索
CSS のようなセレクターを使って、サブツリー内のノードを検索します。冗長な findAll とフィルターループの代わりに使えます。
// BEFORE — verbose traversal
const texts = frame.findAll(n => n.type === 'TEXT' && n.name === 'Title')
// AFTER — one-liner with query
const texts = frame.query('TEXT[name=Title]')
セレクター構文:
- タイプ:
FRAME、TEXT、RECTANGLE、ELLIPSE、COMPONENT、INSTANCE、SECTION(大文字と小文字を区別しません) - 属性の完全一致:
[name=Card]、[visible=true]、[opacity=0.5] - 属性の部分一致:
[name*=art](含む)、[name^=Header](前方一致)、[name$=Nav](後方一致) - ドットパスのたどり:
[fills.0.type=SOLID]、[fills.*.type=SOLID](ワイルドカードインデックス) - インスタンスの照合:
[mainComponent=nodeId]、[mainComponent.name=Button] - 結合子:
FRAME > TEXT(直接の子)、FRAME TEXT(すべての子孫)、A + B(隣接する兄弟)、A ~ B(一般兄弟) - 疑似クラス:
:first-child、:last-child、:nth-child(2)、:not(TYPE)、:is(FRAME, RECTANGLE)、:where(TEXT, ELLIPSE) - ノード ID:
#nodeIdまたは GUID のみ - カンマ:
TEXT, RECTANGLE(和集合) - ワイルドカード:
*(任意のタイプ)
QueryResult のメソッド:
| メソッド | 説明 |
|---|---|
.length | 一致したノードの数 |
.first() | 最初に一致したノード(または null) |
.last() | 最後に一致したノード(または null) |
.toArray() | 通常の配列に変換 |
.each(fn) | コールバックで反復し、チェーン用に this を返します |
.map(fn) | 新しい配列にマッピング |
.filter(fn) | 新しい QueryResult に絞り込み |
.values(keys) | プロパティ値を抽出:.values(['name', 'x', 'y']) → [{name, x, y}, ...] |
.set(props) | 一致したすべてのノードにプロパティを設定(下記の node.set() を参照) |
.query(selector) | 一致したノード内でサブクエリを実行 |
for...of | 反復可能 — for ループで使用できます |
スコープ: node.query() はそのノードのサブツリー内を検索します。ページ全体を検索するには、figma.currentPage.query('...') を使ってください。グローバルな figma.query() はありません。
例:
// Recolor all text inside cards
figma.currentPage.query('FRAME[name^=Card] TEXT').set({
fills: [{type: 'SOLID', color: {r: 0.2, g: 0.2, b: 0.8}}]
})
// Get names and positions of all frames
return figma.currentPage.query('FRAME').values(['name', 'x', 'y'])
// Find the first component named "Button"
const btn = figma.currentPage.query('COMPONENT[name=Button]').first()
// Find all instances of a specific component
figma.currentPage.query(`INSTANCE[mainComponent=${compId}]`)
// Find nodes with solid fills using dot-path traversal
figma.currentPage.query('[fills.0.type=SOLID]')
node.set(props) — プロパティをまとめて更新
1回の呼び出しで複数のプロパティを設定します。チェーンに使用できるよう、this を返します。
// BEFORE — one line per property
frame.opacity = 0.5
frame.cornerRadius = 8
frame.name = "Card"
// AFTER — single call
frame.set({ opacity: 0.5, cornerRadius: 8, name: "Card" })
優先キーの順序: オブジェクト内のキーの順序にかかわらず、layoutMode はほかのプロパティ(width/height など)よりも常に先に適用されます。これにより、layoutMode が設定されているかどうかによって resize() の動作が変わるという、よくあるバグを防げます。
幅/高さの処理: width と height は自動的に node.resize() に渡されます。たとえば、{ width: 200 } を設定すると、resize(200, currentHeight) が呼び出されます。
クエリとのチェーン:
// Find all rectangles named "Divider" and update them
figma.currentPage.query('RECTANGLE[name=Divider]').set({
fills: [{type: 'SOLID', color: {r: 0.9, g: 0.9, b: 0.9}}],
cornerRadius: 2
})
figma.createAutoLayout(direction?, props?) — 自動レイアウトのフレーム
自動レイアウトが有効で、両軸がコンテンツに合わせて伸縮するフレームを作成します。子要素同士に構造的な関係がある場合は、常にこれをデフォルトのコンテナとして使用してください(ルール 12a を参照)。
// BEFORE — manual setup, easy to get ordering wrong
const frame = figma.createFrame()
frame.layoutMode = 'VERTICAL'
frame.primaryAxisSizingMode = 'AUTO'
frame.counterAxisSizingMode = 'AUTO'
frame.layoutSizingHorizontal = 'HUG'
frame.layoutSizingVertical = 'HUG'
// AFTER — one call, layout ready
const frame = figma.createAutoLayout('VERTICAL')
子要素を追加した後すぐに layoutSizingHorizontal/Vertical = 'FILL' を使用できます。サイズ設定モードを手動で設定する必要はありません。
最初または2番目の引数として、オプションの props オブジェクトを受け取ります。
figma.createAutoLayout({ name: 'Card', itemSpacing: 12 }) // HORIZONTAL + props
figma.createAutoLayout('VERTICAL', { name: 'Column', itemSpacing: 8 }) // VERTICAL + props
node.placeholder — AI の作業中を知らせるシマーオーバーレイ
作業中であることを示す視覚的なシマーオーバーレイをノードに設定します。**作業が終わったら、必ずシマーを削除してください。**シマーが残っているとユーザーを混乱させ、作業が未完了であることを示してしまいます。
// Mark as in-progress
frame.placeholder = true
// ... build out the content ...
// MUST remove when done — never leave shimmers on finished nodes
frame.placeholder = false
複雑なレイアウトを構築する場合は、セクションに内容を追加する前に placeholder = true を設定し、各セクションが完成したら placeholder = false に設定します。
await node.screenshot(opts?) — インラインスクリーンショット
ノードを PNG としてキャプチャし、レスポンス内にインラインで返します。別途 get_screenshot を呼び出す必要がなくなります。
// Take a screenshot of a frame (returned inline in the tool response)
await frame.screenshot()
// Custom scale (default auto-scales: 0.5x or capped so max dimension ≤ 1024px)
await frame.screenshot({ scale: 2 })
// Include overlapping content from sibling nodes
await frame.screenshot({ contentsOnly: false })
使用するタイミング: ノードを作成または変更した後、同じスクリプト内で結果を視覚的に確認するために screenshot() を呼び出します。別途 get_screenshot を呼び出す必要はありません。
自動命名: 画像のキャプションにはノードのメタデータ("Card (300x150 at 0,60).png")が含まれ、画像を解析しなくても配置状況を把握できます。
デフォルトのスケーリング: 0.5x のスケールを使用しますが、出力の最大寸法が 1024px を超えないように自動的に上限が設定されます。{ scale: N } を明示的に指定すると、この上限は適用されません。
6. 段階的なワークフロー(バグを防ぐ方法)
バグの最も一般的な原因は、1回の use_figma 呼び出しで多くの作業を一度に行おうとすることです。小さな手順に分けて作業し、それぞれの後に検証してください。
主なルール
- 1回の
use_figma呼び出しにつき、論理操作は最大10個までです。「論理操作」とは、ノードを作成し、プロパティを設定して、親にすることです。20個のノードを作成する必要がある場合は、2~3回に分けてください。 - プレースホルダーから始め、上から下へ構築してください。 各セクションで
placeholder = trueに設定して外側の構造を先に作成し、その後の呼び出しでプレースホルダーを実際の内容に段階的に置き換えます。
手順
- まず調査します。 何かを作成する前に、読み取り専用の
use_figmaを実行して、ファイルにすでに存在するもの(ページ、コンポーネント、変数、命名規則)を確認します。既存のものに合わせてください。 - 骨組みを作成します。 プレースホルダーとなるセクションを含むトップレベルの構造を作成します。各セクションで
placeholder = trueに設定し、ユーザーが進捗を確認できるようにします。 - セクションを段階的に埋めます。 以降の各呼び出しでは、1つのセクションの内容を追加し、完了したら
placeholder = falseに設定します。screenshot()を撮って確認します。 - 各呼び出しから ID を返します。 作成したノード ID、変数 ID、コレクション ID は、必ずオブジェクトとして
returnします(例:return { createdNodeIds: [...] })。後続の呼び出しでこれらを入力として使用します。 - 各手順の後に検証します。
get_metadataを使用して、構造(数、名前、階層、位置)を確認します。インラインでawait node.screenshot()を使用するか、大きな節目の後にget_screenshotを使用して、視覚的な問題を見つけます。 - 先に進む前に修正します。 検証で問題が見つかった場合は、次の手順に進む前に修正してください。問題のある基盤の上に構築してはいけません。
複雑なタスクで推奨される手順の順序
Step 1: Inspect file — discover existing pages, components, variables, conventions
Step 2: Create tokens/variables (if needed)
→ validate with get_metadata
Step 3: Create individual components
→ validate with get_metadata + get_screenshot
Step 4: Compose layouts from component instances
→ validate with get_screenshot
Step 5: Final verification
各ステップで検証する項目
| 実行後... | get_metadata で確認 | get_screenshot で確認 |
|---|---|---|
| 変数の作成 | コレクション数、変数数、モード名 | — |
| コンポーネントの作成 | 子の数、バリアント名、プロパティの定義 | バリアントが表示されていること、折りたたまれていないこと、グリッドが読みやすいこと |
| 変数のバインド | ノードのプロパティにバインドが反映されていること | 色/トークンが正しく解決されていること |
| レイアウトの構成 | インスタンスノードに mainComponent があり、階層が正しいこと | テキストが切り取られていないこと、要素が重なっていないこと、間隔が正しいこと |
7. エラーからの復旧と自己修正
use_figma はアトミックです。スクリプトが失敗した場合、実行されません。 スクリプトでエラーが発生しても、ファイルに変更は加えられません。ファイルは呼び出し前と同じ状態のままです。そのため、中途半端なノードや失敗したスクリプトによる孤立要素が残ることはなく、修正後に安全に再試行できます。
use_figma がエラーを返したとき
- 停止します。 コードをすぐに修正して再試行しないでください。
- エラーメッセージを注意深く読みます。 API の誤った使い方、フォントの不足、無効なプロパティ値など、何が問題だったのかを正確に把握します。
- エラーが不明確な場合は、
get_metadataまたはget_screenshotを呼び出して、現在のファイル状態を把握します。 - エラーメッセージに基づいてスクリプトを修正します。
- 修正したスクリプトを再試行します。
よくある自己修正パターン
| エラーメッセージ | 考えられる原因 | 修正方法 |
|---|---|---|
"not implemented" | figma.notify() を使用した | 削除します。出力には return を使用してください |
"node must be an auto-layout frame or a child of an auto-layout frame" / "FILL can only be set on children of auto-layout frames" / "HUG can only be set on auto-layout frames or text children of auto-layout frames" / "FILL cannot be set on absolute positioned auto-layout children" / "FILL cannot be set on canvas grid children" | 構造上のコンテキストで許可されていないノードに HUG/FILL を設定しようとした(例:親がオートレイアウトではない、appendChild の前に実行した、テキスト以外の子に HUG を設定しようとした、絶対位置指定の子に FILL を設定しようとした) | figma.createAutoLayout() で親をオートレイアウトにします。先に appendChild を実行します。HUG はオートレイアウトフレーム自体、または TEXT の子にのみ使用します。絶対位置指定/変更不可/グリッドの子には、FIXED と resize() を使用します。gotchas.md を参照してください |
"Setting figma.currentPage is not supported" | 同期ページセッター(figma.currentPage = page)を使用した。これは機能しません | ページを切り替える唯一の方法である await figma.setCurrentPageAsync(page) を使用します |
| プロパティ値が範囲外 | カラーチャンネルが 1 を超えている(0~1 ではなく 0~255 を使用した) | 255 で割ります |
"Cannot read properties of null" | ノードが存在しない(ID が誤っている、ページが違う) | ページのコンテキストを確認し、ID を検証します |
| スクリプトが停止する/応答がない | 無限ループ、または未解決の Promise | while(true) や await の不足がないか確認し、コードが終了することを確かめます |
"The node with id X does not exist" | 子の detachInstance() によって親インスタンスが暗黙的に切り離され、ID が変わった | 安定した(インスタンスではない)親フレームからトラバースして、ノードを再特定します |
スクリプトは成功したが、結果がおかしいとき
get_metadataを呼び出して、構造が正しいか(階層、数、位置)確認します。get_screenshotを呼び出して、見た目が正しいか確認します。テキストの切り取り(行の高さによってコンテンツが欠ける)や要素の重なりに注意してください。これらはよく起き、見落としやすい問題です。- 不一致の内容を特定します。構造の問題(階層の誤り、ノードの欠落)ですか、それとも見た目の問題(色の誤り、レイアウトの崩れ、コンテンツの切り取り)ですか?
- 問題のある部分だけを修正する、対象を絞ったスクリプトを作成します。すべてを作り直さないでください。
検証ワークフローの全容については、検証とエラーからの復旧を参照してください。
8. 事前チェックリスト
use_figma を呼び出す前に、以下を必ず確認してください。
- コードで
returnを使ってデータを返している(figma.closePlugin()は使わない) - コードが非同期 IIFE でラップされていない(自動でラップされます)
-
returnの値に、実行可能な情報(ID、件数など)を含む構造化データが含まれている -
figma.notify()を一切使っていない - 出力に
console.log()を一切使っていない(代わりにreturnを使う) - すべての色が 0~1 の範囲になっている(0~255 ではない)
- Paint の
colorオブジェクトには{r, g, b}のみを使い、aフィールドを含めていない(不透明度は Paint レベルに設定します:{ type: 'SOLID', color: {...}, opacity: 0.5 }) - Fills/strokes はその場で変更せず、新しい配列として再代入している
- ページの切り替えに
await figma.setCurrentPageAsync(page)を使っている(同期セッターのfigma.currentPage = pageは機能しません) -
parent.appendChild(child)の後にlayoutSizingVertical/Horizontal = 'FILL'を設定している - すべてのテキスト変更で、標準的な手順に従っている:
loadFontAsync→await→characters/フォント/サイズなどを変更 → 影響を受けたノード ID を返す。Inter(たまたま事前に読み込まれているだけ)に限らず、どのフォントファミリー/スタイルでも機能します。 - スタイル名は
listAvailableFontsAsync()で確認済みであり、記憶を頼りに推測していない("SemiBold"と"Semi Bold"の取り違えはよくある落とし穴です) -
FONT_FAMILYスコープの変数では、setBoundVariable("fontFamily", …)、setValueForMode、またはsetExplicitVariableModeForCollectionを呼ぶ前に、関連するすべてのモードの値を読み込んでいる -
lineHeight/letterSpacingは数値のみではなく、{unit, value}形式を使っている - サイズモードを設定する前に
resize()を呼び出している(resize()はサイズモードを FIXED にリセットします) - 複数ステップのワークフローでは、前の呼び出しで取得した ID を変数ではなく文字列リテラルとして渡している
- 新しい最上位ノードを (0,0) から離れた位置に配置し、既存のコンテンツと重ならないようにしている
- 構造的に関連する子要素を持つコンテナには、絶対 x/y ではなく
figma.createAutoLayout()を使っている(ルール 12a を参照) - 作成または変更したすべてのノード ID を収集し、
returnの値に含めている - すべての非同期呼び出し(
loadFontAsync、setCurrentPageAsync、importComponentByKeyAsyncなど)をawaitしている(Promise を放置しない)
9. 作成する前に規約を確認する
何かを作成する前に、必ず Figma ファイルを確認してください。 ファイルによって、命名規則、変数構成、コンポーネントのパターンは異なります。新しい規約を持ち込むのではなく、既存の規約にコードを合わせてください。
規約(命名、スコープ、構造など)が不明な場合は、まず Figma ファイルを確認し、次にユーザーのコードベースを確認してください。どちらにも情報がない場合に限り、一般的なパターンを使ってください。
簡易確認スクリプト
すべてのページと最上位ノードを一覧表示する:
const pages = figma.root.children.map(p => `${p.name} id=${p.id} children=${p.children.length}`);
return pages.join('\n');
すべてのページにある既存コンポーネントを一覧表示する:
公開済みコンポーネントには search_design_system を使用できます。キャンバス上のコンポーネントには、2 段階のファンアウトを使ってください。1 つのスクリプト内でページをループしないでください。
ステップ 1:ページ ID を取得するため、読み取り専用の use_figma を 1 回実行します:
return figma.root.children.map(p => ({ id: p.id, name: p.name }));
ステップ 2:次のアシスタントのターンで、ページごとに 1 つの use_figma を並列で出力します(N 個のツール使用ブロックを 1 つのメッセージに含めます)。それぞれで以下を実行します:
// Read-only inspection — skip invisible instance interiors for the
// hundreds-of-times-faster findAllWithCriteria.
figma.skipInvisibleInstanceChildren = true;
const page = await figma.getNodeByIdAsync(PAGE_ID);
await figma.setCurrentPageAsync(page);
// findAllWithCriteria uses an indexed type lookup — hundreds of times faster
// than the findAll(n => n.type === '…') side-effect-in-predicate antipattern.
const matches = page.findAllWithCriteria({ types: ['COMPONENT', 'COMPONENT_SET'] });
return matches.map(n => ({ page: page.name, name: n.name, type: n.type, id: n.id }));
既存の変数コレクションとその規約を一覧表示する:
const collections = await figma.variables.getLocalVariableCollectionsAsync();
const results = collections.map(c => ({
name: c.name, id: c.id,
varCount: c.variableIds.length,
modes: c.modes.map(m => m.name)
}));
return results;
10. 参考ドキュメント
タスクの内容に応じて、必要なドキュメントを読み込んでください。
| ドキュメント | 読み込むタイミング | 内容 |
|---|---|---|
| gotchas.md | use_figma を実行する前 | 既知の落とし穴をすべて、誤った例/正しい例のコードとともに説明しています。まずはテキスト編集の基本レシピを確認してください。 |
| common-patterns.md | 動作するコード例が必要な場合 | スクリプトのひな形:図形、テキスト、オートレイアウト、変数、コンポーネント、複数ステップのワークフロー |
| plugin-api-patterns.md | ノードを作成・編集する場合 | 塗り、線、オートレイアウト、エフェクト、グループ化、複製、スタイル |
| api-reference.md | API の正確な仕様が必要な場合 | ノードの作成、変数 API、主要なプロパティ、動作する機能と動作しない機能 |
| validation-and-recovery.md | 複数ステップの書き込みやエラーからの復旧を行う場合 | get_metadata と get_screenshot のワークフロー、必須のエラー復旧手順 |
| component-patterns.md | コンポーネントやバリアントを作成する場合 | combineAsVariants、コンポーネントプロパティ、INSTANCE_SWAP、バリアントのレイアウト、既存コンポーネントの検索、メタデータの走査 |
| variable-patterns.md | 変数を作成・バインドする場合 | コレクション、モード、スコープ、エイリアス、バインドパターン、既存変数の検索 |
| text-style-patterns.md | テキストスタイルを作成・適用する場合 | タイプスケール、listAvailableFontsAsync によるフォント検索、スタイルの一覧表示、ノードへのスタイル適用 |
| effect-style-patterns.md | エフェクトスタイルを作成・適用する場合 | ドロップシャドウ、スタイルの一覧表示、ノードへのスタイル適用 |
| plugin-api-standalone.index.md | API 全体の仕様を把握する必要がある場合 | Plugin API に含まれるすべての型、メソッド、プロパティの索引 |
| plugin-api-standalone.d.ts | 型シグネチャの正確な情報が必要な場合 | 型定義ファイル全体。特定のシンボルを grep で検索し、一度にすべてを読み込まないでください。 |
11. スニペットの例
このドキュメントでは、さまざまな箇所にスニペットが記載されています。これらのスニペットには、再利用できる便利な Plugin API のコードが含まれています。そのまま使うことも、作業を進める際のひな形として使うこともできます。汎用的なスニペットとして文書化するのが最適な重要概念があれば、その内容を明記してディスクに保存し、今後再利用できるようにしてください。