Publishing Apps and the Marketplace

This content was generated with the assistance of AI and should be verified against the official Webflow documentation before being relied on in production.

This sub-section’s Webflow bibliography lists the reference material consulted while preparing these pages.

This page describes how apps are published on Webflow as it was on 2026-10-28, the date on which its facts were checked against the official developer documentation. The tools are pinned to the versions current on that date: the Webflow CLI @webflow/webflow-cli 2.15.0 (Node 22.13 or later), @webflow/designer-extension-typings 2.2.2 and the JavaScript SDK webflow-api 3.3.4. Registering an app is a Workspace feature, and uploading a bundle needs a workspace administrator with two-factor authentication. Plans are named by tier only, and every example runs in a free Developer workspace.

The running example is Fernbrook Gardens, the fictitious botanical garden of the whole sub-section. Its agency builds the Plant Label Kit, a Designer Extension (with a small backend) that fills in the alt text of plant photos, builds printable plant labels from the CMS and handles the garden’s two extra locales, Spanish and German. This page follows that app from a local build to a Marketplace listing. How apps are built is covered in Apps Overview and OAuth and Designer Extensions and the Designer API; the credentials of a Data Client are in Data API: Authentication and Scopes.

Three ways an app reaches users

An app that works on the developer’s machine is visible only to users of the workspace that registered it. The official documentation states that sharing outside the workspace requires Marketplace submission. Three situations follow from that.

Situation What happens Typical use

Development in the registered workspace

Only members of the workspace see the app. The Launch development app button loads the local development URL

Building and debugging

Private app

A Marketplace submission with visibility set to private. After approval the developer receives an install URL, and only the people who hold it can install the app

An internal tool for one organization or one client

Public app

A Marketplace submission, listed or unlisted, reviewed and published

Software for any Webflow workspace

Testing with a few external users before launch is a separate process, the user testing process of the Apps documentation. A private app is not a substitute for it, nor for public distribution.

The capability of the app decides what has to be shipped:

  • A Designer Extension ships a front-end bundle, bundle.zip, that Webflow hosts. This is the part with the size limit and the version history.

  • A Data Client ships no bundle. It runs on the developer’s own server and needs an install URL that starts the OAuth flow.

  • A hybrid app has both, and follows both sets of rules. See Hybrid Apps.

The bundle

A Designer Extension is a web application that Webflow serves inside an iframe in the Designer. The bundle is the production build of that application, zipped by the CLI.

Prerequisites

  • A complete, tested extension.

  • The Webflow CLI installed.

  • Admin access to the workspace where the app is registered.

  • Two-factor authentication enabled on the account.

Building the bundle

The sequence is a production build followed by webflow extension bundle. The build writes the application to a build or dist folder, and the folder can be set in webflow.json; the bundle command run from the project root creates bundle.zip. For frameworks such as Next.js or Astro the framework’s own production build runs first and its output directory is bundled; both steps can be combined in a package.json script.

The package.json of the Plant Label Kit, with the pinned versions:

{
  "name": "plant-label-kit",
  "private": true,
  "type": "module",
  "engines": { "node": ">=22.13" },
  "scripts": {
    "build": "vite build",
    "bundle": "npm run build && webflow extension bundle"
  },
  "dependencies": {
    "react": "18.3.1",
    "react-dom": "18.3.1"
  },
  "devDependencies": {
    "@webflow/webflow-cli": "2.15.0",
    "@webflow/designer-extension-typings": "2.2.2",
    "vite": "5.4.11",
    "typescript": "7.0.2"
  }
}

The CLI itself is described in Webflow CLI.

The 5 MB limit

The documentation is explicit: the bundle must not exceed 5 MB. Webflow compiles the bundle and serves it from a unique URL, found under Edit App > Building Blocks > Designer Extension in the app’s settings. Every customer site that opens the app downloads it, which is why the limit exists and why a small bundle is also a faster app. The usual ways to stay under it:

  • Ship only what the panel needs. A label designer does not need a full charting library.

  • Import individual functions rather than whole utility libraries.

  • Keep images, fonts and sample data out of the bundle. Fetch them from the app’s backend, which is reachable over HTTPS.

  • Compare the size after every dependency upgrade. The check is cheap to automate, as shown below.

Source maps stay out of the production bundle

