From webflow-pack
Installs webflow-api SDK and configures Webflow authentication with API tokens or OAuth 2.0. Use for initializing client in Node.js/TypeScript projects.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin webflow-packThis skill is limited to using the following tools:
Set up the official Webflow JS SDK (`webflow-api` on npm) and configure authentication
Sets up TypeScript local dev workflow for Webflow Data API with hot reload via tsx, Vitest mocks, Express webhooks, and ngrok tunneling.
Initializes, builds, and deploys Webflow Cloud applications via CLI with non-interactive flags, mount path validation, and package manager detection. Use for Webflow project creation and deployment.
Guides deployment of Webflow Code Components to workspaces via Webflow CLI. Covers pre-flight checks, authentication, execution, and verification. Use for publish/deploy requests.
Share bugs, ideas, or general feedback.
Set up the official Webflow JS SDK (webflow-api on npm) and configure authentication
using either a workspace/site API token or OAuth 2.0 for Data Client Apps.
https://developers.webflow.com# npm
npm install webflow-api
# pnpm
pnpm add webflow-api
# yarn
yarn add webflow-api
The package is webflow-api (not @webflow/sdk). Current version: 3.x (Data API v2).
Webflow offers two auth methods:
| Method | Use Case | Scope |
|---|---|---|
| API Token (workspace) | Server-side scripts, internal tools | All sites in workspace |
| API Token (site) | Single-site integrations | One site only |
| OAuth 2.0 | Public apps, Webflow Marketplace apps | User-authorized scopes |
# Set environment variable (never hardcode tokens)
echo 'WEBFLOW_API_TOKEN=your-token-here' >> .env
echo '.env' >> .gitignore
import { WebflowClient } from "webflow-api";
// Initialize with workspace or site token
const webflow = new WebflowClient({
accessToken: process.env.WEBFLOW_API_TOKEN!,
});
For apps that need user authorization, implement the OAuth 2.0 authorization code flow:
import express from "express";
import { WebflowClient } from "webflow-api";
const app = express();
const CLIENT_ID = process.env.WEBFLOW_CLIENT_ID!;
const CLIENT_SECRET = process.env.WEBFLOW_CLIENT_SECRET!;
const REDIRECT_URI = "https://yourapp.com/auth/webflow/callback";
// Step 1: Redirect user to Webflow authorization page
// Scopes: sites:read, sites:write, cms:read, cms:write,
// pages:read, pages:write, forms:read, ecommerce:read,
// ecommerce:write, custom_code:read, custom_code:write
app.get("/auth/webflow", (req, res) => {
const scopes = "sites:read cms:read cms:write";
const authUrl =
`https://webflow.com/oauth/authorize` +
`?client_id=${CLIENT_ID}` +
`&response_type=code` +
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
`&scope=${encodeURIComponent(scopes)}`;
res.redirect(authUrl);
});
// Step 2: Exchange authorization code for access token
// The authorization code expires in 15 minutes
app.get("/auth/webflow/callback", async (req, res) => {
const code = req.query.code as string;
const response = await fetch("https://api.webflow.com/oauth/access_token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code,
grant_type: "authorization_code",
redirect_uri: REDIRECT_URI,
}),
});
const { access_token } = await response.json();
// Store access_token securely — it does not expire but can be revoked
const webflow = new WebflowClient({ accessToken: access_token });
const { sites } = await webflow.sites.list();
res.json({ authorized: true, siteCount: sites?.length });
});
import { WebflowClient } from "webflow-api";
const webflow = new WebflowClient({
accessToken: process.env.WEBFLOW_API_TOKEN!,
});
async function verify() {
// List all sites accessible with this token
const { sites } = await webflow.sites.list();
if (!sites || sites.length === 0) {
throw new Error("No sites accessible. Check token scopes.");
}
for (const site of sites) {
console.log(`Site: ${site.displayName} (${site.id})`);
console.log(` Short name: ${site.shortName}`);
console.log(` Last published: ${site.lastPublished}`);
}
}
verify().catch(console.error);
| Scope | Access |
|---|---|
sites:read | List/get sites |
sites:write | Publish sites |
cms:read | Read collections and items |
cms:write | Create/update/delete CMS items |
pages:read | List/get pages |
pages:write | Update page content |
forms:read | Read form submissions |
ecommerce:read | Read products, orders, inventory |
ecommerce:write | Create/update products, fulfill orders |
custom_code:read | Read registered custom code |
custom_code:write | Register/apply custom code |
webflow-api package.env file, git-ignored)WebflowClient instance| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid or revoked token | Generate new token at developers.webflow.com |
403 Forbidden | Token missing required scope | Add scopes in app settings or generate new token |
429 Too Many Requests | Rate limit exceeded | Wait for Retry-After header (60s reset) |
MODULE_NOT_FOUND | Wrong package name | Use webflow-api, not @webflow/sdk |
| OAuth code expired | Authorization code > 15 min old | Re-initiate OAuth flow promptly |
After successful auth, proceed to webflow-hello-world for your first API call.