Network Switcher
Mainnet, Devnet, and Testnet cluster switcher for the wallet dropdown.
Preview
"use client";import { ClusterElement } from "@solana/connector/react";import { Globe } from "lucide-react";import { Button } from "@/components/ui/button";import { clusterColors } from "@/lib/cluster-colors";import { cn } from "@/lib/utils";interface NetworkSwitcherButtonProps { onClick: () => void;}export function NetworkSwitcherButton({ onClick }: NetworkSwitcherButtonProps) { return ( <ClusterElement render={({ cluster }) => ( <Button type="button" variant="outline" size="icon" className="relative rounded-full" onClick={onClick} title={`Network: ${cluster?.label || "Unknown"}`} > <Globe className="h-4 w-4" /> <span className={cn( "border-background absolute -right-0.5 -bottom-0.5 h-3.5 w-3.5 rounded-full border-2", clusterColors[cluster?.id || ""] || "bg-purple-500", )} /> </Button> )} /> );}Prerequisites
Complete the installation guide and install Connect Button before using this addon.
Try the Demo
Want to see it working immediately without manual wiring? Install the demo:
npx shadcn@latest add https://nitso.fun/r/network-switcher-demo.jsonpnpm dlx shadcn@latest add https://nitso.fun/r/network-switcher-demo.jsonyarn dlx shadcn@latest add https://nitso.fun/r/network-switcher-demo.jsonbunx --bun shadcn@latest add https://nitso.fun/r/network-switcher-demo.jsonThis installs network-switcher-demo.tsx into your components/ folder. Drop it anywhere:
import { NetworkSwitcherDemo } from '@/components/network-switcher-demo';
export default function Page() {
return <NetworkSwitcherDemo />;
}Delete it when you're ready to wire things up yourself.
Installation
npx shadcn@latest add https://nitso.fun/r/network-switcher.jsonpnpm dlx shadcn@latest add https://nitso.fun/r/network-switcher.jsonyarn dlx shadcn@latest add https://nitso.fun/r/network-switcher.jsonbunx --bun shadcn@latest add https://nitso.fun/r/network-switcher.jsonInstall shadcn UI components
npx shadcn@latest buttonpnpm dlx shadcn@latest buttonyarn dlx shadcn@latest buttonbunx --bun shadcn@latest buttonCopy the source code
"use client";import { ClusterElement } from "@solana/connector/react";import { Globe } from "lucide-react";import { Button } from "@/components/ui/button";import { clusterColors } from "@/lib/cluster-colors";import { cn } from "@/lib/utils";interface NetworkSwitcherButtonProps { onClick: () => void;}export function NetworkSwitcherButton({ onClick }: NetworkSwitcherButtonProps) { return ( <ClusterElement render={({ cluster }) => ( <Button type="button" variant="outline" size="icon" className="relative rounded-full" onClick={onClick} title={`Network: ${cluster?.label || "Unknown"}`} > <Globe className="h-4 w-4" /> <span className={cn( "border-background absolute -right-0.5 -bottom-0.5 h-3.5 w-3.5 rounded-full border-2", clusterColors[cluster?.id || ""] || "bg-purple-500", )} /> </Button> )} /> );}Wiring
Update the file where you use <ConnectButton /> (e.g. your header or layout):
Before:
import { ConnectButton } from "@/components/nitso/connect-button/";
export function Header() {
return (
<nav>
<ConnectButton />
</nav>
);
}After:
import { useState } from "react";
import { ConnectButton } from "@/components/nitso/connect-button/";
import {
WalletDropdownContent,
type WalletDropdownContentProps,
} from "@/components/nitso/connect-button/";
import {
NetworkSwitcherButton,
NetworkSwitcherView,
} from "@/components/nitso/addons/network-switcher/";
function WalletDropdownWithNetwork(props: WalletDropdownContentProps) {
const [view, setView] = useState<"wallet" | "network">("wallet");
if (view === "network") {
return <NetworkSwitcherView onBack={() => setView("wallet")} />;
}
return (
<WalletDropdownContent
{...props}
actions={<NetworkSwitcherButton onClick={() => setView("network")} />}
/>
);
}
export function Header() {
return (
<nav>
<ConnectButton /> // [!code --]
<ConnectButton dropdownContent={WalletDropdownWithNetwork} /> // [!code
++]
</nav>
);
}The WalletDropdownWithNetwork component uses a view state to toggle between the wallet dropdown and the network picker. NetworkSwitcherButton is added to the actions slot in the dropdown header, and NetworkSwitcherView replaces the entire dropdown when the user taps it. The onBack callback returns to the wallet view.
Props
NetworkSwitcherButton
| Prop | Type | Default | Description |
|---|---|---|---|
onClick | () => void | — | Callback to switch to network view (required) |
className | string | — | Additional CSS classes |
NetworkSwitcherView
| Prop | Type | Default | Description |
|---|---|---|---|
onBack | () => void | — | Callback to return to wallet view (required) |
className | string | — | Additional CSS classes |