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

# Network switching & validation

> Show the active network, let users switch, and make sure a wallet is on the right network before you transact.

## Prerequisites

Before this page: have a connected wallet (see [Connecting external wallets](https://docs.dynamic.xyz/docs/javascript/building-ui/connecting-external-wallets.md)). Network operations act on a specific `WalletAccount` that your app supplies.

## What you'll build

Three things most web3 apps need:

* **Show** the wallet's current network.
* **Switch** the wallet to another supported network.
* **Validate** the wallet is on the network your action requires — and switch (or ask the user to) when it isn't.

## Showing the active network

`getActiveNetworkData` returns `{ networkData }` for the wallet's current network — `displayName`, `iconUrl`, `nativeCurrency`, and the `networkId`. `getNetworksData` returns every network configured for your project, across all chains — filter it to the wallet's `chain` so the picker only offers networks the wallet can actually switch to.

> [tab] TypeScript
>
> ```typescript theme={"system"}
> import {
>   getActiveNetworkData,
>   getNetworksData,
>   switchActiveNetwork,
>   type WalletAccount,
> } from '@dynamic-labs-sdk/client';
>
> async function renderNetworkPicker(
>   select: HTMLSelectElement,
>   walletAccount: WalletAccount,
> ) {
>   const { networkData } = await getActiveNetworkData({ walletAccount });
>   // getNetworksData spans every configured chain; a wallet can only switch
>   // within its own chain, so keep only the networks on the wallet's chain.
>   const networks = getNetworksData().filter(
>     (network) => network.chain === walletAccount.chain,
>   );
>
>   select.replaceChildren();
>   for (const network of networks) {
>     const option = document.createElement('option');
>     option.value = network.networkId;
>     option.textContent = network.displayName;
>     option.selected = network.networkId === networkData?.networkId;
>     select.append(option);
>   }
>
>   select.addEventListener('change', async () => {
>     await switchActiveNetwork({ networkId: select.value, walletAccount });
>   });
> }
> ```

> [tab] React
>
> ```tsx theme={"system"}
> import {
>   getNetworksData,
>   type WalletAccount,
> } from '@dynamic-labs-sdk/client';
> import {
>   useGetActiveNetworkData,
>   useSwitchActiveNetwork,
> } from '@dynamic-labs-sdk/react-hooks';
>
> function NetworkPicker({ walletAccount }: { walletAccount: WalletAccount }) {
>   const { data } = useGetActiveNetworkData({ walletAccount });
>   const { mutateAsync: switchNetwork, isPending } = useSwitchActiveNetwork();
>   // Keep only networks on the wallet's own chain — the only ones it can switch to.
>   const networks = getNetworksData().filter(
>     (network) => network.chain === walletAccount.chain,
>   );
>
>   return (
>     <select
>       value={data?.networkData?.networkId ?? ''}
>       disabled={isPending}
>       onChange={(event) =>
>         switchNetwork({ networkId: event.target.value, walletAccount })
>       }
>     >
>       {networks.map((network) => (
>         <option key={network.networkId} value={network.networkId}>
>           {network.displayName}
>         </option>
>       ))}
>     </select>
>   );
> }
> ```
>
> The active-network query refetches on `networkChanged`, so the picker reflects switches made anywhere — including from inside the wallet.

## Validating before an action

Before a transaction that must run on a specific network, check the active network and switch if needed. Some wallets don't allow programmatic switching — `isProgrammaticNetworkSwitchAvailable` tells you whether to switch for the user or ask them to switch in their wallet.

> [tab] TypeScript
>
> ```typescript theme={"system"}
> import {
>   getActiveNetworkData,
>   switchActiveNetwork,
>   isProgrammaticNetworkSwitchAvailable,
> } from '@dynamic-labs-sdk/client';
> import type { WalletAccount } from '@dynamic-labs-sdk/client';
>
> // Ensure the wallet is on `requiredNetworkId`; returns whether it's safe to proceed.
> async function ensureNetwork(
>   walletAccount: WalletAccount,
>   requiredNetworkId: string,
> ): Promise<boolean> {
>   const { networkData } = await getActiveNetworkData({ walletAccount });
>   if (networkData?.networkId === requiredNetworkId) return true;
>
>   if (isProgrammaticNetworkSwitchAvailable({ walletAccount })) {
>     await switchActiveNetwork({ networkId: requiredNetworkId, walletAccount });
>     return true;
>   }
>
>   // promptManualSwitch is your implementation — tell the user to switch in their wallet.
>   promptManualSwitch(requiredNetworkId);
>   return false;
> }
> ```

> [tab] React
>
> ```tsx theme={"system"}
> import {
>   getActiveNetworkData,
>   isProgrammaticNetworkSwitchAvailable,
> } from '@dynamic-labs-sdk/client';
> import type { WalletAccount } from '@dynamic-labs-sdk/client';
> import { useSwitchActiveNetwork } from '@dynamic-labs-sdk/react-hooks';
>
> function useEnsureNetwork(walletAccount: WalletAccount) {
>   const { mutateAsync: switchNetwork } = useSwitchActiveNetwork();
>
>   return async (requiredNetworkId: string) => {
>     const { networkData } = await getActiveNetworkData({ walletAccount });
>     if (networkData?.networkId === requiredNetworkId) return true;
>
>     if (!isProgrammaticNetworkSwitchAvailable({ walletAccount })) return false;
>
>     await switchNetwork({ networkId: requiredNetworkId, walletAccount });
>     return true;
>   };
> }
> ```

> [!TIP]
>
> Call your network check right before sending — not just on page load. A user can switch networks in their wallet at any time, so validate at the moment the network actually matters.

## Handling errors

| Situation | What to do |
| - | - |
| `isProgrammaticNetworkSwitchAvailable` is `false` | Show the target network's `displayName` and ask the user to switch in their wallet, then re-check. |
| User rejects the switch prompt (`UserRejectedError`) | Keep them on the current network and don't proceed with the action that required the switch. |
| Target network not in `getNetworksData` | It isn't enabled for your project — enable it in the Dynamic Console rather than hardcoding it. |
| `networkData` is `undefined` | The wallet's current chain isn't among your configured networks; treat it as "wrong network" and prompt a switch. |

## See also

* [Connected wallets management](https://docs.dynamic.xyz/docs/javascript/building-ui/connected-wallets-management.md) — the wallet you're switching networks for
* [Transaction confirmation & simulation](https://docs.dynamic.xyz/docs/javascript/building-ui/transaction-confirmation.md) — validate the network right before sending
* [Token balances & display](https://docs.dynamic.xyz/docs/javascript/building-ui/token-balances-display.md) — balances are per network


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.