React components in a Webflow CLI roundtrip

Export Webflow components to React, deploy an Astro app to Webflow Cloud, and import code components back, all with the Webflow CLI.

React components in a Webflow CLI roundtrip

Stefan Judis
Freelance Developer
View author profile
Stefan Judis
Freelance Developer
View author profile
Table of contents

Your app needs the site’s navigation and footer. You shouldn’t have to copy them into code and keep them in sync by hand.

Your Webflow components can move into your codebase as React components, and if you want to, Webflow can also host the custom apps you build with them. You can even send your own code components the other way onto your Webflow sites.

If that's news to you, this post walks through all three. We'll export the navigation and footer from a Webflow site into an Astro app and use them to build a small guestbook that stores entries in SQLite. Then we'll deploy the app to Webflow Cloud, so it lives on the original site under /guestbook. And finally, we'll send a React component the other way: a button that lets visitors sign the guestbook from any page.

Every step runs through the Webflow CLI: webflow devlink export, webflow apps deploy and webflow devlink import.

If you'd rather watch than read, here's this post in video format.

Where we start

This Webflow site is simple. It has a list of articles, a navigation and a footer. The navigation and the footer are set up as Webflow components, because DevLink only exports defined components. It can't export loose elements on a page.

The guestbook that should move into this Webflow site is a small Astro app. You type a name and a message, hit the button, and your entry shows up in the list below. It's server-rendered, there's no client-side JavaScript involved for the guestbook itself, and it's completely unstyled. Not pretty, but it works.

The guestbook entries go into a local SQLite database. Luckily, Webflow Cloud provides one, too. That's why the app declares it in its wrangler.json. There's nothing to set up by hand and Webflow Cloud creates the database automatically on the first deployment. If you want the details, the SQLite docs for Webflow Cloud cover the binding, local development and migrations.

So, right now we have a Webflow site without a guestbook and a guestbook without a Webflow site. Let's bring them together.

Setup

If you don't have the Webflow CLI yet, install it and authenticate.

npm install -g @webflow/webflow-cli
webflow auth login

The login opens a browser once. After that, you can manage your Webflow workspaces and sites from the command line, and getting components out of a site into your codebase is a nifty one-liner.

Export existing Webflow components

The devlink export command pulls the site's components and global styles into the app:

webflow devlink export

On the first run, the CLI asks which site to export from, where the components should live, and whether we want style isolation so the Webflow CSS doesn't clash with other styles on the page. The answers land in a new webflow.json, together with the site ID.

{
  "region": "us",
  "siteId": "<YOUR_SITE_ID>",
  "devlink-export": {
    "rootDir": "./webflow",
    "components": ".*",
    "componentGroups": ".*",
    "ts": true,
    "cssScopes": true,
    "relativeHrefRoot": "/"
  }
}

If you look at the new webflow/ directory, you discover exported React components like Navigation.tsx and the site's styles bundled in css/global.css, and a few more helper files.

Once you export your webflow components, there's one rule to follow. Don't edit the exported files; every following export will overwrite your changes. You should treat your Webflow site as a source of truth.

How to apply your existing Webflow styles

If you exported the components with style isolation turned on, you need to get your application ready to apply the Webflow styles. To avoid style clashes, the rules in the exported CSS files sit inside a @scope (.wf-devlink-<hash>) at-rule. @scope will enforce that your Webflow styles only apply inside an element carrying that class.

@scope (.wf-devlink-6810416396b7772dcea519aa818e38ce) {
  /* ... */
}

But where do you get this class from?

The DevLink export also ships a tiny devlinkScope.ts file that exports exactly this class as a string. Import the global CSS and the scope class into your application and put the class on <body>:

---
import "../../webflow/css/global.css";
import { DEVLINK_SCOPE_CLASS } from "../../webflow/devlinkScope";
---

<body class={DEVLINK_SCOPE_CLASS}>
  <slot />
</body>

That's pretty much it. Now the Webflow base styles and all existing classes are applied to the application. And if you put the DevLink scope class onto the body, the Webflow styles apply to the whole page.

If you now build out the HTML in your application, you can use the same classes as any component on Webflow to get the same look and feel.

<div class="container">
  <input class="w-input text-field" name="name" />
  <textarea class="w-input text-field" name="message"></textarea>
  <button class="w-button submit-button">Sign the guestbook</button>
</div>

In the guestbook case, w-input and w-button are Webflow's built-in classes. They're automatically applied on form inputs and buttons. text-field and submit-button are custom classes defined on the Webflow site. Combined, the plain HTML gets the site's look on top of Webflow's defaults, the same way it works on the canvas. There's no need for custom CSS.

Wrap the page in the Webflow site components

So at this stage, the Astro page that included the guestbook form is on brand, but the page is still floating in nothing. Astro renders React components, so the exported navigation and footer can go into the layout like any other component:

---
import "../../webflow/css/global.css";
import { DEVLINK_SCOPE_CLASS } from "../../webflow/devlinkScope";
import { Footer } from "../../webflow/Footer";
import { Navigation } from "../../webflow/Navigation";

interface Props {
  title: string;
}