Source maps are useful for debugging, but the documentation says to keep them, and other review files, out of the bundle: bundles that ship source maps are not accepted. The maps still matter, because reviewers need them (see the review ZIP below). The build therefore produces them, a separate archive keeps them, and they are removed before the bundle is made.

Uploading a version

Uploading is done by hand in the Webflow dashboard, by a workspace administrator.

  1. In Workspace settings, open the Apps & Integrations tab.

  2. Under Develop, find the app and select Publish extension version.

  3. Choose bundle.zip and write notes that describe the change.

  4. A confirmation message appears and the version shows up in the version history.

The Publish extension version button is disabled for anybody who is not a workspace admin or who has not enabled two-factor authentication. A developer who cannot see an enabled button should check those two conditions first. This is also why the upload cannot be part of an unattended pipeline: the account that uploads is an administrator with 2FA, so the pipeline builds and verifies the artifact, and a person with the right role performs the upload.

Testing the uploaded version

The button names matter here. Open any Webflow site in the workspace, open the app and select Launch App. Do not select Launch development app: that one loads the local development URL and not the uploaded version, so a test through it proves nothing about the bundle that was uploaded.

Version history and the absence of rollback

Each upload creates a new versioned instance. The history is available from the …​ button in the app’s settings, then Version History. There is no one-click rollback. To revert, check out an earlier commit in version control, generate a new bundle from it and upload that as a new version.

Three practical consequences for the Fernbrook agency:

  • Tag every upload. The version notes carry the Git tag, for example plant-label-kit-1.4.0, so that the version in the dashboard maps to a commit.

  • Keep the lockfile committed. A rebuild from an old tag must reproduce the old bundle, which needs the old dependency versions.

  • Rehearse the revert. The procedure below is the whole rollback, and it takes as long as a build plus a manual upload.

git fetch --tags
git checkout plant-label-kit-1.3.2
npm ci
npm run bundle
# Then, in Workspace settings > Apps & Integrations > Develop:
# Publish extension version, choose bundle.zip, note "Revert to 1.3.2".

Updating an app

An update is a new bundle.zip uploaded the same way. The notes should mention any new required scope, because changing the required scopes makes users authenticate again. For a published app the Marketplace has its own update path, covered later: for Designer Extension changes the new version is published from the workspace as well.

A build and packaging pipeline

The pipeline below builds the extension, archives its source maps into the review ZIP, removes the maps, creates the bundle and fails if the bundle contains a source map or is too large. It does not upload anything: the upload remains the administrator’s step. The size check uses 5,000,000 bytes, the stricter reading of 5 MB, so a bundle that passes is under the limit under either reading.

#!/usr/bin/env bash
# scripts/package.sh: build, archive source maps, create bundle.zip
set -euo pipefail

rm -rf dist bundle.zip review.zip
npm ci
npm run build

# The review ZIP: maps of this exact build, the manifest and the lockfile.
(cd dist && zip -q -r ../review.zip . -i '*.map')
zip -q review.zip package.json package-lock.json

# The bundle itself must not carry source maps.
find dist -name '*.map' -delete
npx webflow extension bundle

if unzip -l bundle.zip | grep -E '\.map$'; then
  echo "bundle.zip contains source maps" >&2
  exit 1
fi

size=$(wc -c < bundle.zip)
limit=5000000
echo "bundle.zip: ${size} bytes (limit ${limit})"
if [ "${size}" -gt "${limit}" ]; then
  echo "bundle.zip is over the size limit" >&2
  exit 1
fi

The same script runs in CI, and the two archives are stored as workflow artifacts so that whoever uploads can download exactly what was built from the tagged commit:

name: package-plant-label-kit
on:
  push:
    tags: ["plant-label-kit-*"]

permissions:
  contents: read

jobs:
  package:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: bash scripts/package.sh
      - uses: actions/upload-artifact@v4
        with:
          name: plant-label-kit-${{ github.ref_name }}
          path: |
            bundle.zip
            review.zip
          retention-days: 90

The workflow holds no Webflow secret, because nothing in it talks to Webflow. The CI side of the sub-section is in Testing, CI and DevOps.

Private apps

A private app is a custom app for one workspace or one specific implementation. It has the full API capability but is not meant for broad distribution. It is created through the same submission form as a public app: in the Marketplace Visibility section the developer selects Private, completes the app information and submits it. Private apps go through the same review as public apps.

