Displaying On-Chain Data
Render balances, tokens, NFTs, and program state in React.
Search across all documentation pages
Render balances, tokens, NFTs, and program state in React.
import { createSolanaRpc, address, lamports } from "@solana/kit";
import { fetchMaybeTokenAccount } from "@solana-program/token";When to reach for this:
"use client";
import { useEffect, useState } from "react";
import { createSolanaRpc, address } from "@solana/kit";
export function SolBalance({ owner }: { owner: string }) {
const [sol, setSol] = useState<number | null>(null);
useEffect(() => {
const rpc = createSolanaRpc(process.env.NEXT_PUBLIC_RPC_URL!);
rpc.getBalance(address(owner)).send().then(({ value }) => setSol(Number(value) / 1e9));
}, [owner]);
if (sol === null) return <span>…</span>;
return <span>{sol.toFixed(4)} SOL</span>;
}What this demonstrates:
getBalance.getAsset on supporting RPC providers.| Alternative | Use When | Don't Use When |
|---|---|---|
| Server render initial | SEO | Wallet-only private data |
| Indexer GraphQL | Rich history | Simple balance chip |
Providers in client layout.tsx; pages mix server + client components.
Server env only for keypairs; NEXT_PUBLIC_ for RPC URLs.
All examples use @solana/kit, not web3.js v1.
Signing only in client components.
Revalidate on-chain reads carefully - chain is source of truth.
HTTPS endpoints returning Solana Actions JSON.
Separate React Native app with MWA.
Surfpool for integration; mock RPC in unit tests.
Separate env files and program IDs.
Decode simulation logs for user-facing messages.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026