const { title } = Astro.props;
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>{title}</title>
  </head>
  <body class={DEVLINK_SCOPE_CLASS}>
    <Navigation client:load />
    <slot />
    <Footer />
  </body>
</html>

The navigation gets client:load because its mobile menu toggles state in React. The footer has no interactive parts, so it renders as static HTML.

And there we have it. The site's navigation and footer wrap the guestbook, in the site's fonts and styles. When these components change in Webflow, rerunning the export pulls in the changes.

That's perfect, but how do we get this guestbook running on localhost into your Webflow site?

Deploy to Webflow Cloud

Webflow Cloud supports Astro, Next.js, Vite and static apps. Embed your project into your Webflow sites with a single command.

webflow apps deploy \
  --site-id <YOUR_SITE_ID> \
  --app-name guestbook \
  --mount /guestbook \
  --environment main

The webflow apps deploy command creates the app on Webflow, reads wrangler.json and creates the specified SQLite database. For the call above, the command defines a site id, the app name, the mount path inside the Webflow site and the environment. It's pretty straightforward.

When the deploy is done, the CLI writes the app ID into webflow.json, so the next deploy updates this app instead of creating a new one.

To access the configuration and settings of a site-attached app, go to your site settings under Webflow Cloud. There you can check deployments, and the environment's Storage tab shows entries in the database.

Following the mount path, the app lives under the site's URL at /guestbook, and because it pulls in existing Webflow components, it looks like any other page of the site.

It's fully functional, too. Created guestbook notes are now stored in the cloud database.

Once you mount an application into your Webflow site, you need to decide when and how often to pull in new components. If you adjust the navigation or any other shared component, the application needs to export the components to receive updates and be redeployed.
Whether you run that by hand or wire it into an automation is up to you.

Import custom code components into your Webflow site

So far, components went one direction, from Webflow into the app that lives under /guestbook. What if you want a component from your app on any page of your site?

For example, if you want a way to sign the guestbook from any other Webflow page, you can also import React components using the webflow devlink import command.

That's the other direction. devlink export brings components into your codebase. devlink import takes React components from your codebase and turns them into components you can use on the canvas.

For the guestbook, the component is GuestbookBubble. It's a button that opens a small form in a popover. The submitted form sends a POST request to /guestbook, which is the same route handler that takes submissions on the guestbook app page itself.

The React component accepts an action, a bubbleLabel and a heading, and it uses the exported Webflow classes to stay on brand.

// src/components/GuestbookBubble.tsx
import "../../webflow/css/global.css";
import { DEVLINK_SCOPE_CLASS } from "../../webflow/devlinkScope";

export default function GuestbookBubble({
  action = "/guestbook",
  bubbleLabel = "Leave a note",
  heading = "Sign the guestbook",
}: Props) {
  // …
}

To import this component into a Webflow site, you need to turn it into a code component. A code component is a React component paired with a .webflow.tsx definition file.

GuestbookBubble.webflow.tsx wraps the component exported from GuestbookBubble.tsx and tells Webflow which props show up in the Properties panel:

// src/components/GuestbookBubble.webflow.tsx
import { props } from "@webflow/data-types";
import { declareComponent } from "@webflow/react";
import GuestbookBubble from "./GuestbookBubble";

export default declareComponent(GuestbookBubble, {
  name: "Guestbook bubble",
  description: "A bubble that opens a form and posts the entry to the guestbook",
  group: "Guestbook",
  props: {
    bubbleLabel: props.Text({
      name: "Bubble label",
      defaultValue: "Leave a note",
    }),
    heading: props.Text({
      name: "Heading",
      defaultValue: "Sign the guestbook",
    }),
    action: props.Text({
      name: "Form action",
      defaultValue: "/guestbook",
      tooltip: "Where the form posts to.",
    }),
  },
});

Then the CLI does the rest:

webflow devlink import

The first devlink import run is interactive and asks for a library name, a description, and whether you trust this code. It also writes the library ID into webflow.json, which later runs as needed.

And just like that, the components defined in your application can become code components in a library in your Webflow workspace.

Once you drop the code component onto the page, the Properties panel shows the props you defined in code. Make adjustments and tweak whatever needs to be changed, and you're done!

As a final result, this small React component renders a button that opens the popover. People can now leave notes from anywhere. All the entries show up on /guestbook and are stored in the database of the deployed Cloud App.

Everything lives in your Webflow site. Pretty wild!

The bigger picture

And that's it! If you want to connect your Webflow site with a custom application or share components, the Webflow CLI has three commands for you in stock!

webflow devlink export brings components into your codebase, webflow apps deploy applications under your Webflow sites (standalone apps are possible, too), and webflow devlink import sends custom code components back into your Webflow site.

Go build something

Take an app you have lying around and give it a home on your Webflow site.

Share what you put in there, and now have fun!


Last Updated
October 30, 2026
Category

Related articles


verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Jetzt kostenlos loslegen

Try Webflow for as long as you like with our free Starter plan. Purchase a paid Site plan to publish, host, and unlock additional features.

Get started — it’s free
Get started — it’s free
Demo ansehen
Demo ansehen

Try Webflow for as long as you like with our free Starter plan. Purchase a paid Site plan to publish, host, and unlock additional features.