After approval the developer receives a unique install URL. Only people with that URL can install the app, so the URL is shared directly with the intended users and the developer keeps track of who has it. A private app has no Marketplace listing page and is not visible on the public Marketplace, and it is not suited to multi-workspace distribution. Private apps can still be monetized under the standard Marketplace terms.

For Fernbrook Gardens this is the right choice if the Plant Label Kit stays an internal tool: the agency installs it on the garden’s workspace and on nobody else’s. It becomes a public app only if the agency decides to offer it to other gardens.

Submitting to the Marketplace

The steps are: prepare the technical requirements and assets, submit through the Webflow App submission form, respond to review feedback, and promote the app after publication.

Technical requirements

  • Two-factor authentication is enabled for an admin account of the workspace.

  • The app is fully tested and functional, not a beta or pre-release.

  • The app has clear documentation and error handling.

  • The app meets the security, authentication, OAuth, scope and data-handling rules of the Marketplace Guidelines.

What the submission contains

Item Content

Install URL

For Data Client and hybrid apps. The client_id must match the app, the scope must include only scopes selected in the form, and the URL must start a valid install. A Designer Extension needs no install URL, because Webflow handles its installation

Production bundle

Uploaded in the app settings, without source maps

Review ZIP

Required for new Designer Extension and hybrid apps and for updates that change the Designer Extension bundle. A Data Client-only app does not need it

Published testing site

A .webflow.io URL, using https://, with the app installed and every feature available

Review access

Full access for reviewers: a demo account, gated features, test credentials and sample data, none of which may expire

Backend

Every backend service and third-party integration kept running throughout the review

Demo video

A walkthrough of 2 to 5 minutes from installation to use, in English or with English subtitles, on Loom, YouTube (unlisted or private) or Google Drive. A Data Client must also show OAuth approval and denial

App Review Preflight receipt

A code that starts with wfpre_ followed by 32 hexadecimal characters, produced by running Preflight in the Designer on the bundle and the review ZIP

Listing

Name, descriptions, features, logo, screenshots, links, support email and policies

The submission form checks required fields and formats, listing rules (English copy, no Webflow name in the app name or domains, disclosed pricing, explained custom-code and workspace scopes), that links resolve and point to their own content, and that videos are hosted where the form allows. Complex features and pricing are documented in the review notes and the video.

The review ZIP with source maps

Webflow has to be able to review a Designer Extension from source, and a minified bundle is not reviewable. The review ZIP is the solution, and it is uploaded to the Source map artifact field of the form as a single ZIP:

  • The Source Map v3 files (.map), the package.json and the lockfile, all from the exact build that produced the bundle.

  • Alternatively, when the source ships unchanged, the source files plus a short README that explains how the bundle is packaged, and the package.json and lockfile if they are used.

  • The ZIP is uploaded directly; a link does not replace it.

The maps stay private to the review team and are never published. The pipeline above produces the first variant automatically, which is why it archives the maps of the same build before it deletes them from the bundle.

Preflight

The Preflight receipt is required for new apps and for updates that change code or scopes; a Data Client without the custom code scope does not need one. Every Blocker and Required update reported by Preflight has to be fixed first, and the resulting receipt is pasted into the form. The result is one of three values:

Result Effect

ready

Accepted

needs_review

Accepted, and a reviewer checks the flagged items

changes_required

Blocks the submission, as does a receipt the form does not recognize

Install URL for a Data Client

The Plant Label Kit has a backend that edits CMS items, so it is a hybrid app and needs an install URL. The recommended route sends the user straight to Webflow OAuth. A URL that requests scopes beyond those configured makes the installation fail, while one that requests too few installs successfully and then fails on API calls, so the URL carries every scope the app uses. With placeholders:

https://webflow.com/oauth/authorize
  ?client_id=REPLACE_WITH_CLIENT_ID
  &response_type=code
  &scope=authorized_user%3Aread%20cms%3Aread%20cms%3Awrite%20assets%3Aread

The authorization-code flow, state handling and token exchange are in Data API: Authentication and Scopes.

Listing requirements

The listing is a separate piece of work that the review checks against the guidelines.

Field Rule

App name

At most 30 characters

Short description

At most 100 characters

Long description

At most 10,000 characters; Markdown is supported but links are not

Feature list

At most 5 features

App logo

900x900 px, 1:1, PNG, at most 50 KB; a logomark, not a text logotype

Screenshots

3 to 5 images, 1280x846 px, PNG or JPG, at most 2 MB each

Categories

Up to 5, chosen from the list the form offers

