Agent Skills: Framer Rate Limits

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/framer-rate-limits

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/framer-pack/skills/framer-rate-limits

Skill Files

Browse the full folder contents for framer-rate-limits.

Download Skill

Loading file tree…

plugins/saas-packs/framer-pack/skills/framer-rate-limits/SKILL.md

Skill Metadata

Name
framer-rate-limits
Description
'Implement Framer rate limiting, backoff, and idempotency patterns.

Framer Rate Limits

Overview

Handle Framer API rate limits for Server API and plugin operations. The Server API uses WebSocket, so rate limits apply per-connection. CMS operations are limited by collection size and concurrent writes.

Rate Limit Reference

| Operation | Limit | Notes | |-----------|-------|-------| | Server API connections | 1 per site | WebSocket, persistent | | CMS setItems | ~100 items/call | Batch larger sets | | CMS getItems | No hard limit | Returns all items | | Plugin API calls | Debounced | Framer throttles internally | | Publish | ~1/minute | Site publishing | | Image upload | Concurrent limit | Via CMS image fields |

Instructions

Step 1: Batch CMS Writes

async function batchSetItems(collection: any, items: any[], batchSize = 100) {
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    await collection.setItems(batch);
    console.log(`Synced ${Math.min(i + batchSize, items.length)}/${items.length}`);
    if (i + batchSize < items.length) {
      await new Promise(r => setTimeout(r, 1000)); // 1s between batches
    }
  }
}

Step 2: Debounced Plugin Operations

// Debounce rapid plugin UI interactions
function debounce<T extends (...args: any[]) => any>(fn: T, ms = 300) {
  let timer: NodeJS.Timeout;
  return (...args: Parameters<T>) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}

const debouncedSync = debounce(async () => {
  await syncCollection();
}, 500);

Step 3: Retry for Server API

async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      return await fn();
    } catch (err: any) {
      if (i === maxRetries) throw err;
      const delay = 1000 * Math.pow(2, i);
      console.log(`Retry ${i + 1} in ${delay}ms`);
      await new Promise(r => setTimeout(r, delay));
    }
  }
  throw new Error('Unreachable');
}

Error Handling

| Error | Cause | Solution | |-------|-------|----------| | WebSocket disconnected | Connection timeout | Reconnect with backoff | | setItems slow | Large batch | Split into chunks of 100 | | Publish rate limited | Too frequent | Wait 60s between publishes |

Resources

Next Steps

For security, see framer-security-basics.