Bridge UI

Next.js

Set up Bridge UI in a Next.js App Router project.

Bridge UI React works with Next.js using a client provider in the App Router.

Use the framework selector in the site header to switch between React and Vue.

Install packages

Packages are published on npm as 0.0.3.

Note

Bridge UI Vue targets Vue apps. For a Vue SSR stack, use the Nuxt guide instead.

bun add @bridge-ui/[email protected]

Providers

Interactive Bridge UI components and imperative actions need a client boundary. Create a providers component and wrap your root layout:

See the Nuxt guide for Vue setup.

app/providers.tsx:

"use client";

import { BridgeUIProvider } from "@bridge-ui/react";
import { BridgeUIHosts } from "@bridge-ui/react/Actions";
import type { PropsWithChildren } from "react";

export function Providers({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider global={{}} components={{}}>
      <BridgeUIHosts
        modal={{ modal: { transition: "fade" } }}
        dialog={{ modal: { transition: "fade" } }}
        snackbar={{ max: 3, timeout: 5000, position: "bottom-center" }}
      >
        {children}
      </BridgeUIHosts>
    </BridgeUIProvider>
  );
}

app/layout.tsx:

import { Providers } from "./providers";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

BridgeUIHosts enables imperative actions ( useModalAction, useDialogAction, useSnackbarAction) from any client component under the provider.

Using components

Import Bridge UI components from client components (or pages marked with "use client"):

See the Nuxt guide.

"use client";

import { Button } from "@bridge-ui/react/Components/Button";

export function Example() {
  return <Button>Save</Button>;
}

Select async data

The Select component accepts an asyncData object with search and resolve callbacks. Call your own JSON API with axios (Route Handlers, external API, etc.).

Client helper

Create lib/asyncSelect.ts:

import type { SelectAsyncData, SelectValue } from "@bridge-ui/core";
import axios from "axios";

export function asyncSelect(options: { url: string }): SelectAsyncData {
  const { url } = options;

  return {
    limit: 20,
    resolve: async (values: SelectValue[]) => {
      const { data } = await axios.get(url, {
        params: { ids: values },
        headers: { Accept: "application/json" },
      });

      return data;
    },
    search: async (query) => {
      const params: Record<string, string> = {};
      if (query) params.search = query;

      const { data } = await axios.get(url, {
        params,
        headers: { Accept: "application/json" },
      });

      return data;
    },
  };
}

Your endpoint should return { label, value, description } objects and accept:

Param Purpose
search Filter options while the user types
ids Resolve labels for already-selected values

Usage in a page

See the Nuxt guide.

"use client";

import { useState } from "react";

import { asyncSelect } from "@/examples/core/integrations/asyncSelect";
import { Select } from "@bridge-ui/react/Components/Select";

export function UserSelect() {
  const [userId, setUserId] = useState<null | number | string>(null);

  return (
    <Select
      label="User"
      value={userId}
      onChange={setUserId}
      placeholder="Type to search users..."
      asyncData={asyncSelect({ url: "/api/examples/users" })}
    />
  );
}

asyncData implies searchable. Selected values are resolved through the same endpoint with ids when the page loads or when chips need labels.

Next steps