> For the complete documentation index, see [llms.txt](https://developers.felt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.felt.com/js-sdk/integrating-with-react.md).

# Integrating with React

To work with Felt embeds in React, we have a starter template that you can use as a starting point.

This is available on GitHub in the [felt/js-sdk-starter-react](https://github.com/felt/js-sdk-starter-react) repository.

In that repo, you will find a `feltUtils.ts` file that demonstrates some ways to make using the Felt SDK in React easier. The SDK itself is framework-agnostic and ships no React bindings — the hooks below are small wrappers you copy into your own project.

### Embedding with `useFeltEmbed`

```tsx
function MyComponent() {
  // get the felt controller (or null if it's not loaded yet) and a ref to the map container
  // into which we can embed the map
  const { felt, mapRef } = useFeltEmbed("FELT_MAP_ID", {
    uiControls: {
      cooperativeGestures: false,
      fullScreenButton: false,
      showLegend: false,
    },
  });

  return (
    <div>
      {/* the map container — remember to give it a height in your CSS */}
      <div ref={mapRef} />

      {/* a component that uses the Felt controller */}
      <MyFeltApp felt={felt} />
    </div>
  );
}
```

<details>

<summary>useFeltEmbed implementation</summary>

```typescript
import {
  Felt,
  FeltController,
  FeltEmbedOptions,
  Layer,
} from "@feltmaps/js-sdk";
import React from "react";

export function useFeltEmbed(mapId: string, embedOptions: FeltEmbedOptions) {
  const [felt, setFelt] = React.useState<FeltController | null>(null);
  const hasLoadedRef = React.useRef(false);
  const mapRef = React.useRef<HTMLDivElement>(null);

  React.useEffect(() => {
    async function loadFelt() {
      if (hasLoadedRef.current) return;
      if (!mapRef.current) return;

      hasLoadedRef.current = true;
      const felt = await Felt.embed(mapRef.current, mapId, embedOptions);
      setFelt(felt);
    }

    loadFelt();
  }, []);

  return {
    felt,
    mapRef,
  };
}
```

A few things worth knowing about this hook:

* The `hasLoadedRef` guard exists because React's Strict Mode runs effects twice in development — without it you would embed two iframes.
* The hook embeds once for the component's lifetime: changing `mapId` after mount won't re-embed. If you need to switch maps, remount the component (for example with a `key={mapId}` prop).

</details>

### Getting live data

A common use case for building apps on Felt is to be notified when entities are updated. The main example of this is when you want to change the visibility of say a layer, and have your own UI reflect that change.

Rather than keeping track of the visibility of entities yourself, you can use the Felt SDK to listen for changes to the visibility of entities.

Here is an example of how you might do this for layers assuming you already have a reference to a `Layer` object, e.g. from calling `felt.getLayers()`:

```typescript
export function useLiveLayer(felt: FeltController, initialLayer: Layer) {
  // start with the layer we were given
  const [currentLayer, setLayer] = React.useState<Layer | null>(initialLayer);

  // listen for changes to the layer and update our state accordingly
  // (onLayerChange returns its unsubscribe function, so returning it
  // from the effect cleans up the listener on unmount)
  React.useEffect(() => {
    return felt.onLayerChange({
      options: { id: initialLayer.id },
      handler: ({ layer }) => setLayer(layer),
    });
  }, [felt, initialLayer.id]);

  // return the live layer
  return currentLayer;
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.felt.com/js-sdk/integrating-with-react.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
