Claude-code-plugins webflow-install-auth

install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/webflow-pack/skills/webflow-install-auth" ~/.claude/skills/jeremylongshore-claude-code-plugins-webflow-install-auth && rm -rf "$T"
manifest: plugins/saas-packs/webflow-pack/skills/webflow-install-auth/SKILL.md
source content

Webflow Install & Auth

Overview

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.

Prerequisites

  • Node.js 18+
  • npm, pnpm, or yarn
  • A Webflow account with a workspace
  • An API token (workspace or site) from
    https://developers.webflow.com

Instructions

Step 1: Install the SDK

# 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).

Step 2: Choose Authentication Method

Webflow offers two auth methods:

MethodUse CaseScope
API Token (workspace)Server-side scripts, internal toolsAll sites in workspace
API Token (site)Single-site integrationsOne site only
OAuth 2.0Public apps, Webflow Marketplace appsUser-authorized scopes

Step 3: Token-Based Authentication

# 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!,
});

Step 4: OAuth 2.0 Flow (Data Client Apps)

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 });
});

Step 5: Verify Connection

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);

Webflow API Scopes Reference

ScopeAccess
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

Output

  • Installed
    webflow-api
    package
  • Environment variable with API token (
    .env
    file, git-ignored)
  • Working
    WebflowClient
    instance
  • Verified connection by listing accessible sites

Error Handling

ErrorCauseSolution
401 Unauthorized
Invalid or revoked tokenGenerate new token at developers.webflow.com
403 Forbidden
Token missing required scopeAdd scopes in app settings or generate new token
429 Too Many Requests
Rate limit exceededWait for
Retry-After
header (60s reset)
MODULE_NOT_FOUND
Wrong package nameUse
webflow-api
, not
@webflow/sdk
OAuth code expiredAuthorization code > 15 min oldRe-initiate OAuth flow promptly

Resources

Next Steps

After successful auth, proceed to

webflow-hello-world
for your first API call.