# React Router 7 with Vite

[React Router](https://reactrouter.com/) is a standard library for routing in React applications that enables dynamic, client-side routing. This document explains how to integrate [Flagship](https://www.flagship.io/) feature flag management with React Router 7 in a Vite-powered React application.

### Project Overview

This project demonstrates how to integrate Flagship feature flagging system with a React Router 7 application. The integration allows you to:

* Toggle features based on Flagship flags
* Send analytics hits to track user behavior
* Display different UI components based on feature flags
* Route between different pages with flag-controlled behavior

### Setup and Configuration

#### 1. Flagship Provider Setup

The application uses a custom `FsProvider` component from <kbd>FsProvider.tsx</kbd> to initialize Flagship with your environment credentials:

```tsx
// helpers/FsProvider.tsx
import FlagshipProvider, {
  LogLevel,
  type VisitorData,
} from "@flagship.io/react-sdk";
import { Loader } from "../components/Loader";

export function FsProvider({
  children,
  visitorData
}: {
  children: React.ReactNode;
  visitorData?: VisitorData;
}) {
  return (
    <FlagshipProvider
      envId={import.meta.env.VITE_ENV_ID} // Environment ID from Flagship
      apiKey={import.meta.env.VITE_API_KEY} // API Key from Flagship
      logLevel={LogLevel.DEBUG}
      visitorData={visitorData || null} // visitor data to pass
      loadingComponent={<Loader />} // Optional Loading component while flags are being fetched
    >
      {children}
    </FlagshipProvider>
  );
}
```

#### 2. Application Structure

The main application structure in <kbd>App.tsx</kbd> sets up React Router and wraps everything in the Flagship provider:

```tsx
// App.tsx
import { useState } from "react";
import { createBrowserRouter, RouterProvider } from "react-router";
import Home from "./routes/home";
import { FsProvider } from "./helpers/FsProvider";
import AnotherPage from "./routes/anotherPage";
import { Layout } from "./Layout";

const router = createBrowserRouter([
  {
    path: "/",
    Component: Layout,
    children: [
      {
        index: true,
        Component: Home,
      },
      {
        path: "another-page",
        Component: AnotherPage,
      },
    ],
  },
]);

function App() {

    // Initialize visitor data
  const [visitorData, setVisitorData] = useState({
    hasConsented: true,
  });

  return (
    <FsProvider
      visitorData={visitorData}
    >
      <RouterProvider router={router} />
    </FsProvider>
  );
}
```

#### 3. Layout Component

The application uses a common layout with navigation in Layout.tsx:

```tsx
// Layout.tsx
import { Outlet } from "react-router";
import Nav from "./components/Nav";

export function Layout() {
  return (
    <div className={"container"}>
      <div className="nav">
        <Nav />
      </div>
      <main className={"main"}>
        <Outlet />
      </main>
    </div>
  );
}
```

#### 4. Navigation Component

The navigation component in Nav.tsx uses React Router's `Link` component:

```tsx
// components/Nav.tsx
import { Link } from "react-router";

export default function Nav() {
  return (
    <>
      <Link to="/">Home</Link>
      <Link to="/another-page">Page - 2</Link>
    </>
  );
}
```

### Using Flagship Flags

There are two main ways to access feature flags in your components:

#### Option 1: Use the `useFsFlag` Hook Directly

As shown in anotherPage.tsx:

```tsx
// routes/anotherPage.tsx
import { useFsFlag } from "@flagship.io/react-sdk";

export default function AnotherPage() {
  // Get the flag `btnColor` using useFsFlag hook
  const flag = useFsFlag("btnColor");
  const flagValue = flag.getValue("#dc3545");

  return (
    <>
      <h1>This is another page</h1>
      <p>flag key: btnColor</p>
      <p>flag value: {flagValue}</p>
      <button style={{ background: flagValue }}>Click me</button>
    </>
  );
}
```

#### Option 2: Create Reusable Flag Components

For better reusability, create dedicated components like MyFlagComponent.tsx:

```tsx
// components/MyFlagComponent.tsx
import { useFsFlag } from "@flagship.io/react-sdk";

export function MyFlagComponent() {
    // Replace 'my_flag_key' with the actual key of the flag you want to use
    const myFlag = useFsFlag("my_flag_key");
    return <p>flag value: {myFlag.getValue("default-value")}</p>
}
```

Then use this component in your routes like home.tsx:

```tsx
// routes/home.tsx
import { MyFlagComponent } from "../components/MyFlagComponent";
import { MyButtonSendHit } from "../components/MyButtonSendHit";

export default function Home() {
  return (
    <>
      <h1>Example of Flagship implementation with React Router framework</h1>
      <p>flag key: my_flag_key</p>
      <MyFlagComponent />
      <MyButtonSendHit />
    </>
  );
}
```

### Sending Analytics Hits

To track user actions, you can send analytics hits using the Flagship SDK as shown in MyButtonSendHit.tsx:

```tsx
// components/MyButtonSendHit.tsx
import { useFlagship, HitType, EventCategory } from "@flagship.io/react-sdk";

export function MyButtonSendHit() {
  const fs = useFlagship();

  const onSendHitClick = () => {
    // This will send a hit to Flagship
    fs.sendHits({
      type: HitType.EVENT,
      category: EventCategory.ACTION_TRACKING,
      action: "click button",
    });
  };

  return (
    <button
      style={{ width: 100, height: 50 }}
      onClick={() => {
        onSendHitClick();
      }}
    >
      Send hits
    </button>
  );
}
```

### Handling Loading States

The application includes a loading component in Loader.tsx that displays while Flagship flags are being fetched:

```tsx
// components/Loader.tsx
export function Loader() {
    return (
        <div className='loader'>
            <div className="lds-ring"><div></div><div></div><div></div><div></div></div>
        </div>
    )
}
```

### Environment Configuration

For Flagship to work properly, you need to set up the following environment variables in a .env.local file:

```txt
VITE_ENV_ID=your-flagship-environment-id
VITE_API_KEY=your-flagship-api-key
```

### Running the Application

To run the application:

```bash
# Install dependencies
yarn install

# Start development server
yarn dev

# Build for production
yarn build

# Preview production build
yarn preview
```

### Additional Considerations

1. **Visitor Data**: You can customize the visitor data passed to Flagship in the `FsProvider` component.
2. **Default Values**: Always provide default values for flags in case they can't be retrieved from Flagship.
3. **Error Handling**: Consider adding error boundaries around components that depend on feature flags.
4. **Performance**: Be mindful of how many flag lookups you're performing in frequently re-rendered components.

For more information about Flagship, refer to the [official documentation](https://docs.developers.flagship.io/).


---

# Agent Instructions: 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:

```
GET https://docs.abtasty.com/server-side/sdks/react/examples/react-router-7-with-vite.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
