Framer core workflow a
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill framer-core-workflow-aAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Execute Framer primary workflow: Core Workflow A.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
4.9 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Framer CMS Plugin — Managed Collections
Overview
Build a Framer plugin that syncs external data into CMS Managed Collections. Managed Collections are plugin-controlled — your plugin creates the schema and populates items. This is the primary integration pattern for connecting Framer to external CMSes, databases, or APIs.
Prerequisites
- Completed
framer-install-authsetup - Plugin dev server running
- Understanding of Framer CMS concepts
Instructions
Step 1: Create a Managed Collection
// src/App.tsx — CMS sync plugin
import { framer } from 'framer-plugin';
import { useState } from 'react';
framer.showUI({ width: 340, height: 400, title: 'Content Sync' });
export function App() {
const [status, setStatus] = useState('');
const syncCollection = async () => {
setStatus('Fetching data...');
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await response.json();
setStatus('Creating collection...');
const collection = await framer.createManagedCollection({
name: 'Blog Posts',
fields: [
{ id: 'title', name: 'Title', type: 'string' },
{ id: 'body', name: 'Body', type: 'formattedText' },
{ id: 'author', name: 'Author', type: 'string' },
{ id: 'slug', name: 'Slug', type: 'slug', userEditable: false },
],
});
setStatus(`Syncing ${posts.length} items...`);
const items = posts.slice(0, 20).map((post: any) => ({
fieldData: {
title: post.title,
body: `<p>${post.body}</p>`,
author: `User ${post.userId}`,
slug: post.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
},
}));
await collection.setItems(items);
setStatus(`Synced ${items.length} posts`);
framer.notify(`Synced ${items.length} blog posts`);
};
return (
<div style={{ padding: 16 }}>
<h3>Blog Post Sync</h3>
<button onClick={syncCollection} style={{ width: '100%', padding: 8 }}>Sync Now</button>
{status && <p style={{ marginTop: 8, fontSize: 13, color: '#666' }}>{status}</p>}
</div>
);
}
Step 2: Handle CMS Field Types
// Framer CMS field types reference
const fields = [
{ id: 'title', name: 'Title', type: 'string' as const },
{ id: 'content', name: 'Content', type: 'formattedText' as const },
{ id: 'price', name: 'Price', type: 'number' as const },
{ id: 'featured', name: 'Featured', type: 'boolean' as const },
{ id: 'publishDate', name: 'Published', type: 'date' as const },
{ id: 'heroImage', name: 'Hero', type: 'image' as const },
{ id: 'category', name: 'Category', type: 'enum' as const, cases: [
{ id: 'tech', name: 'Technology' },
{ id: 'design', name: 'Design' },
]},
{ id: 'slug', name: 'Slug', type: 'slug' as const, userEditable: false },
];
Step 3: Incremental Sync with Change Detection
async function incrementalSync(collection: ManagedCollection, newData: any[]) {
const existing = await collection.getItems();
const existingMap = new Map(existing.map(i => [i.fieldData.slug, i]));
const toUpsert = newData.map(item => {
const match = existingMap.get(item.slug);
return match ? { ...item, id: match.id } : item;
});
await collection.setItems(toUpsert);
}
Step 4: Unmanaged Collection Access
// Read from user-created CMS collections (not plugin-managed)
const collections = await framer.getCollections();
for (const col of collections) {
if (col.type === 'unmanaged') {
const items = await col.getItems();
console.log(`${col.name}: ${items.length} items`);
}
}
Output
- Managed CMS collection with typed fields
- External data synced into Framer CMS
- Incremental sync support
- Image auto-upload from URLs
Error Handling
| Error | Cause | Solution |
|---|---|---|
Collection exists | Duplicate name | Use getManagedCollection() first |
Invalid field type | Wrong type string | Use: string, formattedText, number, boolean, date, image, enum, slug |
Image upload failed | URL not public | Ensure images are publicly accessible |
setItems timeout | Too many items | Batch into chunks of 100 |
Resources
Next Steps
For code components and overrides, see framer-core-workflow-b.