> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fastapps.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget Basics

> Learn the fundamentals of creating widgets with FastApps

## What is a Widget?

A widget is a React component that:

* Lives in `widgets/<widget-name>/index.jsx`
* Receives props from your MCP tool
* Renders in the ChatGPT interface
* Can be interactive and stateful

## Basic Widget Structure

```jsx theme={null}
import React from "react";
import { useWidgetProps } from "fastapps";

export default function MyWidget() {
  // 1. Get data from Python backend
  const props = useWidgetProps();

  // 2. Render UI based on props
  return (
    <div style={{ padding: "1rem" }}>
      <h2>{props.title}</h2>
      <p>{props.description}</p>
    </div>
  );
}
```

## Common Patterns

### Lists

```jsx theme={null}
export default function PizzaList() {
  const { pizzas } = useWidgetProps();

  return (
    <ul>
      {pizzas.map((pizza) => (
        <li key={pizza.name}>
          <strong>{pizza.name}</strong> — {pizza.style}
        </li>
      ))}
    </ul>
  );
}
```

### User Input with State

```jsx theme={null}
import { useWidgetState } from "fastapps";

export default function TodoWidget() {
  const [todos, setTodos] = useWidgetState("todos", []);
  const [text, setText] = useWidgetState("text", "");

  return (
    <div>
      <input
        value={text}
        onChange={(event) => setText(event.target.value)}
        placeholder="Add a task"
      />
      <button
        onClick={() => {
          setTodos([...todos, text]);
          setText("");
        }}
      >
        Add
      </button>
      <ul>
        {todos.map((todo) => (
          <li key={todo}>{todo}</li>
        ))}
      </ul>
    </div>
  );
}
```

### Conditional UI

```jsx theme={null}
export default function WeatherWidget() {
  const { loading, weather } = useWidgetProps();

  if (loading) {
    return <p>Loading...</p>;
  }

  if (!weather) {
    return <p>No forecast available.</p>;
  }

  return (
    <div>
      <h2>{weather.city}</h2>
      <p>{weather.summary}</p>
    </div>
  );
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="React Hooks" icon="code" href="/widgets/react-hooks/index">
    Learn about React Hooks
  </Card>

  <Card title="Advanced Patterns" icon="wand-magic-sparkles" href="/widgets/advanced-patterns/index">
    Explore Advanced Patterns
  </Card>
</CardGroup>
