@depup/nuxt 4.2.2-depup.0 → 4.4.2-depup.0

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.
Files changed (100) hide show
  1. package/README.md +23 -105
  2. package/app.d.ts +1 -1
  3. package/dist/app/compat/capi.d.ts +1 -1
  4. package/dist/app/compat/interval.d.ts +1 -1
  5. package/dist/app/compat/interval.js +3 -3
  6. package/dist/app/components/client-fallback.client.js +5 -1
  7. package/dist/app/components/client-fallback.server.js +5 -1
  8. package/dist/app/components/error-404.d.vue.ts +6 -6
  9. package/dist/app/components/error-404.vue +4 -4
  10. package/dist/app/components/error-404.vue.d.ts +6 -6
  11. package/dist/app/components/error-500.d.vue.ts +6 -6
  12. package/dist/app/components/error-500.vue +4 -4
  13. package/dist/app/components/error-500.vue.d.ts +6 -6
  14. package/dist/app/components/island-renderer.js +2 -2
  15. package/dist/app/components/nuxt-announcer.d.ts +26 -0
  16. package/dist/app/components/nuxt-announcer.js +59 -0
  17. package/dist/app/components/nuxt-error-page.vue +4 -4
  18. package/dist/app/components/nuxt-island.js +8 -2
  19. package/dist/app/components/nuxt-layout.js +49 -23
  20. package/dist/app/components/nuxt-link.js +30 -16
  21. package/dist/app/components/nuxt-root.vue +1 -1
  22. package/dist/app/components/nuxt-route-announcer.js +11 -2
  23. package/dist/app/components/nuxt-stubs.d.ts +2 -2
  24. package/dist/app/components/nuxt-stubs.js +2 -2
  25. package/dist/app/components/nuxt-time.vue +13 -2
  26. package/dist/app/components/test-component-wrapper.js +10 -2
  27. package/dist/app/components/utils.d.ts +7 -1
  28. package/dist/app/components/utils.js +18 -0
  29. package/dist/app/components/welcome.vue +1 -1
  30. package/dist/app/composables/announcer.d.ts +23 -0
  31. package/dist/app/composables/announcer.js +47 -0
  32. package/dist/app/composables/asyncData.d.ts +24 -37
  33. package/dist/app/composables/asyncData.js +217 -184
  34. package/dist/app/composables/chunk.js +1 -2
  35. package/dist/app/composables/component.js +1 -2
  36. package/dist/app/composables/cookie.d.ts +14 -0
  37. package/dist/app/composables/cookie.js +68 -12
  38. package/dist/app/composables/error.d.ts +9 -6
  39. package/dist/app/composables/error.js +14 -1
  40. package/dist/app/composables/fetch.d.ts +11 -16
  41. package/dist/app/composables/fetch.js +79 -76
  42. package/dist/app/composables/index.d.ts +2 -0
  43. package/dist/app/composables/index.js +1 -0
  44. package/dist/app/composables/manifest.d.ts +4 -6
  45. package/dist/app/composables/manifest.js +6 -24
  46. package/dist/app/composables/pages.d.ts +2 -0
  47. package/dist/app/composables/pages.js +1 -0
  48. package/dist/app/composables/payload.d.ts +4 -0
  49. package/dist/app/composables/payload.js +44 -17
  50. package/dist/app/composables/preload.js +1 -1
  51. package/dist/app/composables/route-announcer.d.ts +2 -2
  52. package/dist/app/composables/route-announcer.js +6 -6
  53. package/dist/app/composables/router.d.ts +14 -3
  54. package/dist/app/composables/router.js +15 -6
  55. package/dist/app/composables/script-stubs.js +2 -2
  56. package/dist/app/composables/ssr.d.ts +2 -2
  57. package/dist/app/composables/ssr.js +1 -1
  58. package/dist/app/composables/state.d.ts +11 -1
  59. package/dist/app/composables/state.js +11 -2
  60. package/dist/app/composables/url.d.ts +1 -1
  61. package/dist/app/composables/url.js +1 -1
  62. package/dist/app/config.d.ts +1 -2
  63. package/dist/app/entry.async.d.ts +2 -2
  64. package/dist/app/entry.d.ts +3 -2
  65. package/dist/app/entry.js +2 -2
  66. package/dist/app/index.d.ts +3 -3
  67. package/dist/app/index.js +1 -1
  68. package/dist/app/middleware/{manifest-route-rule.js → route-rules.js} +2 -2
  69. package/dist/app/nuxt.d.ts +58 -40
  70. package/dist/app/nuxt.js +6 -2
  71. package/dist/app/plugins/dev-server-logs.js +1 -1
  72. package/dist/app/plugins/payload.client.js +0 -3
  73. package/dist/app/plugins/preload.server.js +3 -1
  74. package/dist/app/plugins/restore-state.client.js +1 -2
  75. package/dist/app/plugins/revive-payload.client.js +9 -3
  76. package/dist/app/plugins/router.js +17 -18
  77. package/dist/app/plugins/view-transitions.client.js +39 -4
  78. package/dist/app/types.d.ts +1 -1
  79. package/dist/app/utils.d.ts +6 -9
  80. package/dist/compiler/runtime/index.d.ts +14 -0
  81. package/dist/compiler/runtime/index.js +14 -0
  82. package/dist/components/runtime/lazy-hydrated-component.js +2 -1
  83. package/dist/components/runtime/server-component.js +0 -1
  84. package/dist/head/runtime/components.js +70 -26
  85. package/dist/index.d.mts +1 -1
  86. package/dist/index.d.ts +1 -1
  87. package/dist/index.mjs +2918 -1331
  88. package/dist/pages/runtime/composables.d.ts +10 -1
  89. package/dist/pages/runtime/index.d.ts +1 -1
  90. package/dist/pages/runtime/page.js +24 -24
  91. package/dist/pages/runtime/plugins/prerender.server.js +5 -10
  92. package/dist/pages/runtime/plugins/router.js +29 -20
  93. package/dist/pages/runtime/router.options.js +12 -6
  94. package/dist/pages/runtime/utils.d.ts +7 -0
  95. package/dist/pages/runtime/validate.js +4 -2
  96. package/meta.d.ts +1 -0
  97. package/meta.js +19 -0
  98. package/package.json +87 -66
  99. package/types.d.ts +1 -1
  100. /package/dist/app/middleware/{manifest-route-rule.d.ts → route-rules.d.ts} +0 -0
@@ -1,11 +1,13 @@
1
1
  import { Suspense, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, shallowReactive, shallowRef, unref } from "vue";
2
2
  import { useRoute, useRouter } from "../composables/router.js";
3
3
  import { useNuxtApp } from "../nuxt.js";
4
- import { _wrapInTransition } from "./utils.js";
4
+ import { _mergeTransitionProps, _wrapInTransition } from "./utils.js";
5
5
  import { LayoutMetaSymbol, PageRouteSymbol } from "./injections.js";
6
6
  import { useRoute as useVueRouterRoute } from "#build/pages";
7
7
  import layouts from "#build/layouts";
8
8
  import { appLayoutTransition as defaultLayoutTransition } from "#build/nuxt.config.mjs";
