Ir al contenido
Evaluar mi proyecto
Componentes · SeccionesDisponible

Página 404 con enchufe desconectado

Ilustración SVG animada, mensaje claro, qué hacer a continuación y enlace de regreso.

Esta página se desconectó

El enlace que seguiste ya no existe o la dirección tiene un error. No pasa nada: aquí tienes por dónde seguir.

  • Revisa la dirección
  • Usa el menú principal
  • Escríbenos si sigue fallando
Volver al inicio

Código completo

Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.

seccion-404.tsx68 líneas
Descargar
"use client";

import type { CSSProperties } from "react";

/** Página de error 404 con ilustración animada de un enchufe desconectado, mensaje claro, qué hacer a continuación y enlace de regreso. Ilustración SVG propia. React + TypeScript, sin dependencias. */
export type Seccion404Props = {
  title?: string;
  description?: string;
  href?: string;
  action?: string;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gcsfo-root { box-sizing: border-box; container-type: inline-size; display: grid; place-items: center; align-content: center; gap: 22px; width: 100%; min-height: 520px; padding: 40px 20px; background: #f4f6fb; color: #1f2430; text-align: center; font: 400 16px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; overflow: hidden; }
.gcsfo-root *, .gcsfo-root *::before, .gcsfo-root *::after { box-sizing: border-box; }
.gcsfo-root :focus-visible { outline: 3px solid #2f5bff; outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .gcsfo-root * { animation: none !important; } }
.gcsfo-art { position: relative; width: min(420px, 90%); height: 150px; }
.gcsfo-art svg { width: 100%; height: 100%; overflow: visible; }
.gcsfo-plug { animation: gcsfo-pull 3.2s cubic-bezier(.65, 0, .35, 1) infinite; }
.gcsfo-spark { transform-origin: 208px 75px; animation: gcsfo-spark 3.2s linear infinite; }
.gcsfo-code { margin: 0; font: 900 clamp(72px, 16cqi, 160px)/.85 "Arial Black", ui-sans-serif, system-ui, sans-serif; letter-spacing: -.06em; color: #1f2430; }
.gcsfo-code span { color: #2f5bff; }
.gcsfo-title { margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -.02em; }
.gcsfo-desc { margin: 0; max-width: 42ch; color: #5b6477; }
.gcsfo-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 4px 0 0; padding: 0; list-style: none; font-size: 14px; }
.gcsfo-list li { padding: 6px 12px; border: 1px solid #dde1ec; border-radius: 99px; background: #fff; color: #4a5368; }
.gcsfo-btn { display: inline-flex; align-items: center; min-height: 50px; padding: 0 26px; border-radius: 12px; background: #1f2430; color: #fff; font-weight: 600; text-decoration: none; transition: background .2s, transform .25s cubic-bezier(.16, 1, .3, 1); }
.gcsfo-btn:hover { background: #2f5bff; transform: translateY(-2px); }
@keyframes gcsfo-pull { 0%, 12% { transform: translateX(0); } 40%, 70% { transform: translateX(96px); } 100% { transform: translateX(0); } }
@keyframes gcsfo-spark { 0%, 36%, 100% { opacity: 0; transform: scale(.4); } 40% { opacity: 1; transform: scale(1.2); } 48% { opacity: 0; transform: scale(1.5); } }`;

export function Seccion404({ title = "Esta página se desconectó", description = "El enlace que seguiste ya no existe o la dirección tiene un error. No pasa nada: aquí tienes por dónde seguir.", href = "#", action = "Volver al inicio", className = "", style }: Seccion404Props) {
  return (
    <section className={`gcsfo-root ${className}`} style={style} aria-labelledby="gcsfo-t">
      <style>{CSS}</style>
      <div className="gcsfo-art" aria-hidden="true">
        <svg viewBox="0 0 420 150">
          <path d="M0 75 H150" stroke="#9aa3b8" strokeWidth="6" strokeLinecap="round" fill="none" />
          <rect x="150" y="45" width="52" height="60" rx="10" fill="#1f2430" />
          <rect x="190" y="55" width="12" height="12" rx="3" fill="#0b0e14" />
          <rect x="190" y="83" width="12" height="12" rx="3" fill="#0b0e14" />
          <g className="gcsfo-plug">
            <path d="M420 75 H290" stroke="#9aa3b8" strokeWidth="6" strokeLinecap="round" fill="none" />
            <rect x="234" y="45" width="56" height="60" rx="10" fill="#2f5bff" />
            <rect x="196" y="57" width="38" height="8" rx="3" fill="#cfd6ea" />
            <rect x="196" y="85" width="38" height="8" rx="3" fill="#cfd6ea" />
          </g>
          <g className="gcsfo-spark" fill="#ffb800">
            <path d="M208 52 l5 14 l-9 -3 l8 14 l-3 -10 l9 3 z" />
          </g>
        </svg>
      </div>
      <p className="gcsfo-code" aria-hidden="true">4<span>0</span>4</p>
      <h2 className="gcsfo-title" id="gcsfo-t">{title}</h2>
      <p className="gcsfo-desc">{description}</p>
      <ul className="gcsfo-list" aria-label="Sugerencias">
        <li>Revisa la dirección</li>
        <li>Usa el menú principal</li>
        <li>Escríbenos si sigue fallando</li>
      </ul>
      <a className="gcsfo-btn" href={href} onClick={(event) => href === "#" && event.preventDefault()}>{action}</a>
    </section>
  );
}

Úsalo en tu proyecto

Instálalo con la CLI de shadcn.

terminal.sh1 líneas
npx shadcn@latest add https://www.gassierconsulting.com/r/seccion-404

Ejemplo de uso de Página 404 con enchufe desconectado

Después de copiar seccion-404.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.

ejemplo.tsx5 líneas
import { Seccion404 } from "./seccion-404";

export default function Ejemplo() {
  return <Seccion404 title="Ejemplo" />;
}

Propiedades de Seccion404

Seccion404 acepta 6 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.

PropiedadTipoDescripción
title?stringOpcional.
description?stringOpcional.
href?stringOpcional.
action?stringOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

Accesibilidad y rendimiento

El archivo tiene 68 líneas (4 KB) y define 2 animaciones con @keyframes. Esto es lo que hace Página 404 con enchufe desconectado por quien lo usa:

  • Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
  • Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
  • Expone su estado a tecnologías de apoyo con atributos aria-*.
  • Es un componente de cliente de Next.js: incluye la directiva "use client".
Licencia
MIT
Dependencias
React >=18
Compatibilidad
React 18 y 19 · Next.js (componente de cliente)