Support and policies

A support email, a privacy policy URL and a terms of service URL

Language

English. If the app’s own interface is in another language, the long description says which

The English rule applies to the listing and not to the app. The Plant Label Kit interface can offer Spanish and German labels, and the long description states that the app operates in English, Spanish and German.

The Marketplace Guidelines

Review covers the Designer code, the calls to the Webflow API, OAuth and authorization, changes to Webflow data, handling of credentials and user data, and the connect, disconnect and uninstall behavior. It is not a security audit and not a complete list of defects: approval covers only the version, configuration, permissions and behavior that were reviewed, and material changes can require a new review.

Scopes and OAuth

  • OAuth 2.0 is required. An app must not collect Webflow credentials by hand or bypass the flow.

  • Every requested scope must be needed for the advertised functionality and tied to a documented endpoint that the app calls. Read-only apps request :read scopes, write-only apps :write, and both only when both are used.

  • Site-level scopes are preferred over workspace-level ones. For identity alone, use authorized_user:read, not sites:read or workspace:read.

  • custom_code:read and custom_code:write are elevated-risk scopes, requested only for a disclosed custom code feature.

  • A unique state is sent with every authorization request and verified before the code is exchanged. The redirect URI matches the registered one exactly, and the code (single use, valid 15 minutes) is never retried, persisted or logged.

  • The OAuth flow runs once, at install or on explicit re-authorization; signing out of the app does not revoke the Webflow authorization unless the user intends it.

Tokens and secrets

  • Tokens are stored server side in encrypted storage or a secret manager: never in browser storage, plaintext, client code, logs or responses.

  • The client_secret stays out of client code, public repositories, build artifacts, image layers and pipeline logs.

  • When a user revokes access, the app stops using the token and deletes it.

  • Credential headers are never sent to non-Webflow domains, and secrets are never hardcoded as string literals.

  • A Data Client gives three written attestations: the OAuth token is encrypted at rest, stored server side only and deleted on uninstall or revocation.

Injected scripts and custom code

Code that an app places on a customer’s site goes through the Custom Code API, so that the site owner can see, manage and remove it. The listing states what code is applied, what it does, where it runs and why, and remotely loaded resources are disclosed at submission. On uninstall the app removes the custom code it registered at site and page level, keeps the customer’s unrelated scripts and deletes the Webflow-side data it added. The guidelines recommend immutable, versioned HTTPS URLs with integrity and the crossorigin attribute set to anonymous, scoping the injection to the pages that need it, and never asking users to paste scripts manually.

The Plant Label Kit does not inject scripts; if it later adds a visitor-facing widget, the widget is delivered this way. The API side is in Data API: Assets, Forms and Custom Code.

Designer Extension technical rules

  • No eval(), new Function() or string arguments to timers, and no untrusted data inserted as raw HTML.

  • Read or change the site only through the official Designer APIs, never by manipulating the Designer interface.

  • Stay compatible with the Webflow Content Security Policy: inline event handlers and javascript: URIs fail review.

  • Minification is fine, obfuscation is not (encoded string arrays, runtime atob() decoding, scrambled self-invoking functions).

  • No keyboard shortcuts that invoke the app or its features.

  • An external iframe may be used for authentication, not as the primary interface when its content can change without review.

Network and data handling

Every endpoint uses HTTPS and points to production: staging, localhost and private-network references are removed before submission. A Data Client’s redirect URI is a single fully qualified HTTPS URL on a production domain, with no wildcard, IP address, tunnel service or port other than 443. CORS allows only origins the developer controls, never a wildcard. Backend endpoints verify identity with a session or signed token and never trust a client-supplied siteId. Data is read and written only through the official APIs, rate limits are respected with exponential backoff, and Webflow remains the source of truth: the app shows when data was fetched and never silently overwrites it.

Performance

The app uses resources efficiently, avoids long-running background tasks that affect performance, and monitors and fixes performance problems; persistent problems can lead to removal. The 5 MB bundle limit is the hard edge of this guideline, and a bundle far below it is the practical target.

Accessibility

The app is designed for users with different abilities and follows WCAG practices, including alt text for images, keyboard navigation and sufficient color contrast. For an app whose purpose is to fix alt text this is also a matter of credibility. The wider topic is in Accessibility.

Localization

