@xenterprises/nuxt-x-marketing 1.4.5 → 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -30,6 +30,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
30
30
  section and its sample product data were dropped with them. Every other section of the
31
31
  demo page is unchanged.
32
32
 
33
+ ## [1.4.7] - 2026-09-06
34
+
35
+ ### Fixed
36
+
37
+ - `XXLegal` and `XFooterXLegal` show the X Enterprises logo as display-only (no link), matching the marketing page standard.
38
+
39
+ ## [1.4.6] - 2026-09-06
40
+
41
+ ### Added
42
+
43
+ - Ships `app/error.vue`: branded 404 / 500 (and other status) page with marketing chrome (`XHeaderNav`, `XFooter`), plain copy, and a home CTA via `clearError({ redirect: "/" })`. Consumers override with their own `app/error.vue`.
44
+
33
45
  ## [1.4.5] - 2026-09-03
34
46
 
35
47
  ### Fixed
@@ -2,13 +2,12 @@
2
2
  <footer
3
3
  class="bg-gray-900 text-gray-400 text-xs relative overflow-visible pt-2"
4
4
  >
5
- <a v-if="resolvedLogo.src" :href="resolvedLogo.href" target="_blank">
6
- <img
7
- :src="resolvedLogo.src"
8
- :alt="resolvedLogo.alt"
9
- class="h-6 w-6 mx-auto -mt-4 relative z-10"
10
- />
11
- </a>
5
+ <img
6
+ v-if="resolvedLogo.src"
7
+ :src="resolvedLogo.src"
8
+ :alt="resolvedLogo.alt"
9
+ class="h-6 w-6 mx-auto -mt-4 relative z-10"
10
+ />
12
11
  <div
13
12
  class="flex flex-col md:flex-row justify-between items-center px-6 pt-3 pb-5 max-w-screen-2xl mx-auto gap-4"
14
13
  >
@@ -43,7 +42,7 @@ const props = defineProps({
43
42
  type: Array,
44
43
  default: null,
45
44
  },
46
- /** Logo object { src, alt, href } (defaults to X Enterprises logo) */
45
+ /** Logo object { src, alt } (defaults to X Enterprises logo). href is ignored; logo is display-only. */
47
46
  logo: {
48
47
  type: Object,
49
48
  default: null,
@@ -2,13 +2,12 @@
2
2
  <footer
3
3
  class="bg-gray-900 text-gray-400 text-xs relative overflow-visible pt-2"
4
4
  >
5
- <a v-if="resolvedLogo.src" :href="resolvedLogo.href" target="_blank">
6
- <img
7
- :src="resolvedLogo.src"
8
- :alt="resolvedLogo.alt"
9
- class="h-6 w-6 mx-auto -mt-4 relative z-10"
10
- />
11
- </a>
5
+ <img
6
+ v-if="resolvedLogo.src"
7
+ :src="resolvedLogo.src"
8
+ :alt="resolvedLogo.alt"
9
+ class="h-6 w-6 mx-auto -mt-4 relative z-10"
10
+ />
12
11
  <div
13
12
  class="flex flex-col md:flex-row justify-between items-center px-6 pt-3 pb-5 max-w-screen-2xl mx-auto gap-4"
14
13
  >
@@ -38,6 +37,7 @@
38
37
  /**
39
38
  * XXLegal — X Enterprises branded legal footer bar
40
39
  * Defaults to X Enterprises copyright, logo, and legal links.
40
+ * XE logo is display-only (no link), per marketing page standard.
41
41
  * Pass props to override any defaults for white-label use.
42
42
  */
43
43
  const props = defineProps({
@@ -51,7 +51,7 @@ const props = defineProps({
51
51
  type: Array,
52
52
  default: null,
53
53
  },
54
- /** Logo object { src, alt, href } (defaults to X Enterprises logo). Pass false to hide. */
54
+ /** Logo object { src, alt } (defaults to X Enterprises logo). Pass false to hide. href is ignored; logo is display-only. */
55
55
  logo: {
56
56
  type: [Object, Boolean],
57
57
  default: null,
package/app/error.vue ADDED
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <div class="min-h-screen flex flex-col">
3
+ <XHeaderNav v-if="headerActive" />
4
+
5
+ <main class="flex-grow flex items-center">
6
+ <UApp>
7
+ <div class="w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24 md:py-32">
8
+ <div class="max-w-xl">
9
+ <p class="xText-eyebrow text-primary-500 mb-4">
10
+ {{ codeLabel }}
11
+ </p>
12
+ <h1 class="xText-display xText-balance">
13
+ {{ title }}
14
+ </h1>
15
+ <p class="mt-6 text-xl text-neutral-600 dark:text-neutral-300">
16
+ {{ description }}
17
+ </p>
18
+ <div class="mt-10 flex flex-wrap gap-4">
19
+ <UButton size="xl" color="primary" @click="goHome">
20
+ Back home
21
+ </UButton>
22
+ <UButton
23
+ v-if="isServerError"
24
+ size="xl"
25
+ color="neutral"
26
+ variant="outline"
27
+ @click="goHome"
28
+ >
29
+ Try again
30
+ </UButton>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </UApp>
35
+ </main>
36
+
37
+ <XFooter v-if="footerActive" />
38
+ </div>
39
+ </template>
40
+
41
+ <script setup>
42
+ /**
43
+ * Layer default error page for 404 / 500 (and other status codes).
44
+ * Replaces Nuxt's stock error UI. Consumers override with their own app/error.vue.
45
+ * error.vue is a full app replacement (not wrapped by app.vue), so chrome is inlined.
46
+ */
47
+ const props = defineProps({
48
+ error: {
49
+ type: Object,
50
+ required: true,
51
+ },
52
+ });
53
+
54
+ const appConfig = useAppConfig();
55
+ const xMarketing = appConfig?.xMarketing;
56
+
57
+ const headerActive = computed(() => xMarketing?.header?.active !== false);
58
+ const footerActive = computed(() => xMarketing?.footer?.active !== false);
59
+
60
+ const status = computed(() => {
61
+ const code = props.error?.statusCode ?? props.error?.status;
62
+ return typeof code === "number" ? code : Number(code) || 500;
63
+ });
64
+
65
+ const isNotFound = computed(() => status.value === 404);
66
+ const isServerError = computed(() => status.value >= 500);
67
+
68
+ const codeLabel = computed(() => String(status.value));
69
+
70
+ const title = computed(() => {
71
+ if (isNotFound.value) return "Page not found";
72
+ if (isServerError.value) return "Something broke";
73
+ return "Something went wrong";
74
+ });
75
+
76
+ const description = computed(() => {
77
+ if (isNotFound.value) {
78
+ return "That page is gone, or the link is wrong.";
79
+ }
80
+ if (isServerError.value) {
81
+ return "We hit a problem on our side. Try again in a minute.";
82
+ }
83
+ return props.error?.statusMessage || props.error?.message || "Please try again.";
84
+ });
85
+
86
+ const siteName = computed(() => xMarketing?.name);
87
+
88
+ useSeoMeta({
89
+ title: () => (siteName.value ? `${title.value} | ${siteName.value}` : title.value),
90
+ robots: "noindex",
91
+ });
92
+
93
+ function goHome() {
94
+ clearError({ redirect: "/" });
95
+ }
96
+ </script>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@xenterprises/nuxt-x-marketing",
3
3
  "license": "SEE LICENSE IN LICENSE",
4
4
  "type": "module",
5
- "version": "1.4.5",
5
+ "version": "1.4.7",
6
6
  "main": "./nuxt.config.ts",
7
7
  "scripts": {
8
8
  "dev": "nuxi dev .playground",