framer-plugins
Framer Plugin SDKの専門家です。Framerプラグインの構築、デバッグ、修正が必要な場合に活用できます。ManagedCollection API、CMSSync、プラグインモード、UIパターン、権限管理、データストレージ、よくある落とし穴など、幅広い機能や知識をカバーしています。
description の原文を見る
Framer Plugin SDK expert. Use when building, debugging, or modifying Framer plugins. Covers ManagedCollection API, CMS sync, plugin modes, UI patterns, permissions, data storage, and common pitfalls.
SKILL.md 本文
Framer プラグイン開発ガイド
Framer Plugin SDK のエキスパートです。Framer プラグインの構築、デバッグ、または変更時にこのリファレンスを使用してください。常にプロジェクトの CLAUDE.md でプロジェクト固有のオーバーライドを確認してください。
クイックリファレンス
- SDK パッケージ:
framer-plugin(v3.6+) - スキャフォルディング:
npm create framer-plugin@latest - ビルド: Vite +
vite-plugin-framer - ベーススタイル:
import "framer-plugin/framer.css" - コアインポート:
import { framer } from "framer-plugin" - 開発ワークフロー:
npm run dev→ Framer → Developer Tools → Development Plugin
framer.json
すべてのプラグインにはプロジェクトルートに framer.json が必要です:
{
"id": "6bbb4f",
"name": "My Plugin",
"modes": ["configureManagedCollection", "syncManagedCollection"],
"icon": "/icon.svg"
}
id— ユニークな 16 進数識別子(スキャフォルディングで自動生成)modes— サポートされるモードの配列(下記参照)icon—public/内の 30×30 SVG/PNG。SVG は中央揃えに注意が必要です。
プラグインモード
| モード | 用途 | framer.mode の値 |
|---|---|---|
canvas | 汎用キャンバスアクセス | "canvas" |
configureManagedCollection | CMS: 初回セットアップ / フィールド設定 | "configureManagedCollection" |
syncManagedCollection | CMS: 既存コレクションの再同期 | "syncManagedCollection" |
image | ユーザーが画像を選択 | "image" |
editImage | 既存画像を編集 | "editImage" |
collection | ユーザー編集可能なコレクションにアクセス | "collection" |
CMS プラグインは configureManagedCollection と syncManagedCollection の両方を使用します。
コア framer API
UI 管理
framer.showUI({ position?, width, height, minWidth?, minHeight?, maxWidth?, resizable? })
framer.hideUI()
framer.closePlugin(message?, { variant: "success" | "error" | "info" }) // returns never
framer.notify(message, { variant?, durationMs?, button?: { text, onClick } })
framer.setCloseWarning(message | false) // 同期中の終了前に警告
framer.setBackgroundMessage(message) // プラグイン非表示実行時のステータス
framer.setMenu([{ label, onAction, visible? }, { type: "separator" }])
closePluginは内部でFramerPluginClosedErrorをスローします — catch ブロックで常に無視してくださいshowUIは flicker を避けるためにuseLayoutEffectで呼び出す必要があります
プロパティ
framer.mode— 現在のモード文字列
コレクションアクセス
framer.getActiveManagedCollection() // → Promise<ManagedCollection>
framer.getActiveCollection() // → Promise<Collection> (非管理)
framer.getManagedCollections() // → Promise<ManagedCollection[]>
framer.getCollections() // → Promise<Collection[]>
framer.createManagedCollection() // → Promise<ManagedCollection>
キャンバスメソッド(canvas モード)
framer.addImage({ image, name, altText })
framer.setImage({ image, name, altText })
framer.getImage()
framer.addText(text)
framer.addFrame()
framer.addSVG(svg, name) // 最大 10kB
framer.addComponentInstance({ url, attributes? })
framer.getSelection()
framer.subscribeToSelection(callback)
ManagedCollection API
interface ManagedCollection {
id: string
getItemIds(): Promise<string[]>
setItemOrder(ids: string[]): Promise<void>
getFields(): Promise<ManagedCollectionField[]>
setFields(fields: ManagedCollectionFieldInput[]): Promise<void>
addItems(items: ManagedCollectionItemInput[]): Promise<void> // upsert!
removeItems(ids: string[]): Promise<void>
setPluginData(key: string, value: string | null): Promise<void>
getPluginData(key: string): Promise<string | null>
}
重要: addItems() は upsert です — 新しいアイテムを追加し、id でマッチした既存のアイテムを更新します。
フィールド型
"boolean" | "color" | "number" | "string" | "formattedText" |
"image" | "file" | "link" | "date" | "enum" |
"collectionReference" | "multiCollectionReference" | "array"
フィールド定義
interface ManagedCollectionFieldInput {
id: string
name: string
type: CollectionFieldType
userEditable?: boolean // 管理対象ではデフォルト false
cases?: { id, name }[] // "enum" の場合
collectionId?: string // コレクション参照の場合
fields?: ManagedCollectionFieldInput[] // "array"(ギャラリー)の場合
}
アイテム構造
interface ManagedCollectionItemInput {
id: string
slug: string // ユニークである必要があり、最大 64 文字
draft: boolean
fieldData: Record<string, FieldDataEntryInput>
}
フィールドデータ値 — 型を明示的に指定する必須
{ type: "string", value: "hello" }
{ type: "number", value: 42 }
{ type: "boolean", value: true }
{ type: "date", value: "2024-01-01T00:00:00Z" } // ISO 8601
{ type: "link", value: "https://example.com" }
{ type: "image", value: "https://img.url" | null }
{ type: "file", value: "https://file.url" | null }
{ type: "color", value: "#FF0000" | null }
{ type: "formattedText", value: "<p>hello</p>", contentType: "html" }
{ type: "enum", value: "case-id" }
{ type: "collectionReference", value: "item-id" }
{ type: "multiCollectionReference", value: ["id1", "id2"] }
{ type: "array", value: [{ id: "1", fieldData: { ... } }] }
権限
import { framer, useIsAllowedTo, type ProtectedMethod } from "framer-plugin"
// 命令型チェック
framer.isAllowedTo("ManagedCollection.addItems", "ManagedCollection.removeItems")
// React フック(リアクティブ)
const canSync = useIsAllowedTo("ManagedCollection.addItems", "ManagedCollection.removeItems")
// 標準的な CMS 同期権限
const SYNC_METHODS = [
"ManagedCollection.setFields",
"ManagedCollection.addItems",
"ManagedCollection.removeItems",
"ManagedCollection.setPluginData",
] as const satisfies ProtectedMethod[]
データストレージ決定木
| 用途 | 使用するもの | 理由 |
|---|---|---|
| API キー、認証トークン | localStorage | ユーザー単位、サイズ警告なし、共有なし |
| ユーザー設定 | localStorage | ユーザー単位、同期的 |
| データソース ID、最後の同期時刻 | collection.setPluginData() | コラボレーター間で共有、コレクションに紐付け |
| プロジェクトレベルの設定 | framer.setPluginData() | 共有だが 4kB の合計制限 |
pluginData: エントリあたり 2kB、合計 4kB。文字列のみ。削除する場合はnullを渡します。localStorage: プラグインオリジンごとにサンドボックス化されます。サイズ警告なし。setPluginData()は "Invoking protected message type" トーストをトリガーします(SDK バグ)。
"framer-plugin" からの主要エクスポート
import { framer, useIsAllowedTo, FramerPluginClosedError } from "framer-plugin"
import type {
ManagedCollection, ManagedCollectionField, ManagedCollectionFieldInput,
ManagedCollectionItemInput, FieldDataInput, FieldDataEntryInput,
ProtectedMethod, Collection, CollectionItem
} from "framer-plugin"
import "framer-plugin/framer.css"
参考資料
詳細情報については、このスキルディレクトリの関連ファイルを参照してください:
- api-reference.md — 完全な API シグネチャと型定義
- patterns.md — 32 の公式例から抽出した一般的なプラグインパターン
- pitfalls.md — 既知の落とし穴、ワークアラウンド、デバッグのコツ
- marketplace.md — マーケットプレイス提出ワークフロー、リスト要件、レビュープロセス、プラグインポリシー、公開後の義務
主要ルール
- 常にプロジェクトの
CLAUDE.mdでプロジェクト固有のオーバーライドと決定を確認してください - 新機能を構築する前に、marketplace.md を確認してください — プラグインは Framer のポリシー(英語 UI、ライト+ダークモード、広告なし、USD のみの価格設定、IP 所有権など)に準拠する必要があります。そうしないと、約 3 週間のレビュープロセス中に却下されます
- CMS プラグインは UI を表示する前に
syncManagedCollectionモードでサイレント同期を試みるべきです addItems()は upsert です — 追加する前に既存アイテムを確認する必要はありません- フィールドデータ値は明示的な
typeプロパティを含める必須:{ type: "string", value: "..." } - 機密情報/ユーザー固有のデータには
localStorageを、共有同期状態にはpluginDataを使用します - 標準的な Framer プラグインスタイルのために
"framer-plugin/framer.css"をインポートしてください - Framer の CSS オーバーライドを避けるために
<button>の代わりに<div role="button">を使用してください FramerPluginClosedErrorを catch ブロックで処理してください — サイレントに無視します- リサイズ時の flicker を避けるために
showUIをuseLayoutEffectで呼び出してください - 同期操作の前に常に
framer.isAllowedTo()で権限を確認してください - スラッグはユニークである必要があり、最大 64 文字です — タイトルベースのスラッグにユニーク ID サフィックスを追加します
- フィールド定義で手動編集可能なフィールドに
userEditable: trueを使用します - upsert 中にユーザー編集可能なフィールドを
fieldDataに含めないでください — これらを省略することでユーザー値が保持されます - 同期中にすべてを削除してから再追加しないでください — ソースに存在しないアイテムのみを削除してユーザーデータを保持します
ManagedCollectionにはgetItems()がありません — アイテム ID のみを読み取ることができ、フィールドデータは読み取れません
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- fredm00n
- リポジトリ
- fredm00n/framerlabs
- ライセンス
- MIT
- 最終更新
- 2026/4/17
Source: https://github.com/fredm00n/framerlabs / ライセンス: MIT