An app that writes to a locale-aware endpoint must handle localeId and cmsLocaleId correctly: it specifies the localeId on every write and never overwrites localized content with primary-locale values without the user’s awareness. It also preserves data-w-id and other Webflow identifiers when updating HTML. For Fernbrook Gardens, a bulk alt-text fix that wrote the English text into the Spanish and German variants would break this rule. The model of locales and the API are in Localization and Data API: E-commerce and Localization.

Business, support and audit

Fees and in-app purchases are disclosed and ads are not displayed. Trademarks are used only with authorization, support contact information is accurate, and a developer may keep only one account for active Marketplace listings. Webflow may audit app access and activity, and the developer cooperates by providing the records requested.

The review

After submission Webflow emails confirmation of receipt, usually to the account address, and aims to decide within 10 business days. The documentation for the publishing step describes the review as taking a few days and says that an email arrives on approval; the submission page gives the longer 10-business-day target, which is the figure to plan with. The outcome is approval, a request for changes or rejection.

  • When changes are requested, fix every listed item, retest the whole app end to end and resubmit. The feedback is not exhaustive.

  • Repeated submissions that ignore earlier feedback can pause new submissions for the app, with longer pauses, and may end in rejection. A rejected app can be submitted again when it is ready.

  • Hiding functionality, showing reviewers a different experience or submitting misleading information leads to removal and a ban from future publishing.

  • A blocking problem, such as a failed installation or OAuth, stops the review.

Updating a published app

After approval, material changes need a new review: changes to functionality, user-facing behavior, permissions, bundles, integrations and scripts delivered through the Custom Code API. The update goes through the same form with the submission type App Update.

  • Required fields are the app name and client ID, plus the published testing site.

  • When the Designer Extension bundle changed, the review ZIP is uploaded and the question about a new or changed bundle is answered Yes.

  • A Preflight receipt is needed when the update changes code or scopes. A listing-only update skips the artifacts.

  • An email arrives when the approved update is published, and for Designer Extension changes a new version is also published from the workspace.

  • Scopes are locked after publication. Adding one is an app update, and the scope of the install URL changes only after the update is approved; existing installs do not gain it and have to be asked to re-authorize.

A release checklist for the Plant Label Kit

  1. Tag the commit and let the pipeline build bundle.zip and review.zip.

  2. Check that the bundle is under the limit and holds no source map.

  3. Upload the bundle as a new extension version, with notes that name the tag and any new scope, and test with Launch App.

  4. Run Preflight on the bundle and the review ZIP and fix every Blocker and Required update.

  5. Prepare the testing site on .webflow.io, the demo account that does not expire and the 2 to 5 minute video.

  6. Check the Spanish and German behavior, keyboard use and contrast.

  7. Confirm that disconnecting and uninstalling remove what the app added.

  8. Submit as a private or public app, and wait for the answer.

  9. After approval, keep the tag. It is the only rollback there is.

Pitfalls checklist

  • Looking for a rollback button. There is none: rebuild from an earlier commit and upload it as a new version.

  • Testing the uploaded version with Launch development app and validating the local build instead.

  • Shipping source maps in bundle.zip, or forgetting the review ZIP for a changed bundle.

  • Building the maps and the bundle in two different builds, so that the review ZIP does not match.

  • A disabled Publish extension version button because the user is not an admin or has no 2FA.

  • Adding a scope in code or in the install URL before the app update is approved.

  • An install URL with fewer scopes than the code needs: installation works and the calls fail.

  • Writing to locale-aware endpoints without localeId, overwriting Spanish and German content.

  • Leaving staging or localhost URLs, or an expiring review account, in the submission.

  • Listing copy that is not in English, or that does not say which other language the app speaks.

Summary

  • A Designer Extension ships as bundle.zip, created with webflow extension bundle after a production build. The bundle must not exceed 5 MB and must not contain source maps.

  • Only a workspace admin with two-factor authentication can use Publish extension version. Every upload is a new version; there is no rollback, and a revert is a rebuild of an earlier commit.

  • Test the upload with Launch App, never with Launch development app.

  • A private app uses the same submission and review with visibility set to private and is installed through a unique URL.

  • A Marketplace submission needs a testing site, review access, a demo video, a Preflight receipt and, for new or changed Designer Extensions, a review ZIP with the source maps of the exact build.

  • The guidelines cover least-privilege scopes, server-side tokens, disclosed and removable injected scripts, performance, accessibility and correct locale handling. Webflow aims to decide within 10 business days, and material changes go through an App Update.