For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Resources
Get started
GuidesExamples
GuidesExamples
  • Webflow Apps
    • Register an App
    • FAQs and Troubleshooting
  • Data Clients
    • Build a Data Client
    • Data API reference
    • Data API guides
  • Designer Extensions
    • Build a Designer Extension
    • Upload your extension
    • App Configuration
    • Webflow CLI Reference
    • Design Guidelines
    • Designer API reference
    • Designer API guides
  • Hybrid Apps
    • Authenticate users from the Designer
    • Deep links to the Designer
  • Marketplace
    • Overview
    • Marketplace Guidelines
    • Submitting your App
    • Marketing your App
    • App Metrics
  • Resources
    • Examples
    • Webflow SDK
    • Developer Workspace
    • MCP server and AI tools
  • Company
    • Developer Terms of Service
    • Webflow Terms of Service
LogoLogo
Resources
Get started
On this page
  • Before you start
  • Quick Start (5 minutes)
  • Understanding the example
  • Start the OAuth 2.0 authorization flow
  • Request an access token
  • Next Steps
  • FAQs
Data Clients

Getting Started

Was this page helpful?
Previous

Designer API & Extensions

Next
Built with

In this guide, you’ll create your first Data Client app to authorize with Webflow and make your first request to the Webflow REST API.

Before you start

To successfully follow along with this guide, make sure you have the following:

  • A Webflow site for development and testing
  • A registered app on your Workspace with the sites:read scope enabled
  • An IDE of your choice
  • Node.js installed on your machine.

Quick Start (5 minutes)

This quick start will get you up and running with a data client app

1

Clone the starter app

$git clone https://github.com/Webflow-Examples/webflow-app-starter-v2
$cd webflow-app-starter-v2
$npm install
2

Add your credentials to .env

Navigate to your Workspace settings in the Webflow dashboard and find your Client ID and Secret in the Apps & Integrations -> App Development section. Replace the placeholder values in the .env.example file with your own Client ID and Secret. Then save the file as .env.

1WEBFLOW_CLIENT_ID=your_client_id
2WEBFLOW_SECRET=your_client_secret
3

Start the server

$npm run dev
4

Update your redirect URI

In your workspace settings, navigate to the app development section and your app’s details, update the redirect URI to http://localhost:3000/auth

Redirect URI
5

Visit your app

Visit http://localhost:3000 (or the port of your choice)and click “Connect with Webflow” to see your Webflow sites!

Webflow App Example

Understanding the example

This example is a simple Node.js app that handles authorization and makes a single request to the Webflow REST API.

Review the code in server.jsto understand how the App works.

Installation and configuration

The app uses Fastify to create a lightweight server, Level as a database, and the Webflow JavaScript SDK to make authenticated requests to the Webflow REST API. To keep things simple, the frontend of the app is built with vanilla JavaScript and CSS, with a simple HTML file served from the public directory.

In the beginning of server.js, imports the necessary dependencies, loads environment variables, and initializes the Fastify server. Here, security headers are added to the server to protect against common web vulnerabilities. Also, it initializes the database for storing access tokens.

server.js
1import { WebflowClient } from "webflow-api";
2import Fastify from "fastify";
3import fastifyStatic from "@fastify/static";
4import path from "path";
5import url from "url";
6import { Level } from "level";
7import fs from "fs/promises";
8
9// Load environment variables from .env file
10const {
11WEBFLOW_CLIENT_ID,
12WEBFLOW_SECRET,
13PORT
14NODE_ENV = "development",
15} = process.env;
16
17// Validate required environment variables
18if (!WEBFLOW_CLIENT_ID || !WEBFLOW_SECRET) {
19console.error(
20 "Missing required environment variables. Please check your .env file:"
21);
22console.error("WEBFLOW_CLIENT_ID and WEBFLOW_SECRET are required");
23process.exit(1);
24}
25
26// Initialize our server with basic security headers
27const server = Fastify({
28logger: true,
29trustProxy: true, // Required for secure cookies behind a proxy
30});
31
32// Add security headers
33server.addHook("onSend", async (request, reply) => {
34reply.headers({
35 "X-Content-Type-Options": "nosniff", // Prevent MIME type sniffing
36 "X-Frame-Options": "DENY", // Prevent clickjacking
37 "Strict-Transport-Security": "max-age=31536000; includeSubDomains", // Enforce HTTPS
38});
39});
40
41// Initialize the database (Note: Use a proper database in production)
42const db = new Level("data", { valueEncoding: "json" });
43await db.open();
OAuth Authentication

