Proveedores y App Router
Proveedores de billetera y RPC en Next.js App Router sin bloqueos de SSR.
Receta
// app/layout.tsx
import { SolanaProvider } from "./solana-provider";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<SolanaProvider>{children}</SolanaProvider>
</body>
</html>
);
}// app/solana-provider.tsx
"use client";Cuándo usar esto:
- Cualquier dApp de Solana con Next.js 13+ App Router.
- Para prevenir
window is not definedde los SDKs de billetera. - Para compartir el estado de conexión entre rutas.
Ejemplo Funcional
// app/solana-provider.tsx
"use client";
import { useMemo } from "react";
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { PhantomWalletAdapter, SolflareWalletAdapter } from "@solana/wallet-adapter-wallets";
import "@solana/wallet-adapter-react-ui/styles.css";
export function SolanaProvider({ children }: { children: React.ReactNode }) {
const endpoint = process.env.NEXT_PUBLIC_RPC_URL!;
const wallets = useMemo(
() => [new PhantomWalletAdapter(), new SolflareWalletAdapter()],
[]
);
return (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>{children}</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}Lo que esto demuestra:
- El límite del cliente envuelve todas las importaciones de billetera.
- El layout raíz sigue siendo un Server Component.
useMemoestabiliza las instancias del adaptador de billetera.
Análisis Profundo
Cómo Funciona
- Los Server Components renderizan HTML sin APIs del navegador.
- Los proveedores del cliente se hidratan una vez a nivel de layout.
- Las rutas anidadas heredan el contexto automáticamente.
- Emparejar con
createSolanaRpcdel kit dentro de hooks para lecturas.
Errores Comunes
- Importar la billetera en page.tsx sin "use client" - error de compilación. Solución: dividir la shell del servidor de presentación + isla del cliente.
- Proveedores duplicados en layouts anidados - modales dobles. Solución: un único SolanaProvider raíz.
- Importación de CSS faltante - estilos del modal rotos.
- SSR prefetch llamando a hooks de billetera - bloqueo. Solución: importación dinámica con
ssr:falsepara widgets pesados si es necesario. - Entorno no disponible en la compilación - RPC indefinido. Solución: validar en
next.configo esquema de entorno.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Proveedor de @wallet-ui/react | Plantilla create-solana-dapp | Inversión existente en adaptadores |
| Pages Router | Solo aplicaciones heredadas | Greenfield App Router |
Preguntas Frecuentes
App Router?
Proveedores en layout.tsx del cliente; las páginas mezclan componentes de servidor y cliente.
Secretos?
Entorno del servidor solo para pares de claves; NEXT_PUBLIC_ para URLs RPC.
kit 7.0.0?
Todos los ejemplos usan @solana/kit, no web3.js v1.
Billetera?
Firmado solo en componentes cliente.
Caché?
Revalidar lecturas on-chain cuidadosamente - la cadena es la fuente de verdad.
Acciones?
Endpoints HTTPS que devuelven JSON de Acciones de Solana.
Móvil?
Aplicación React Native separada con MWA.
Pruebas?
Surfpool para integración; simular RPC en pruebas unitarias.
Mainnet?
Archivos de entorno y IDs de programa separados.
Errores?
Decodificar logs de simulación para mensajes dirigidos al usuario.
Relacionado
- Conceptos Básicos de Integración de dApps - estructura
- Adaptador de Billetera - configuración del adaptador
- Firmado del Lado del Cliente - flujos de firma
Versiones de Stack: Esta página fue escrita para 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, y LiteSVM 0.6.x.