{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "error-404",
  "title": "404 Not Found",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/error-404/Error404.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { computed } from 'vue'\nimport { ArrowLeft, LifeBuoy } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\n\ninterface Props {\n  code?: string\n  title?: string\n  description?: string\n  /** Replaces the HTTP response panel. Pass `''` to hide art entirely. */\n  image?: string\n  imageAlt?: string\n  primaryLabel?: string\n  secondaryLabel?: string\n  primaryHref?: string\n  secondaryHref?: string\n  showPrimary?: boolean\n  showSecondary?: boolean\n  primaryDisabled?: boolean\n  secondaryDisabled?: boolean\n  onPrimary?: () => void\n  onSecondary?: () => void\n  /** `'page'` fills the viewport; `'contained'` fits a preview or nested panel. */\n  layout?: 'page' | 'contained'\n  class?: HTMLAttributes['class']\n}\n\nexport type Error404Props = Props\n\nconst props = withDefaults(defineProps<Props>(), {\n  image: '/illustrations/error-404.jpg',\n  imageAlt: '',\n  showPrimary: true,\n  showSecondary: true,\n  primaryDisabled: false,\n  secondaryDisabled: false,\n  layout: 'page',\n})\n\nconst copy = (fallback: string, override?: string) => (override === undefined ? fallback : override)\n\nconst code = computed(() => copy('404', props.code))\nconst title = computed(() => copy('Page not found', props.title))\nconst description = computed(() =>\n  copy(\n    \"The page you're looking for doesn't exist or may have been moved. Check the URL or head back home.\",\n    props.description,\n  ),\n)\nconst primaryLabel = computed(() => copy('Back to home', props.primaryLabel))\nconst secondaryLabel = computed(() => copy('Contact support', props.secondaryLabel))\n</script>\n\n<template>\n  <section\n    data-slot=\"error-404\"\n    :data-layout=\"layout\"\n    :class=\"\n      cn(\n        'bg-background relative flex items-center overflow-hidden px-6 py-16',\n        layout === 'page' ? 'min-h-svh' : 'min-h-[28rem]',\n        props.class,\n      )\n    \"\n  >\n    <div class=\"mx-auto grid w-full max-w-5xl items-center gap-10 lg:grid-cols-2 lg:gap-16\">\n      <div>\n        <p v-if=\"code\" class=\"text-muted-foreground text-sm font-medium\">HTTP {{ code }}</p>\n        <p v-if=\"code\" class=\"mt-3 text-6xl font-semibold tracking-tighter sm:text-7xl\">{{ code }}</p>\n        <h1 class=\"mt-3 text-2xl font-semibold tracking-tight sm:text-3xl\">{{ title }}</h1>\n        <p v-if=\"description\" class=\"text-muted-foreground mt-4 max-w-md text-base\">{{ description }}</p>\n        <div v-if=\"showPrimary || showSecondary\" class=\"mt-8 flex flex-wrap items-center gap-3\">\n          <Button\n            v-if=\"showPrimary\"\n            :as=\"primaryHref ? 'a' : 'button'\"\n            :href=\"primaryHref\"\n            size=\"lg\"\n            :disabled=\"primaryDisabled\"\n            @click=\"onPrimary?.()\"\n          >\n            <ArrowLeft />\n            {{ primaryLabel }}\n          </Button>\n          <Button\n            v-if=\"showSecondary\"\n            :as=\"secondaryHref ? 'a' : 'button'\"\n            :href=\"secondaryHref\"\n            size=\"lg\"\n            variant=\"outline\"\n            :disabled=\"secondaryDisabled\"\n            @click=\"onSecondary?.()\"\n          >\n            {{ secondaryLabel }}\n            <LifeBuoy />\n          </Button>\n        </div>\n      </div>\n      <div v-if=\"image\" class=\"border-border bg-muted overflow-hidden rounded-xl border\">\n        <img :src=\"image\" :alt=\"imageAlt\" class=\"aspect-[4/3] w-full object-cover\" />\n      </div>\n      <div\n        v-else-if=\"image === undefined\"\n        class=\"border-border bg-muted/40 overflow-hidden rounded-xl border font-mono\"\n        aria-hidden=\"true\"\n      >\n        <div class=\"border-border text-muted-foreground truncate border-b px-3 py-2 text-xs\">\n          curl -i https://app.acme.dev/pricing/teams\n        </div>\n        <div class=\"space-y-1 p-4 text-xs leading-relaxed\">\n          <p><span class=\"text-muted-foreground\">HTTP/1.1</span>{{ ' ' }}{{ code || '404' }} Not Found</p>\n          <p class=\"text-muted-foreground\">content-type: application/json</p>\n          <p class=\"text-muted-foreground\">x-request-id: req_9k2e18</p>\n          <p class=\"text-muted-foreground mt-3\">{ \"error\": \"not_found\", \"path\": \"/pricing/teams\" }</p>\n        </div>\n      </div>\n    </div>\n  </section>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/Error404.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/button.json"
  ],
  "description": "Full-page 404 with an isometric missing-page illustration, HTTP code, headline, and Back to home + Contact support. Prop-driven: pass title, description, image, action labels, hrefs, and layout (`page` | `contained`). Pass `image=\"\"` to hide the art.",
  "categories": [
    "layout",
    "feedback"
  ],
  "deprecated": true,
  "replacedBy": "error-page"
}