The App implements OAuth 2.0 authentication through a dedicated /auth route that handles both initiating the authorization flow and processing Webflow’s callback response. When a user clicks “Connect with Webflow”, this route first redirects them to Webflow’s authorization page. After the user grants permission, Webflow redirects back to this route with an authorization code that the App exchanges for an access token.

For a comprehensive walkthrough of implementing OAuth 2.0 authentication in your App, refer to the detailed OAuth 2.0 guide.

Start the OAuth 2.0 authorization flow

This route will check for a code query parameter. If the code isn’t present, Webflow will redirect the user to the Webflow OAuth 2.0 authorization page using the authorizeURL method of the Webflow JavaScript SDK.

server.js
1// OAuth 2.0 authentication endpoint
2server.get("/auth", async (req, reply) => {
3 const { code, error, error_description } = req.query;
4
5 // If no code is provided, redirect to the authorization URL
6 if (!code) {
7 const installUrl = WebflowClient.authorizeURL({
8 scope: scopes,
9 clientId: WEBFLOW_CLIENT_ID,
10 // Optional: Add state parameter for CSRF protection
11 state: Math.random().toString(36).substring(7),
12 });
13 return reply.redirect(installUrl);
14 }
15});

Request an access token

If the code query parameter is present, we’ll use it to request an access token from Webflow using the getAccessToken method of the Webflow JavaScript SDK. We’ll also store the access token in the database and redirect the user to the root URL of the App.

server.js
1// OAuth 2.0 authentication endpoint
2server.get("/auth", async (req, reply) => {
3
4// Previous Code //
5
6 try {
7 // Exchange the code for an access token
8 const token = await WebflowClient.getAccessToken({
9 clientId: WEBFLOW_CLIENT_ID,
10 clientSecret: WEBFLOW_SECRET,
11 code: code,
12 });
13
14 // Store the token in the database
15 await db.put("token", token);
16
17 if (NODE_ENV === "development") {
18 console.log("\nAccess Token Received:", token, "\n");
19 }
20
21 return reply.redirect("/?authorized=true");
22 } catch (error) {
23 console.error("Auth Error:", error);
24 return reply.code(500).send({
25 error: "Authentication failed",
26 message: error.message,
27 });
28 }
29});

The example App stores and retrieves a single access token directly in the Level database. In a production app, you’ll want to implement proper user management and token storage, including:

  • Storing tokens securely per user/workspace
  • Encrypting sensitive data
  • Using secure session management

Consider using dedicated auth services or implementing these security measures using libraries like Passport.js, JWT tokens, and proper database encryption.

Making requests to the REST API

After the user has authorized the App, it can make requests to the REST API using the WebflowClient object. Here, the /sites route makes a request to the “List Sites” endpoint.

Before calling the API, the App retrieves the access token from the database and creates a new, authenticated WebflowClient object.

server.js
1// Example API endpoint
2server.get("/sites", async (req, reply) => {
3 try {
4 const accessToken = await db.get("token");
5
6 const webflow = new WebflowClient({ accessToken });
7
8 const sites = await webflow.sites.list();
9 return sites;
10
11 } catch (error) {
12 console.error("API Error:", error);
13
14 // Handle different types of errors
15 if (error.response?.status === 401) {
16 return reply.code(401).send({
17 error: "Invalid token",
18 message: "Please authenticate again",
19 });
20 }
21
22 return reply.code(500).send({
23 error: "Server error",
24 message: "Failed to fetch sites",
25 });
26 }
27});

Next Steps

Now that you have a working app, you can:

  1. Add more API endpoints: Explore the API Reference and the Data Client Guides to add functionality
  2. Add Designer Extension capabilities: Learn how to add Designer Extension capabilities to your App.
  3. Authenticate a Hybrid App: Learn how to implement authentication for Apps using Data Client and Designer Extension capabilities.
  4. Prepare your Marketplace app: Learn how to prepare your App for submission to the Webflow Marketplace

FAQs

Why can't other users install my app on their sites?

Only apps published to the Webflow Marketplace, either publicly or privately, can be installed by other users. Submit your app for review to make it available for installation.

Want to test with a few users before publishing? Email developers@webflow.com with up to 5 Webflow user emails. Our team can add them to a test group so they can install and use your app with the install URL.