Aprende a integrar Spline en tus componentes React de manera efectiva
Nota: Esta página usa 'use client' para habilitar la interactividad de los botones de copiar código.
Integra una escena de Spline en tu componente React
import Spline from '@splinetool/react-spline/next';export default function MiComponente() {return (<div className="w-full h-screen"><Spline scene="/mi-escena.splinecode" /></div>);}
Maneja el estado de carga y errores
import Spline from '@splinetool/react-spline/next';import { useState } from 'react';export default function SplineConControles() {const [isLoading, setIsLoading] = useState(true);const [hasError, setHasError] = useState(false);const handleLoad = () => {setIsLoading(false);};const handleError = () => {setHasError(true);setIsLoading(false);};return (<div className="relative w-full h-screen">{isLoading && (<div className="absolute inset-0 flex items-center justify-center bg-gray-100 dark:bg-gray-800"><div className="animate-spin rounded-full h-12 w-12 border-b-2 border-pink-500"></div></div>)}{hasError && (<div className="absolute inset-0 flex items-center justify-center bg-red-50 dark:bg-red-900/20"><p className="text-red-600 dark:text-red-400">Error al cargar la escena</p></div>)}<Splinescene="/mi-escena.splinecode"onLoad={handleLoad}onError={handleError}/></div>);}
Usa Spline como fondo con contenido superpuesto
import Spline from '@splinetool/react-spline/next';export default function PaginaConFondo() {return (<div className="relative min-h-screen">{/* Fondo con Spline */}<div className="fixed inset-0 z-0"><Spline scene="/fondo-3d.splinecode" /></div>{/* Contenido superpuesto */}<div className="relative z-10 flex min-h-screen items-center justify-center"><div className="bg-white/80 dark:bg-black/80 backdrop-blur-sm rounded-2xl p-8 max-w-2xl"><h1 className="text-4xl font-bold mb-4">Mi Contenido</h1><p className="text-lg text-gray-600 dark:text-gray-300">Este contenido se superpone sobre la escena 3D de fondo</p></div></div></div>);}
Landing page completa con escena de teclado interactiva en el lado derecho, permitiendo la interacción del usuario con el 3D mientras mantiene el contenido accesible en el lado izquierdo
Ver Demo Funcionalimport SplineBackground from "@/components/SplineBackground";import { SPLINE_SCENES } from "@/lib/spline-paths";import { ArrowRight } from "lucide-react";export default function LandingWebCode() {return (<div className="relative min-h-screen overflow-hidden">{/* Escena Spline de fondo */}<SplineBackgroundscene={SPLINE_SCENES.KEYBOARD}preset="BACKGROUND_RESPONSIVE"className="fixed inset-0 z-0"/>{/* Zona interactiva - Lado derecho */}<div className="fixed right-0 top-0 bottom-0 w-full md:w-1/2 z-5 pointer-events-auto" />{/* Overlay para mejor contraste del texto - Lado izquierdo */}<div className="fixed left-0 top-0 bottom-0 w-full md:w-1/2 bg-linear-to-r from-black/60 via-black/40 to-transparent z-1" />{/* Contenido principal */}<div className="relative z-10 min-h-screen flex items-center"><div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 w-full"><div className="grid lg:grid-cols-2 gap-12 items-center">{/* Hero Section - Lado izquierdo */}<div className="space-y-8 pointer-events-auto">{/* Badge */}<div className="inline-flex items-center gap-2 bg-linear-to-r from-pink-500/10 to-cyan-500/10 backdrop-blur-sm border border-pink-500/20 rounded-full px-4 py-2"><span className="text-sm font-medium bg-linear-to-r from-pink-400 to-cyan-400 bg-clip-text text-transparent">✨ Nuevo diseño disponible</span></div>{/* Título principal */}<div className="space-y-4"><h1 className="text-5xl md:text-7xl font-bold"><span className="bg-linear-to-r from-pink-400 via-purple-400 to-cyan-400 bg-clip-text text-transparent">WebCode</span></h1><p className="text-2xl md:text-3xl font-semibold text-white/90">WebDesign</p><p className="text-lg text-gray-300 max-w-lg">Crea experiencias web únicas con diseño 3D interactivo.Combina código elegante con visualizaciones impresionantes.</p></div>{/* CTAs */}<div className="flex flex-col sm:flex-row gap-4"><button className="group px-8 py-4 bg-linear-to-r from-pink-500 to-cyan-500 hover:from-pink-600 hover:to-cyan-600 text-white font-semibold rounded-xl transition-all duration-300 shadow-lg hover:shadow-pink-500/50 flex items-center justify-center gap-2">Comenzar ahora<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" /></button><button className="px-8 py-4 bg-white/10 hover:bg-white/20 backdrop-blur-sm text-white font-semibold rounded-xl border border-white/20 transition-all duration-300">Ver ejemplos</button></div>{/* Stats */}<div className="grid grid-cols-3 gap-8 pt-8 border-t border-white/10"><div><div className="text-3xl font-bold bg-linear-to-r from-pink-400 to-purple-400 bg-clip-text text-transparent">100%</div><div className="text-sm text-gray-400">Responsive</div></div><div><div className="text-3xl font-bold bg-linear-to-r from-purple-400 to-cyan-400 bg-clip-text text-transparent">3D</div><div className="text-sm text-gray-400">Interactivo</div></div><div><div className="text-3xl font-bold bg-linear-to-r from-cyan-400 to-pink-400 bg-clip-text text-transparent">Fast</div><div className="text-sm text-gray-400">Optimizado</div></div></div></div>{/* Lado derecho - Espacio para interacción con la escena */}<div className="hidden lg:block" /></div></div></div></div>);}
| Propiedad | Tipo | Descripción |
|---|---|---|
scene | string | URL o ruta del archivo .splinecode |
onLoad | function | Callback ejecutado cuando la escena se carga |
onError | function | Callback ejecutado si hay un error |
style | object | Estilos CSS personalizados |
className | string | Clases CSS adicionales |
En Next.js 16, los componentes son Server Components por defecto. Añade 'use client' cuando necesites:
'use client';import { useState } from 'react';import Spline from '@splinetool/react-spline/next';export default function InteractiveSpline() {const [isLoaded, setIsLoaded] = useState(false);return (<div>{!isLoaded && <div>Cargando...</div>}<Splinescene="/escena.splinecode"onLoad={() => setIsLoaded(true)}/></div>);}
Crear landing pages con escenas 3D interactivas requiere una arquitectura de capas cuidadosa para garantizar que tanto el contenido como la escena sean accesibles e interactivos.
FIXED_FULLSCREEN_INTERACTIVEpointer-events-none en capas de overlay y contenidopointer-events-auto sobre la escena que bloqueen la interacciónbackdrop-blur-sm para efecto glassmorphismBACKGROUND_RESPONSIVE para posicionamiento adaptativolg:grid-cols-2 para layout adaptativopointer-events-none, bloqueará toda la interacción.FIXED_FULLSCREEN tiene pointer-events-none, usa FIXED_FULLSCREEN_INTERACTIVE para escenas interactivas.pointer-events-none, elementos interactivos con pointer-events-auto.<div className="relative min-h-screen">{/* Capa 1: Escena 3D (z-0, interactiva) */}<SplineBackgroundscene={SPLINE_SCENES.KEYBOARD}preset="BACKGROUND_RESPONSIVE"container="FIXED_FULLSCREEN_INTERACTIVE" // ← IMPORTANTEclassName="fixed inset-0 z-0"/>{/* Capa 2: Overlay de gradiente (z-1, no interactivo) */}<div className="fixed left-0 top-0 bottom-0 w-full md:w-1/2bg-linear-to-r from-black/60 to-transparentz-1 pointer-events-none" /> {/* ← No bloquea interacción */}{/* Capa 3: Contenido (z-10) */}<div className="relative z-10 min-h-screen flex items-centerpointer-events-none"> {/* ← pointer-events-none en container */}<div className="grid lg:grid-cols-2 gap-12">{/* Contenido izquierda - interactivo */}<div className="space-y-8 pointer-events-auto"> {/* ← auto solo aquí */}<h1>WebCode</h1><button>Click me</button> {/* ← Este botón funciona */}</div>{/* Espacio derecho - NO bloquear la escena */}<div className="hidden lg:block pointer-events-none" /> {/* ← none */}</div></div></div>