9
+ import _routeRulesMatcher from "#build/route-rules.mjs";
10
+ const routeRulesMatcher = _routeRulesMatcher;
9
11
  const LayoutLoader = defineComponent({
10
12
  name: "LayoutLoader",
11
13
  inheritAttrs: false,
@@ -37,7 +39,7 @@ export default defineComponent({
37
39
  const shouldUseEagerRoute = !injectedRoute || injectedRoute === useRoute();
38
40
  const route = shouldUseEagerRoute ? useVueRouterRoute() : injectedRoute;
39
41
  const layout = computed(() => {
40
- let layout2 = unref(props.name) ?? route?.meta.layout ?? "default";
42
+ let layout2 = unref(props.name) ?? route?.meta.layout ?? routeRulesMatcher(route?.path).appLayout ?? "default";
41
43
  if (layout2 && !(layout2 in layouts)) {
42
44
  if (import.meta.dev && layout2 !== "default") {
43
45
  console.warn(`Invalid layout \`${layout2}\` selected.`);
@@ -60,29 +62,52 @@ export default defineComponent({
60
62
  }
61
63
  let lastLayout;
62
64
  return () => {
63
- const hasLayout = layout.value && layout.value in layouts;
64
- const transitionProps = route?.meta.layoutTransition ?? defaultLayoutTransition;
65
+ const hasLayout = !!layout.value && layout.value in layouts;
66
+ const hasTransition = hasLayout && !!(route?.meta.layoutTransition ?? defaultLayoutTransition);
67
+ const transitionProps = hasTransition && _mergeTransitionProps([
68
+ route?.meta.layoutTransition,
69
+ defaultLayoutTransition,
70
+ {
71
+ onBeforeLeave() {
72
+ nuxtApp["~transitionPromise"] = new Promise((resolve) => {
73
+ nuxtApp["~transitionFinish"] = resolve;
74
+ });
75
+ },
76
+ onAfterLeave() {
77
+ nuxtApp["~transitionFinish"]?.();
78
+ delete nuxtApp["~transitionFinish"];
79
+ delete nuxtApp["~transitionPromise"];
80
+ }
81
+ }
82
+ ]);
65
83
  const previouslyRenderedLayout = lastLayout;
66
84
  lastLayout = layout.value;
67
- return _wrapInTransition(hasLayout && transitionProps, {
68
- default: () => h(Suspense, { suspensible: true, onResolve: () => {
69
- nextTick(done);
70
- } }, {
71
- default: () => h(
72
- LayoutProvider,
73
- {
74
- layoutProps: mergeProps(context.attrs, { ref: layoutRef }),
75
- key: layout.value || void 0,
76
- name: layout.value,
77
- shouldProvide: !props.name,
78
- isRenderingNewLayout: (name) => {
79
- return name !== previouslyRenderedLayout && name === layout.value;
85
+ return _wrapInTransition(transitionProps, {
86
+ default: () => h(
87
+ Suspense,
88
+ {
89
+ suspensible: true,
90
+ onResolve: async () => {
91
+ await nextTick(done);
92
+ }
93
+ },
94
+ {
95
+ default: () => h(
96
+ LayoutProvider,
97
+ {
98
+ layoutProps: mergeProps(context.attrs, route.meta.layoutProps ?? {}, { ref: layoutRef }),
99
+ key: layout.value || void 0,
100
+ name: layout.value,
101
+ shouldProvide: !props.name,
102
+ isRenderingNewLayout: (name) => {
103
+ return name !== previouslyRenderedLayout && name === layout.value;
104
+ },
105
+ hasTransition
80
106
  },
81
- hasTransition: !!transitionProps
82
- },
83
- context.slots
84
- )
85
- })
107
+ context.slots
108
+ )
109
+ }
110
+ )
86
111
  }).default();
87
112
  };
88
113
  }
@@ -112,7 +137,8 @@ const LayoutProvider = defineComponent({
112
137
  const name = props.name;
113
138
  if (props.shouldProvide) {
114
139
  provide(LayoutMetaSymbol, {
115
- isCurrent: (route) => name === (route.meta.layout ?? "default")
140
+ // When name=false, always return true so NuxtPage doesn't skip rendering
141
+ isCurrent: (route) => name === false || name === (route.meta.layout ?? routeRulesMatcher(route.path).appLayout ?? "default")
116
142
  });
117
143
  }
118
144
  const injectedRoute = inject(PageRouteSymbol);
@@ -1,12 +1,12 @@
1
- import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent, shallowRef } from "vue";
1
+ import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent, shallowRef, unref } from "vue";
2
2
  import { hasProtocol, joinURL, parseQuery, withTrailingSlash, withoutTrailingSlash } from "ufo";
3
3
  import { preloadRouteComponents } from "../composables/preload.js";
4
4
  import { onNuxtReady } from "../composables/ready.js";
5
- import { navigateTo, resolveRouteObject, useRouter } from "../composables/router.js";
5
+ import { encodeRoutePath, navigateTo, resolveRouteObject, useRouter } from "../composables/router.js";
6
6
  import { useNuxtApp, useRuntimeConfig } from "../nuxt.js";
7
7
  import { cancelIdleCallback, requestIdleCallback } from "../compat/idle-callback.js";
8
8
  import { nuxtLinkDefaults } from "#build/nuxt.config.mjs";
9
- import { hashMode } from "#build/router.options";
9
+ import { hashMode } from "#build/router.options.mjs";
10
10
  const firstNonUndefined = (...args) => args.find((arg) => arg !== void 0);
11
11
  const NuxtLinkDevKeySymbol = Symbol("nuxt-link-dev-key");
12
12
  // @__NO_SIDE_EFFECTS__
@@ -40,18 +40,18 @@ export function defineNuxtLink(options) {
40
40
  function useNuxtLink(props) {
41
41
  const router = useRouter();
42
42
  const config = useRuntimeConfig();
43
- const hasTarget = computed(() => !!props.target && props.target !== "_self");
43
+ const hasTarget = computed(() => !!unref(props.target) && unref(props.target) !== "_self");
44
44
  const isAbsoluteUrl = computed(() => {
45
- const path = props.to || props.href || "";
45
+ const path = unref(props.to) || unref(props.href) || "";
46
46
  return typeof path === "string" && hasProtocol(path, { acceptRelative: true });
47
47
  });
48
48
  const builtinRouterLink = resolveComponent("RouterLink");
49
49
  const useBuiltinLink = builtinRouterLink && typeof builtinRouterLink !== "string" ? builtinRouterLink.useLink : void 0;
50
50
  const isExternal = computed(() => {
51
- if (props.external) {
51
+ if (unref(props.external)) {
52
52
  return true;
53
53
  }
54
- const path = props.to || props.href || "";
54
+ const path = unref(props.to) || unref(props.href) || "";
55
55
  if (typeof path === "object") {
56
56
  return false;
57
57
  }
@@ -59,15 +59,15 @@ export function defineNuxtLink(options) {
59
59
  });
60
60
  const to = computed(() => {
61
61
  checkPropConflicts(props, "to", "href");
62
- const path = props.to || props.href || "";
62
+ const path = unref(props.to) || unref(props.href) || "";
63
63
  if (isExternal.value) {
64
64
  return path;
65
65
  }
66
- return resolveTrailingSlashBehavior(path, router.resolve, props.trailingSlash);
66
+ return resolveTrailingSlashBehavior(path, router.resolve, unref(props.trailingSlash));
67
67
  });
68
- const link = isExternal.value ? void 0 : useBuiltinLink?.({ ...props, to });
68
+ const link = isExternal.value ? void 0 : useBuiltinLink?.({ ...props, to, viewTransition: unref(props.viewTransition) });
69
69
  const href = computed(() => {
70
- const effectiveTrailingSlash = props.trailingSlash ?? options.trailingSlash;
70
+ const effectiveTrailingSlash = unref(props.trailingSlash) ?? options.trailingSlash;
71
71
  if (!to.value || isAbsoluteUrl.value || isHashLinkWithoutHashMode(to.value)) {
72
72
  return to.value;
73
73
  }
@@ -92,7 +92,7 @@ export function defineNuxtLink(options) {
92
92
  isExactActive: link?.isExactActive ?? computed(() => to.value === router.currentRoute.value.path),
93
93
  route: link?.route ?? computed(() => router.resolve(to.value)),
94
94
  async navigate(_e) {
95
- await navigateTo(href.value, { replace: props.replace, external: isExternal.value || hasTarget.value });
95
+ await navigateTo(href.value, { replace: unref(props.replace), external: isExternal.value || hasTarget.value });
96
96
  }
97
97
  };
98
98
  }
@@ -214,9 +214,9 @@ export function defineNuxtLink(options) {
214
214
  const path = typeof to.value === "string" ? to.value : isExternal.value ? resolveRouteObject(to.value) : router.resolve(to.value).fullPath;
215
215
  const normalizedPath = isExternal.value ? new URL(path, window.location.href).href : path;
216
216
  await Promise.all([
217
- nuxtApp.hooks.callHook("link:prefetch", normalizedPath).catch(() => {
217
+ nuxtApp.hooks.callHook("link:prefetch", normalizedPath)?.catch(() => {
218
218
  }),
219
- !isExternal.value && !hasTarget.value && preloadRouteComponents(to.value, router).catch(() => {
219
+ !import.meta.dev && !isExternal.value && !hasTarget.value && preloadRouteComponents(to.value, router).catch(() => {
220
220
  })
221
221
  ]);
222
222
  }
@@ -339,12 +339,26 @@ export function defineNuxtLink(options) {
339
339
  // converts `""` to `null` to prevent the attribute from being added as empty (`href=""`)
340
340
  rel,
341
341
  target,
342
- onClick: (event) => {
342
+ onClick: async (event) => {
343
343
  if (isExternal.value || hasTarget.value) {
344
344
  return;
345
345
  }
346
346
  event.preventDefault();
347
- return props.replace ? router.replace(href.value) : router.push(href.value);
347
+ try {
348
+ const encodedHref = encodeRoutePath(href.value);
349
+ return await (props.replace ? router.replace(encodedHref) : router.push(encodedHref));
350
+ } finally {
351
+ if (import.meta.client && isHashLinkWithoutHashMode(to.value)) {
352
+ const rawHash = to.value.slice(1);
353
+ let hash = rawHash;
354
+ try {
355
+ hash = decodeURIComponent(rawHash);
356
+ } catch {
357
+ }
358
+ const el2 = document.getElementById(hash);
359
+ el2?.focus();
360
+ }
361
+ }
348
362
  }
349
363
  }, slots.default?.());
350
364
  };
@@ -44,7 +44,7 @@ const error = useError();
44
44
  const abortRender = import.meta.server && error.value && !nuxtApp.ssrContext.error;
45
45
  const BOT_RE = /bot\b|chrome-lighthouse|facebookexternalhit|google\b/i;
46
46
  onErrorCaptured((err, target, info) => {
47
- nuxtApp.hooks.callHook("vue:error", err, target, info).catch((hookError) => console.error("[nuxt] Error in `vue:error` hook", hookError));
47
+ nuxtApp.hooks.callHook("vue:error", err, target, info)?.catch((hookError) => console.error("[nuxt] Error in `vue:error` hook", hookError));
48
48
  if (import.meta.client && BOT_RE.test(navigator.userAgent)) {
49
49
  nuxtApp.hooks.callHook("app:error", err);
50
50
  console.error(`[nuxt] Not rendering error page for bot with user agent \`${navigator.userAgent}\`:`, err);
@@ -1,4 +1,4 @@
1
- import { defineComponent, h } from "vue";
1
+ import { computed, defineComponent, h } from "vue";
2
2
  import { useRouteAnnouncer } from "../composables/route-announcer.js";
3
3
  export default defineComponent({
4
4
  name: "NuxtRouteAnnouncer",
@@ -14,6 +14,15 @@ export default defineComponent({
14
14
  },
15
15
  setup(props, { slots, expose }) {
16
16
  const { set, polite, assertive, message, politeness } = useRouteAnnouncer({ politeness: props.politeness });
17
+ const role = computed(() => {
18
+ if (politeness.value === "assertive") {
19
+ return "alert";
20
+ }
21
+ if (politeness.value === "off") {
22
+ return void 0;
23
+ }
24
+ return "status";
25
+ });
17
26
  expose({
18
27
  set,
19
28
  polite,
@@ -27,7 +36,7 @@ export default defineComponent({
27
36
  position: "absolute"
28
37
  }
29
38
  }, h("span", {
30
- "role": "alert",
39
+ "role": role.value,
31
40
  "aria-live": politeness.value,
32
41
  "aria-atomic": props.atomic,
33
42
  "style": {
@@ -1,6 +1,6 @@
1
1
  export declare const NuxtImg: {
2
- setup: () => void;
2
+ setup: () => never;
3
3
  };
4
4
  export declare const NuxtPicture: {
5
- setup: () => void;
5
+ setup: () => never;
6
6
  };
@@ -2,8 +2,8 @@ import { createError } from "../composables/error.js";
2
2
  function renderStubMessage(name) {
3
3
  throw createError({
4
4
  fatal: true,
5
- statusCode: 500,
6
- statusMessage: `${name} is provided by @nuxt/image. Check your console to install it or run 'npx nuxt module add @nuxt/image'`
5
+ status: 500,
6
+ statusText: `${name} is provided by @nuxt/image. Check your console to install it or run 'npx nuxt module add @nuxt/image'`
7
7
  });
8
8
  }
9
9
  export const NuxtImg = {
@@ -59,6 +59,9 @@ const formatter = computed(() => {
59
59
  return new Intl.DateTimeFormat(_locale ?? propsLocale, rest);
60
60
  });
61
61
  const formattedDate = computed(() => {
62
+ if (isInvalidDate.value) {
63
+ return date.value.toString();
64
+ }
62
65
  if (!props.relative) {
63
66
  return formatter.value.format(date.value);
64
67
  }
@@ -80,7 +83,8 @@ const formattedDate = computed(() => {
80
83
  const value = diffInSeconds / seconds;
81
84
  return formatter.value.format(Math.round(value), unit);
82
85
  });
83
- const isoDate = computed(() => date.value.toISOString());
86
+ const isInvalidDate = computed(() => Number.isNaN(date.value.getTime()));
87
+ const isoDate = computed(() => isInvalidDate.value ? void 0 : date.value.toISOString());
84
88
  const title = computed(() => props.title === true ? isoDate.value : typeof props.title === "string" ? props.title : void 0);
85
89
  const dataset = {};
86
90
  if (import.meta.server) {
@@ -101,7 +105,14 @@ if (import.meta.server) {
101
105
  }
102
106
  return name;
103
107
  };
104
- const date2 = new Date(el2.getAttribute("datetime"));
108
+ const datetime = el2.getAttribute("datetime");
109
+ if (!datetime) {
110
+ return;
111
+ }
112
+ const date2 = new Date(datetime);
113
+ if (Number.isNaN(date2.getTime())) {
114
+ return;
115
+ }
105
116
  const options = {};
106
117
  for (const name of el2.getAttributeNames()) {
107
118
  if (name.startsWith("data-")) {
@@ -1,14 +1,22 @@
1
1
  import { defineComponent, h } from "vue";
2
2
  import { parseQuery } from "vue-router";
3
3
  import { resolve } from "pathe";
4
- import destr from "destr";
5
4
  import { devRootDir } from "#build/nuxt.config.mjs";
6
5
  export default (url) => defineComponent({
7
6
  name: "NuxtTestComponentWrapper",
8
7
  inheritAttrs: false,
9
8
  async setup(props, { attrs }) {
10
9
  const query = parseQuery(new URL(url, "http://localhost").search);
11
- const urlProps = query.props ? destr(query.props) : {};
10
+ let urlProps = {};
11
+ if (query.props) {
12
+ try {
13
+ const parsedProps = JSON.parse(query.props);
14
+ if (parsedProps && typeof parsedProps === "object") {
15
+ urlProps = parsedProps;
16
+ }
17
+ } catch {
18
+ }
19
+ }
12
20
  const path = resolve(query.path);
13
21
  if (!path.startsWith(devRootDir)) {
14
22
  throw new Error(`[nuxt] Cannot access path outside of project root directory: \`${path}\`.`);
@@ -1,4 +1,4 @@
1
- import type { RendererNode, VNode } from 'vue';
1
+ import type { RendererNode, TransitionProps, VNode } from 'vue';
2
2
  import type { RouteLocationNormalized } from 'vue-router';
3
3
  /**
4
4
  * Internal utility
@@ -46,3 +46,9 @@ export declare function getFragmentHTML(element: RendererNode | null, withoutSlo
46
46
  export declare function elToStaticVNode(el: RendererNode | null, staticNodeFallback?: string): VNode;
47
47
  export declare function isStartFragment(element: RendererNode): boolean;
48
48
  export declare function isEndFragment(element: RendererNode): boolean;
49
+ export declare function toArray<T>(value: T | T[]): T[];
50
+ /**
51
+ * Internal utility
52
+ * @private
53
+ */
54
+ export declare function _mergeTransitionProps(routeProps: TransitionProps[]): TransitionProps;
@@ -1,4 +1,5 @@
1
1
  import { Transition, createStaticVNode, h } from "vue";
2
+ import { defu } from "defu";
2
3
  import { isString, isPromise, isArray, isObject } from "@vue/shared";
3
4
  import { START_LOCATION } from "#build/pages";
4
5
  export const _wrapInTransition = (props, children) => {
@@ -124,3 +125,20 @@ export function isStartFragment(element) {
124
125
  export function isEndFragment(element) {
125
126
  return element.nodeName === "#comment" && element.nodeValue === "]";
126
127
  }
128
+ export function toArray(value) {
129
+ return Array.isArray(value) ? value : [value];
130
+ }
131
+ export function _mergeTransitionProps(routeProps) {
132
+ const _props = [];
133
+ for (const prop of routeProps) {
134
+ if (!prop) {
135
+ continue;
136
+ }
137
+ _props.push({
138
+ ...prop,
139
+ onAfterLeave: prop.onAfterLeave ? toArray(prop.onAfterLeave) : void 0,
140
+ onBeforeLeave: prop.onBeforeLeave ? toArray(prop.onBeforeLeave) : void 0
141
+ });
142
+ }
143
+ return defu(..._props);
144
+ }
@@ -26,7 +26,7 @@ useHead({
26
26
  </script>
27
27
 
28
28
  <template>
29
- <div class="antialiased bg-white dark:bg-[#020420] dark:text-white flex flex-col items-center justify-center min-h-screen place-content-center sm:text-base text-[#020420] text-sm"><div class="flex flex-col mt-6 sm:mt-0"><h1 class="flex flex-col gap-y-4 items-center justify-center"><a href="https://nuxt.com?utm_source=nuxt-welcome" target="_blank" class="gap-4 inline-flex items-end"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" aria-label="Nuxt" class="h-8 sm:h-12" viewBox="0 0 800 200"><path fill="#00dc82" d="M168.303 200h111.522c3.543 0 7.022-.924 10.09-2.679A20.1 20.1 0 0 0 297.3 190a19.86 19.86 0 0 0 2.7-10.001 19.86 19.86 0 0 0-2.709-9.998L222.396 41.429a20.1 20.1 0 0 0-7.384-7.32 20.3 20.3 0 0 0-10.088-2.679c-3.541 0-7.02.925-10.087 2.68a20.1 20.1 0 0 0-7.384 7.32l-19.15 32.896L130.86 9.998a20.1 20.1 0 0 0-7.387-7.32A20.3 20.3 0 0 0 113.384 0c-3.542 0-7.022.924-10.09 2.679a20.1 20.1 0 0 0-7.387 7.319L2.709 170A19.85 19.85 0 0 0 0 179.999c-.002 3.511.93 6.96 2.7 10.001a20.1 20.1 0 0 0 7.385 7.321A20.3 20.3 0 0 0 20.175 200h70.004c27.737 0 48.192-12.075 62.266-35.633l34.171-58.652 18.303-31.389 54.93 94.285h-73.233zm-79.265-31.421-48.854-.011 73.232-125.706 36.541 62.853-24.466 42.01c-9.347 15.285-19.965 20.854-36.453 20.854"/><path fill="currentColor" d="M377 200a4 4 0 0 0 4-4v-93s5.244 8.286 15 25l38.707 66.961c1.789 3.119 5.084 5.039 8.649 5.039H470V50h-27a4 4 0 0 0-4 4v94l-17-30-36.588-62.98c-1.792-3.108-5.081-5.02-8.639-5.02H350v150zm299.203-56.143L710.551 92h-25.73a9.97 9.97 0 0 0-8.333 4.522L660.757 120.5l-15.731-23.978A9.97 9.97 0 0 0 636.693 92h-25.527l34.348 51.643L608.524 200h24.966a9.97 9.97 0 0 0 8.29-4.458l19.18-28.756 18.981 28.72a9.97 9.97 0 0 0 8.313 4.494h24.736zM724.598 92h19.714V60.071h28.251V92H800v24.857h-27.437V159.5c0 10.5 5.284 15.429 14.43 15.429H800V200h-16.869c-23.576 0-38.819-14.143-38.819-39.214v-43.929h-19.714zM590 92h-15c-3.489 0-6.218.145-8.5 2.523-2.282 2.246-2.5 3.63-2.5 7.066v52.486c0 8.058-.376 12.962-4 16.925-3.624 3.831-8.619 5-16 5-7.247 0-12.376-1.169-16-5-3.624-3.963-4-8.867-4-16.925v-52.486c0-3.435-.218-4.82-2.5-7.066C519.218 92.145 516.489 92 513 92h-15v62.422q0 21.006 11.676 33.292C517.594 195.905 529.103 200 544 200s26.204-4.095 34.123-12.286Q590 175.428 590 154.422z"/></svg> <span class="bg-[#00DC42]/10 border border-[#00DC42]/50 font-mono font-semibold group-hover:bg-[#00DC42]/15 group-hover:border-[#00DC42] inline-block leading-none px-2 py-1 rounded sm:px-2.5 sm:py-1.5 sm:text-[14px] text-[#00DC82] text-[12px]">4.2.2</span> </a></h1><div class="gap-4 grid grid-cols-1 max-w-[980px] mt-6 px-4 sm:gap-6 sm:grid-cols-3 sm:mt-10 w-full"><div class="bg-gray-50/10 border border-[#00DC42]/50 dark:bg-white/5 flex flex-col gap-1 p-6 rounded-lg sm:col-span-2"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/80 dark:text-[#00DC82] flex h-[32px] items-center justify-center rounded text-[#00DC82] w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-[18px]" viewBox="0 0 256 256"><path fill="currentColor" d="m228.1 121.2-143.9-88A8 8 0 0 0 72 40v176a8 8 0 0 0 12.2 6.8l143.9-88a7.9 7.9 0 0 0 0-13.6" opacity=".2"/><path fill="currentColor" d="M80 232a15.5 15.5 0 0 1-7.8-2.1A15.8 15.8 0 0 1 64 216V40a15.8 15.8 0 0 1 8.2-13.9 15.5 15.5 0 0 1 16.1.3l144 87.9a16 16 0 0 1 0 27.4l-144 87.9A15.4 15.4 0 0 1 80 232m0-192v176l144-88Z"/></svg></div><h2 class="font-semibold mt-1 text-base">Get started</h2><p class="dark:text-gray-200 text-gray-700 text-sm">Remove this welcome page by replacing <a class="bg-green-50 border border-green-600/10 dark:bg-[#020420] dark:border-white/10 dark:text-[#00DC82] font-bold font-mono p-1 rounded text-green-700">&lt;NuxtWelcome/&gt;</a> in <a href="https://nuxt.com/docs/4.x/directory-structure/app" target="_blank" rel="noopener" class="bg-green-50 border border-green-600/20 dark:bg-[#020420] dark:border-white/20 dark:text-[#00DC82] font-bold font-mono hover:border-[#00DC82] p-1 rounded text-green-700">app.vue</a> with your own code.</p></div><a href="https://nuxt.com/docs?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"> <div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M136 48v128H88V80H40V48a8 8 0 0 1 8-8h32a8 8 0 0 1 8 8 8 8 0 0 1 8-8h32a8 8 0 0 1 8 8m89.9 149.6-8.3-30.9-46.4 12.5 8.3 30.9a8 8 0 0 0 9.8 5.6l30.9-8.3a8 8 0 0 0 5.7-9.8M184.5 43.1a8.1 8.1 0 0 0-9.8-5.7l-30.9 8.3a8.1 8.1 0 0 0-5.7 9.8l8.3 30.9L192.8 74Z" opacity=".2"/><path fill="currentColor" d="M233.6 195.6 192.2 41a16 16 0 0 0-19.6-11.3L141.7 38l-1 .3A16 16 0 0 0 128 32H96a15.8 15.8 0 0 0-8 2.2 15.8 15.8 0 0 0-8-2.2H48a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h32a15.8 15.8 0 0 0 8-2.2 15.8 15.8 0 0 0 8 2.2h32a16 16 0 0 0 16-16v-99.6l27.8 103.7a16 16 0 0 0 15.5 11.9 20 20 0 0 0 4.1-.5l30.9-8.3a16 16 0 0 0 11.3-19.6M156.2 92.1l30.9-8.3 20.7 77.3-30.9 8.3Zm20.5-46.9 6.3 23.1-30.9 8.3-6.3-23.1ZM128 48v120H96V48Zm-48 0v24H48V48ZM48 208V88h32v120Zm80 0H96v-24h32zm90.2-8.3-30.9 8.3-6.3-23.2 31-8.3z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Documentation</h2> <p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">We highly recommend you take a look at the Nuxt documentation to level up.</p> </a></div><div class="gap-4 grid grid-cols-1 max-w-[980px] mt-4 px-4 sm:gap-6 sm:grid-cols-3 sm:mt-6 w-full"><a href="https://nuxt.com/modules?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"> <div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M64 216a8 8 0 0 1-8-8v-42.7a27.6 27.6 0 0 1-14.1 2.6A28 28 0 1 1 56 114.7V72a8 8 0 0 1 8-8h46.7a27.6 27.6 0 0 1-2.6-14.1A28 28 0 1 1 161.3 64H208a8 8 0 0 1 8 8v42.7a27.6 27.6 0 0 0-14.1-2.6 28 28 0 1 0 14.1 53.2V208a8 8 0 0 1-8 8Z" opacity=".2"/><path fill="currentColor" d="M220.3 158.5a8.1 8.1 0 0 0-7.7-.4 20.2 20.2 0 0 1-23.2-4.4 20 20 0 0 1 13.1-33.6 19.6 19.6 0 0 1 10.1 1.8 8.1 8.1 0 0 0 7.7-.4 8.2 8.2 0 0 0 3.7-6.8V72a16 16 0 0 0-16-16h-36.2c.1-1.3.2-2.7.2-4a36.1 36.1 0 0 0-38.3-35.9 36 36 0 0 0-33.6 33.3 36.4 36.4 0 0 0 .1 6.6H64a16 16 0 0 0-16 16v32.2l-4-.2a35.6 35.6 0 0 0-26.2 11.4 35.3 35.3 0 0 0-9.7 26.9 36 36 0 0 0 33.3 33.6 36.4 36.4 0 0 0 6.6-.1V208a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16v-42.7a8.2 8.2 0 0 0-3.7-6.8M208 208H64v-42.7a8.2 8.2 0 0 0-3.7-6.8 8.1 8.1 0 0 0-7.7-.4 19.6 19.6 0 0 1-10.1 1.8 20 20 0 0 1-13.1-33.6 20.2 20.2 0 0 1 23.2-4.4 8.1 8.1 0 0 0 7.7-.4 8.2 8.2 0 0 0 3.7-6.8V72h46.7a8.2 8.2 0 0 0 6.8-3.7 8.1 8.1 0 0 0 .4-7.7 19.6 19.6 0 0 1-1.8-10.1 20 20 0 0 1 33.6-13.1 20.2 20.2 0 0 1 4.4 23.2 8.1 8.1 0 0 0 .4 7.7 8.2 8.2 0 0 0 6.8 3.7H208v32.2a36.4 36.4 0 0 0-6.6-.1 36 36 0 0 0-33.3 33.6A36.1 36.1 0 0 0 204 176l4-.2Z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Modules</h2> <p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Discover our list of modules to supercharge your Nuxt project.</p> </a> <a href="https://nuxt.com/docs/4.x/examples?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M224 56v144a8 8 0 0 1-8 8H40a8 8 0 0 1-8-8V56a8 8 0 0 1 8-8h176a8 8 0 0 1 8 8" opacity=".2"/><path fill="currentColor" d="M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 160H40V56h176zM80 84a12 12 0 1 1-12-12 12 12 0 0 1 12 12m40 0a12 12 0 1 1-12-12 12 12 0 0 1 12 12"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Examples</h2> <p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Explore different way of using Nuxt features and get inspired.</p> </a> <a href="https://nuxt.com/deploy?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256"><path fill="currentColor" d="M94.1 184.6c-11.4 33.9-56.6 33.9-56.6 33.9s0-45.2 33.9-56.6Zm90.5-67.9v64.6a8 8 0 0 1-2.4 5.6l-32.3 32.4a8 8 0 0 1-13.5-4.1l-8.4-41.9Zm-45.3-45.3H74.7a8 8 0 0 0-5.6 2.4l-32.4 32.3a8 8 0 0 0 4.1 13.5l41.9 8.4Z" opacity=".2"/><path fill="currentColor" d="M96.6 177a7.9 7.9 0 0 0-10.1 5c-6.6 19.7-27.9 25.8-40.2 27.7 1.9-12.3 8-33.6 27.7-40.2a8 8 0 1 0-5.1-15.1c-16.4 5.4-28.4 18.4-34.8 37.5a91.8 91.8 0 0 0-4.6 26.6 8 8 0 0 0 8 8 91.8 91.8 0 0 0 26.6-4.6c19.1-6.4 32.1-18.4 37.5-34.8a7.9 7.9 0 0 0-5-10.1"/><path fill="currentColor" d="M227.6 41.8a15.7 15.7 0 0 0-13.4-13.4c-11.3-1.7-40.6-2.5-69.2 26.1l-9 8.9H74.7a16.2 16.2 0 0 0-11.3 4.7l-32.3 32.4a15.9 15.9 0 0 0-4 15.9 16 16 0 0 0 12.2 11.1l39.5 7.9 41.8 41.8 7.9 39.5a16 16 0 0 0 11.1 12.2 14.7 14.7 0 0 0 4.6.7 15.6 15.6 0 0 0 11.3-4.7l32.4-32.3a16.2 16.2 0 0 0 4.7-11.3V120l8.9-9c28.6-28.6 27.8-57.9 26.1-69.2M74.7 79.4H120l-39.9 39.9-37.7-7.5Zm81.6-13.6c7.8-7.8 28.8-25.6 55.5-21.6 4 26.7-13.8 47.7-21.6 55.5L128 161.9 94.1 128Zm20.3 115.5-32.4 32.3-7.5-37.7 39.9-39.9Z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Deploy</h2> <p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Learn how to deploy your Nuxt project on different providers.</p> </a></div><footer class="lg:px-8 mb-6 mt-6 mx-auto px-4 sm:mb-0 sm:mt-10 sm:px-6 w-full"><ul class="flex gap-4 items-center justify-center"><li><a href="https://go.nuxt.com/github" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt GitHub Repository</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg> </a></li><li><a href="https://go.nuxt.com/discord" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Discord Server</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0 13 13 0 0 0-.617-1.25.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.08.08 0 0 0 .084-.028 14 14 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13 13 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10 10 0 0 0 .372-.292.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127 12.3 12.3 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028 19.8 19.8 0 0 0 6.002-3.03.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418"/></svg> </a></li><li><a href="https://go.nuxt.com/x" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt on X</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg> </a></li><li><a href="https://go.nuxt.com/bluesky" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Bluesky</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364q.204-.03.415-.056-.207.033-.415.056c-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a9 9 0 0 1-.415-.056q.21.026.415.056c2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8"/></svg> </a></li><li><a href="https://go.nuxt.com/linkedin" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Linkedin</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z"/></svg> </a></li></ul></footer></div></div>
29
+ <div class="antialiased bg-white dark:bg-[#020420] dark:text-white flex flex-col items-center justify-center min-h-screen place-content-center sm:text-base text-[#020420] text-sm"><div class="flex flex-col mt-6 sm:mt-0"><h1 class="flex flex-col gap-y-4 items-center justify-center"><a href="https://nuxt.com?utm_source=nuxt-welcome" target="_blank" class="gap-4 inline-flex items-end"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" aria-label="Nuxt" class="h-8 sm:h-12" viewBox="0 0 800 200"><path fill="#00dc82" d="M168.303 200h111.522c3.543 0 7.022-.924 10.09-2.679A20.1 20.1 0 0 0 297.3 190a19.86 19.86 0 0 0 2.7-10.001 19.86 19.86 0 0 0-2.709-9.998L222.396 41.429a20.1 20.1 0 0 0-7.384-7.32 20.3 20.3 0 0 0-10.088-2.679c-3.541 0-7.02.925-10.087 2.68a20.1 20.1 0 0 0-7.384 7.32l-19.15 32.896L130.86 9.998a20.1 20.1 0 0 0-7.387-7.32A20.3 20.3 0 0 0 113.384 0c-3.542 0-7.022.924-10.09 2.679a20.1 20.1 0 0 0-7.387 7.319L2.709 170A19.85 19.85 0 0 0 0 179.999c-.002 3.511.93 6.96 2.7 10.001a20.1 20.1 0 0 0 7.385 7.321A20.3 20.3 0 0 0 20.175 200h70.004c27.737 0 48.192-12.075 62.266-35.633l34.171-58.652 18.303-31.389 54.93 94.285h-73.233zm-79.265-31.421-48.854-.011 73.232-125.706 36.541 62.853-24.466 42.01c-9.347 15.285-19.965 20.854-36.453 20.854"/><path fill="currentColor" d="M377 200a4 4 0 0 0 4-4v-93s5.244 8.286 15 25l38.707 66.961c1.789 3.119 5.084 5.039 8.649 5.039H470V50h-27a4 4 0 0 0-4 4v94l-17-30-36.588-62.98c-1.792-3.108-5.081-5.02-8.639-5.02H350v150zm299.203-56.143L710.551 92h-25.73a9.97 9.97 0 0 0-8.333 4.522L660.757 120.5l-15.731-23.978A9.97 9.97 0 0 0 636.693 92h-25.527l34.348 51.643L608.524 200h24.966a9.97 9.97 0 0 0 8.29-4.458l19.18-28.756 18.981 28.72a9.97 9.97 0 0 0 8.313 4.494h24.736zM724.598 92h19.714V60.071h28.251V92H800v24.857h-27.437V159.5c0 10.5 5.284 15.429 14.43 15.429H800V200h-16.869c-23.576 0-38.819-14.143-38.819-39.214v-43.929h-19.714zM590 92h-15c-3.489 0-6.218.145-8.5 2.523-2.282 2.246-2.5 3.63-2.5 7.066v52.486c0 8.058-.376 12.962-4 16.925-3.624 3.831-8.619 5-16 5-7.247 0-12.376-1.169-16-5-3.624-3.963-4-8.867-4-16.925v-52.486c0-3.435-.218-4.82-2.5-7.066C519.218 92.145 516.489 92 513 92h-15v62.422q0 21.006 11.676 33.292C517.594 195.905 529.103 200 544 200s26.204-4.095 34.123-12.286Q590 175.428 590 154.422z"/></svg> <span class="bg-[#00DC42]/10 border border-[#00DC42]/50 font-mono font-semibold group-hover:bg-[#00DC42]/15 group-hover:border-[#00DC42] inline-block leading-none px-2 py-1 rounded sm:px-2.5 sm:py-1.5 sm:text-[14px] text-[#00DC82] text-[12px]">4.4.2</span> </a></h1><div class="gap-4 grid grid-cols-1 max-w-[980px] mt-6 px-4 sm:gap-6 sm:grid-cols-3 sm:mt-10 w-full"><div class="bg-gray-50/10 border border-[#00DC42]/50 dark:bg-white/5 flex flex-col gap-1 p-6 rounded-lg sm:col-span-2"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/80 dark:text-[#00DC82] flex h-[32px] items-center justify-center rounded text-[#00DC82] w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-[18px]" viewBox="0 0 256 256"><path fill="currentColor" d="m228.1 121.2-143.9-88A8 8 0 0 0 72 40v176a8 8 0 0 0 12.2 6.8l143.9-88a7.9 7.9 0 0 0 0-13.6" opacity=".2"/><path fill="currentColor" d="M80 232a15.5 15.5 0 0 1-7.8-2.1A15.8 15.8 0 0 1 64 216V40a15.8 15.8 0 0 1 8.2-13.9 15.5 15.5 0 0 1 16.1.3l144 87.9a16 16 0 0 1 0 27.4l-144 87.9A15.4 15.4 0 0 1 80 232m0-192v176l144-88Z"/></svg></div><h2 class="font-semibold mt-1 text-base">Get started</h2><p class="dark:text-gray-200 text-gray-700 text-sm">Remove this welcome page by replacing <a class="bg-green-50 border border-green-600/10 dark:bg-[#020420] dark:border-white/10 dark:text-[#00DC82] font-bold font-mono p-1 rounded text-green-700">&lt;NuxtWelcome/&gt;</a> in <a href="https://nuxt.com/docs/4.x/directory-structure/app" target="_blank" rel="noopener" class="bg-green-50 border border-green-600/20 dark:bg-[#020420] dark:border-white/20 dark:text-[#00DC82] font-bold font-mono hover:border-[#00DC82] p-1 rounded text-green-700">app.vue</a> with your own code.</p></div><a href="https://nuxt.com/docs?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M136 48v128H88V80H40V48a8 8 0 0 1 8-8h32a8 8 0 0 1 8 8 8 8 0 0 1 8-8h32a8 8 0 0 1 8 8m89.9 149.6-8.3-30.9-46.4 12.5 8.3 30.9a8 8 0 0 0 9.8 5.6l30.9-8.3a8 8 0 0 0 5.7-9.8M184.5 43.1a8.1 8.1 0 0 0-9.8-5.7l-30.9 8.3a8.1 8.1 0 0 0-5.7 9.8l8.3 30.9L192.8 74Z" opacity=".2"/><path fill="currentColor" d="M233.6 195.6 192.2 41a16 16 0 0 0-19.6-11.3L141.7 38l-1 .3A16 16 0 0 0 128 32H96a15.8 15.8 0 0 0-8 2.2 15.8 15.8 0 0 0-8-2.2H48a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h32a15.8 15.8 0 0 0 8-2.2 15.8 15.8 0 0 0 8 2.2h32a16 16 0 0 0 16-16v-99.6l27.8 103.7a16 16 0 0 0 15.5 11.9 20 20 0 0 0 4.1-.5l30.9-8.3a16 16 0 0 0 11.3-19.6M156.2 92.1l30.9-8.3 20.7 77.3-30.9 8.3Zm20.5-46.9 6.3 23.1-30.9 8.3-6.3-23.1ZM128 48v120H96V48Zm-48 0v24H48V48ZM48 208V88h32v120Zm80 0H96v-24h32zm90.2-8.3-30.9 8.3-6.3-23.2 31-8.3z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Documentation</h2><p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">We highly recommend you take a look at the Nuxt documentation to level up.</p></a></div><div class="gap-4 grid grid-cols-1 max-w-[980px] mt-4 px-4 sm:gap-6 sm:grid-cols-3 sm:mt-6 w-full"><a href="https://nuxt.com/modules?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M64 216a8 8 0 0 1-8-8v-42.7a27.6 27.6 0 0 1-14.1 2.6A28 28 0 1 1 56 114.7V72a8 8 0 0 1 8-8h46.7a27.6 27.6 0 0 1-2.6-14.1A28 28 0 1 1 161.3 64H208a8 8 0 0 1 8 8v42.7a27.6 27.6 0 0 0-14.1-2.6 28 28 0 1 0 14.1 53.2V208a8 8 0 0 1-8 8Z" opacity=".2"/><path fill="currentColor" d="M220.3 158.5a8.1 8.1 0 0 0-7.7-.4 20.2 20.2 0 0 1-23.2-4.4 20 20 0 0 1 13.1-33.6 19.6 19.6 0 0 1 10.1 1.8 8.1 8.1 0 0 0 7.7-.4 8.2 8.2 0 0 0 3.7-6.8V72a16 16 0 0 0-16-16h-36.2c.1-1.3.2-2.7.2-4a36.1 36.1 0 0 0-38.3-35.9 36 36 0 0 0-33.6 33.3 36.4 36.4 0 0 0 .1 6.6H64a16 16 0 0 0-16 16v32.2l-4-.2a35.6 35.6 0 0 0-26.2 11.4 35.3 35.3 0 0 0-9.7 26.9 36 36 0 0 0 33.3 33.6 36.4 36.4 0 0 0 6.6-.1V208a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16v-42.7a8.2 8.2 0 0 0-3.7-6.8M208 208H64v-42.7a8.2 8.2 0 0 0-3.7-6.8 8.1 8.1 0 0 0-7.7-.4 19.6 19.6 0 0 1-10.1 1.8 20 20 0 0 1-13.1-33.6 20.2 20.2 0 0 1 23.2-4.4 8.1 8.1 0 0 0 7.7-.4 8.2 8.2 0 0 0 3.7-6.8V72h46.7a8.2 8.2 0 0 0 6.8-3.7 8.1 8.1 0 0 0 .4-7.7 19.6 19.6 0 0 1-1.8-10.1 20 20 0 0 1 33.6-13.1 20.2 20.2 0 0 1 4.4 23.2 8.1 8.1 0 0 0 .4 7.7 8.2 8.2 0 0 0 6.8 3.7H208v32.2a36.4 36.4 0 0 0-6.6-.1 36 36 0 0 0-33.3 33.6A36.1 36.1 0 0 0 204 176l4-.2Z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Modules</h2><p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Discover our list of modules to supercharge your Nuxt project.</p></a> <a href="https://nuxt.com/docs/4.x/examples?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 256 256"><path fill="currentColor" d="M224 56v144a8 8 0 0 1-8 8H40a8 8 0 0 1-8-8V56a8 8 0 0 1 8-8h176a8 8 0 0 1 8 8" opacity=".2"/><path fill="currentColor" d="M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 160H40V56h176zM80 84a12 12 0 1 1-12-12 12 12 0 0 1 12 12m40 0a12 12 0 1 1-12-12 12 12 0 0 1 12 12"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Examples</h2><p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Explore different way of using Nuxt features and get inspired.</p></a> <a href="https://nuxt.com/deploy?utm_source=nuxt-welcome" target="_blank" class="bg-gray-50/10 border border-gray-200 dark:bg-white/5 dark:border-white/10 flex flex-col gap-1 group hover:border-[#00DC82] hover:dark:border-[#00DC82] p-6 relative rounded-lg transition-all"><div class="bg-[#00DC82]/5 border border-[#00DC82] dark:bg-[#020420] dark:border-[#00DC82]/50 dark:text-[#00DC82] flex group-hover:dark:border-[#00DC82]/80 h-[32px] items-center justify-center rounded text-[#00DC82] transition-all w-[32px]"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256"><path fill="currentColor" d="M94.1 184.6c-11.4 33.9-56.6 33.9-56.6 33.9s0-45.2 33.9-56.6Zm90.5-67.9v64.6a8 8 0 0 1-2.4 5.6l-32.3 32.4a8 8 0 0 1-13.5-4.1l-8.4-41.9Zm-45.3-45.3H74.7a8 8 0 0 0-5.6 2.4l-32.4 32.3a8 8 0 0 0 4.1 13.5l41.9 8.4Z" opacity=".2"/><path fill="currentColor" d="M96.6 177a7.9 7.9 0 0 0-10.1 5c-6.6 19.7-27.9 25.8-40.2 27.7 1.9-12.3 8-33.6 27.7-40.2a8 8 0 1 0-5.1-15.1c-16.4 5.4-28.4 18.4-34.8 37.5a91.8 91.8 0 0 0-4.6 26.6 8 8 0 0 0 8 8 91.8 91.8 0 0 0 26.6-4.6c19.1-6.4 32.1-18.4 37.5-34.8a7.9 7.9 0 0 0-5-10.1"/><path fill="currentColor" d="M227.6 41.8a15.7 15.7 0 0 0-13.4-13.4c-11.3-1.7-40.6-2.5-69.2 26.1l-9 8.9H74.7a16.2 16.2 0 0 0-11.3 4.7l-32.3 32.4a15.9 15.9 0 0 0-4 15.9 16 16 0 0 0 12.2 11.1l39.5 7.9 41.8 41.8 7.9 39.5a16 16 0 0 0 11.1 12.2 14.7 14.7 0 0 0 4.6.7 15.6 15.6 0 0 0 11.3-4.7l32.4-32.3a16.2 16.2 0 0 0 4.7-11.3V120l8.9-9c28.6-28.6 27.8-57.9 26.1-69.2M74.7 79.4H120l-39.9 39.9-37.7-7.5Zm81.6-13.6c7.8-7.8 28.8-25.6 55.5-21.6 4 26.7-13.8 47.7-21.6 55.5L128 161.9 94.1 128Zm20.3 115.5-32.4 32.3-7.5-37.7 39.9-39.9Z"/></svg></div> <svg xmlns="http://www.w3.org/2000/svg" class="absolute dark:text-white/40 group-hover:size-5 group-hover:text-[#00DC82] right-4 size-4 text-[#020420]/20 top-4 transition-all" viewBox="0 0 256 256"><path fill="currentColor" d="M200 64v104a8 8 0 0 1-16 0V83.3L69.7 197.7a8.2 8.2 0 0 1-11.4 0 8.1 8.1 0 0 1 0-11.4L172.7 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8"/></svg> <h2 class="font-semibold mt-1 text-base">Deploy</h2><p class="dark:text-gray-200 group-hover:dark:text-gray-100 text-gray-700 text-sm">Learn how to deploy your Nuxt project on different providers.</p></a></div><footer class="lg:px-8 mb-6 mt-6 mx-auto px-4 sm:mb-0 sm:mt-10 sm:px-6 w-full"><ul class="flex gap-4 items-center justify-center"><li><a href="https://go.nuxt.com/github" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt GitHub Repository</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg> </a></li><li><a href="https://go.nuxt.com/discord" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Discord Server</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0 13 13 0 0 0-.617-1.25.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.08.08 0 0 0 .084-.028 14 14 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13 13 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10 10 0 0 0 .372-.292.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127 12.3 12.3 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028 19.8 19.8 0 0 0 6.002-3.03.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418"/></svg> </a></li><li><a href="https://go.nuxt.com/x" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt on X</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg> </a></li><li><a href="https://go.nuxt.com/bluesky" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Bluesky</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364q.204-.03.415-.056-.207.033-.415.056c-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a9 9 0 0 1-.415-.056q.21.026.415.056c2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8"/></svg> </a></li><li><a href="https://go.nuxt.com/linkedin" target="_blank" class="dark:hover:text-white dark:text-gray-400 focus-visible:ring-2 hover:text-[#020420] text-gray-500"> <span class="sr-only">Nuxt Linkedin</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z"/></svg> </a></li></ul></footer></div></div>
30
30
  </template>
31
31
 
32
32
  <style scoped>
@@ -0,0 +1,23 @@
1
+ import type { Ref } from 'vue';
2
+ export type AnnouncerPoliteness = 'assertive' | 'polite' | 'off';
3
+ export type NuxtAnnouncerOpts = {
4
+ /** @default 'polite' */
5
+ politeness?: AnnouncerPoliteness;
6
+ };
7
+ export type NuxtAnnouncer = {
8
+ message: Ref<string>;
9
+ politeness: Ref<AnnouncerPoliteness>;
10
+ set: (message: string, politeness?: AnnouncerPoliteness) => void;
11
+ polite: (message: string) => void;
12
+ assertive: (message: string) => void;
13
+ _cleanup: () => void;
14
+ };
15
+ /**
16
+ * Composable for announcing messages to screen readers
17
+ * @since 3.17.0
18
+ * @example
19
+ * const { polite, assertive } = useAnnouncer()
20
+ * polite('Item saved successfully')
21
+ * assertive('Error: Form is invalid')
22
+ */
23
+ export declare function useAnnouncer(opts?: NuxtAnnouncerOpts): Omit<NuxtAnnouncer, '_cleanup'>;
@@ -0,0 +1,47 @@
1
+ import { getCurrentScope, onScopeDispose, shallowRef } from "vue";
2
+ import { useNuxtApp } from "../nuxt.js";
3
+ function createAnnouncer(opts = {}) {
4
+ const message = shallowRef("");
5
+ const politeness = shallowRef(opts.politeness || "polite");
6
+ function set(messageValue = "", politenessSetting = "polite") {
7
+ message.value = messageValue;
8
+ politeness.value = politenessSetting;
9
+ }
10
+ function polite(msg) {
11
+ set(msg, "polite");
12
+ }
13
+ function assertive(msg) {
14
+ set(msg, "assertive");
15
+ }
16
+ function _cleanup() {
17
+ message.value = "";
18
+ politeness.value = opts.politeness || "polite";
19
+ }
20
+ return {
21
+ message,
22
+ politeness,
23
+ set,
24
+ polite,
25
+ assertive,
26
+ _cleanup
27
+ };
28
+ }
29
+ export function useAnnouncer(opts = {}) {
30
+ const nuxtApp = useNuxtApp();
31
+ const announcer = nuxtApp._announcer ||= createAnnouncer(opts);
32
+ if (opts.politeness && opts.politeness !== announcer.politeness.value) {
33
+ announcer.politeness.value = opts.politeness;
34
+ }
35
+ if (import.meta.client && getCurrentScope()) {
36
+ nuxtApp._announcerDeps ||= 0;
37
+ nuxtApp._announcerDeps++;
38
+ onScopeDispose(() => {
39
+ nuxtApp._announcerDeps--;
40
+ if (nuxtApp._announcerDeps === 0) {
41
+ announcer._cleanup();
42
+ delete nuxtApp._announcer;
43
+ }
44
+ });
45
+ }
46
+ return announcer;
47
+ }