> This page is for DevLink.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.webflow.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.webflow.com/_mcp/server.

# Props and slots

> How to create and expose custom properties in Webflow Designer for use in React.

DevLink converts Webflow's component properties into fully typed React props, giving you programmatic control over your components.

These props come with full TypeScript support and preserve all the defaults and rules set up in Webflow. You can use them to update content, handle user interactions, and control how your components behave in your React app.

## Basic props

Webflow's native component properties for content and visibility. The visual editor defines these properties, and DevLink automatically types them in React. DevLink Export supports the following properties:

A prop's **Type** setting determines the values it can accept and how it appears in the Designer.

* Text
* Video
* Link

- Rich text
- Number
- Visibility

#### Example: Notification button

This **Button** component has text and visibility props to show the number of new notifications for a user. The `text` prop sets the number of notifications, while the `showThis` visibility prop shows/hides the button based on the number of notifications.

**`Dashboard.tsx`**

```jsx title="Dashboard.tsx"
import { Button } from "webflow/Button";


export default function Dashboard({numNotifications}: {numNotifications: number}) {
  return (
    <div>
      <Button
        text={`${numNotifications} new notifications`}
        showIcon={numNotifications > 0}
      />
    </div>
  );
}
```

## Attributes

Attributes props let exported components forward arbitrary HTML attributes — `data-*`, `aria-*`, `id`, `role`, event handlers, refs — onto an element's underlying DOM node. DevLink emits the prop typed as `Record<string, unknown>` and spreads it on the bound element.

Use Attributes props to:

* Forward analytics or test-id attributes (`data-testid`, `data-analytics-id`)
* Inject ARIA attributes from React (`aria-label`, `aria-describedby`)
* Hook into element events (`onClick`, `onSubmit`)
* Apply inline styles or attach a React `ref`

#### Creating Attributes props in Webflow

You have two ways to expose Attributes on an element:

1. **From the Custom attributes panel.** Select the element in the Designer, open the Settings tab in the right panel, and find **Custom attributes**. Add attributes by Name and Value, then bind the entire list to a new prop. DevLink generates a prop named after your binding, typed `Record<string, unknown>`. Any static attributes you set become the prop's default value.
2. **From the Props management panel.** Open Props management, click **Add property**, choose **Attributes**, then bind it to an element via that element's Custom attributes section.

#### Example: Tagged button

This **Button** component has a `buttonAttributes` Attributes prop bound to the button element.

**`Dashboard.tsx`**

```tsx title="Dashboard.tsx"
import { Button } from "webflow/Button";

export default function Dashboard() {
  return (
    <Button
      text="Save"
      buttonAttributes={{
        "data-analytics-id": "save-button",
        "aria-describedby": "save-help",
        onClick: () => console.log("clicked"),
      }}
    />
  );
}
```

In the exported component, the prop type is `Record<string, unknown>`, and the static attributes you set in the Designer become the default value:

**`Button.tsx (generated)`**

```tsx title="Button.tsx (generated)"
export type ButtonProps = {
  buttonAttributes?: Record<string, unknown>;
  text?: React.ReactNode;
};

export function Button({
  buttonAttributes = { "data-default": "yes" },
  text = "Click me",
}: ButtonProps) {
  return <button {...buttonAttributes}>{text}</button>;
}
```

## Slots

Webflow's native **Slot** element lets a component accept other components as content, so you can nest components in instances of a parent component — from the Designer or from React.

To create a slot:

1. Open the parent component in the Designer.
2. Add a **Slot** element where the nested content should appear.
3. In instances of the component, drop other components into the slot — or in your React code, pass them via the matching prop.

#### Example: Card component with a slot

For example, this `Card` component has a `cardContent` slot that accepts a React component as its value:

**`Card.tsx`**

```jsx title="Card.tsx"
/**
 * @generated
 * @file Card (generated by DevLink)
 *
 * This file is generated by DevLink from a Webflow component. Manual edits are discouraged.
 *
 * @see {@link https://my-example-site.design.webflow.com | Source site in Webflow}
 */
"use client";

import { DEVLINK_SCOPE_CLASS } from "./devlinkScope";
import Block from "./webflow_modules/Basic/components/Block";
import Heading from "./webflow_modules/Basic/components/Heading";
import InlineCode from "./webflow_modules/Basic/components/InlineCode";
import Section from "./webflow_modules/Basic/components/Section";

/**
 * Props for {@link Card}
 */
export type CardProps = {
  cardContent?: React.ReactNode;
  text?: React.ReactNode;
};

/**
 * Card
 *
 * @see {@link https://my-example-site.design.webflow.com | Source site in Webflow}
 */
export function Card({
  cardContent,
  text = "Hello.",
}: CardProps) {
  return (
    <div
      className={DEVLINK_SCOPE_CLASS}
      style={{
        display: "contents",
      }}
    >
      <Section
        grid={{
          type: "section",
        }}
        tag="section"
      >
        <Heading tag="h1">
          <InlineCode>{"My component"}</InlineCode>
        </Heading>
        <Block tag="div">{text}</Block>
        {cardContent}
      </Section>
    </div>
  );
}
```

You can put other React components in the slot by passing them as the prop value, as in this example:

**`UserProfileCard.tsx`**

```jsx title="UserProfileCard.tsx"
import { Card } from "webflow/Card";
import { UserProfile } from "../../../../../components/UserProfile";

export function UserProfileCard() {
  return (
    <Card
      cardContent={
        <UserProfile id="42" />
      }
    />
  );
}
```

**When to use slots**

* Embed custom React components (e.g., charts, modals, media players).
* Integrate third-party libraries inside a Webflow-made layout.
* Pass dynamic content into a reusable Webflow component without hard-coding it in the Designer.

For more information about using slots, see [Slots](https://help.webflow.com/hc/en-us/articles/33961195339923-Slots).