diff --git a/docs/content/1.getting-started/1.introduction.md b/docs/content/1.getting-started/1.introduction.md index e551a15865c..51d9217602b 100644 --- a/docs/content/1.getting-started/1.introduction.md +++ b/docs/content/1.getting-started/1.introduction.md @@ -46,7 +46,7 @@ Discover more in the [Key concepts section](/guide/concepts/auto-imports). ### Rendering modes -Nuxt offers different rendering modes to accomodate various use-cases: +Nuxt offers different rendering modes to accommodate various use-cases: ::list{type=success} - Universal rendering (Server-side rendering and hydration) diff --git a/docs/content/1.getting-started/10.deployment.md b/docs/content/1.getting-started/10.deployment.md index d7f2af80792..66845b5845c 100644 --- a/docs/content/1.getting-started/10.deployment.md +++ b/docs/content/1.getting-started/10.deployment.md @@ -137,15 +137,15 @@ NITRO_PRESET=node-server nuxt build Nuxt 3 can be deployed to several cloud providers with a minimal amount of configuration: -- :IconCloud{class="h-5 w-4 inline mb-2"} [AWS](https://nitro.unjs.io/deploy/providers/aws) -- :LogoAzure{class="h-5 w-4 inline mb-2"} [Azure](https://nitro.unjs.io/deploy/providers/azure) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Cleavr](https://nitro.unjs.io/deploy/providers/cleavr) -- :LogoCloudFlare{class="h-5 w-4 inline mb-2"} [CloudFlare](https://nitro.unjs.io/deploy/providers/cloudflare) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Digital Ocean](https://nitro.unjs.io/deploy/providers/digitalocean) -- :LogoFirebase{class="h-5 w-4 inline mb-2"} [Firebase](https://nitro.unjs.io/deploy/providers/firebase) -- :IconCloud{class="h-5 w-4 inline mb-2"} [heroku](https://nitro.unjs.io/deploy/providers/heroku) -- :IconCloud{class="h-5 w-4 inline mb-2"} [layer0](https://nitro.unjs.io/deploy/providers/layer0) -- :LogoNetlify{class="h-5 w-4 inline mb-2"} [Netlify](https://nitro.unjs.io/deploy/providers/netlify) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Render](https://nitro.unjs.io/deploy/providers/render) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Stormkit](https://nitro.unjs.io/deploy/providers/stormkit) -- :LogoVercel{class="h-5 w-4 inline mb-2"} [Vercel](https://nitro.unjs.io/deploy/providers/vercel) +- :icon{name="logos:aws" class="h-5 w-4 inline mb-2"} [AWS](https://nitro.unjs.io/deploy/providers/aws) +- :icon{name="logos:microsoft-azure" class="h-5 w-4 inline mb-2"} [Azure](https://nitro.unjs.io/deploy/providers/azure) +- :icon{name="ph:cloud-duotone" class="h-5 w-4 inline mb-2"} [Cleavr](https://nitro.unjs.io/deploy/providers/cleavr) +- :icon{name="logos:cloudflare" class="h-5 w-4 inline mb-2"} [CloudFlare](https://nitro.unjs.io/deploy/providers/cloudflare) +- :icon{name="logos:digital-ocean" class="h-5 w-4 inline mb-2"} [Digital Ocean](https://nitro.unjs.io/deploy/providers/digitalocean) +- :icon{name="logos:firebase" class="h-5 w-4 inline mb-2"} [Firebase](https://nitro.unjs.io/deploy/providers/firebase) +- :icon{name="logos:heroku-icon" class="h-5 w-4 inline mb-2"} [heroku](https://nitro.unjs.io/deploy/providers/heroku) +- :icon{name="ph:cloud-duotone" class="h-5 w-4 inline mb-2"} [layer0](https://nitro.unjs.io/deploy/providers/layer0) +- :icon{name="logos:netlify" class="h-5 w-4 inline mb-2"} [Netlify](https://nitro.unjs.io/deploy/providers/netlify) +- :icon{name="simple-icons:render" class="h-5 w-4 inline mb-2"} [Render](https://nitro.unjs.io/deploy/providers/render) +- :icon{name="ph:cloud-duotone" class="h-5 w-4 inline mb-2"} [Stormkit](https://nitro.unjs.io/deploy/providers/stormkit) +- :icon{name="logos:vercel-icon" class="h-5 w-4 inline mb-2"} [Vercel](https://nitro.unjs.io/deploy/providers/vercel) diff --git a/docs/content/1.getting-started/2.installation.md b/docs/content/1.getting-started/2.installation.md index 78e2cea61a9..63153014fd2 100644 --- a/docs/content/1.getting-started/2.installation.md +++ b/docs/content/1.getting-started/2.installation.md @@ -74,11 +74,15 @@ npm install ``` ```bash [pnpm] -pnpm install --shamefully-hoist +pnpm install ``` :: +::alert +**Note:** If using **pnpm**, make sure to have `.npmrc` with `shamefully-hoist=true` inside it before `pnpm install`. +:: + ## Development Server Now you'll be able to start your Nuxt app in development mode: diff --git a/docs/content/1.getting-started/5.seo-meta.md b/docs/content/1.getting-started/5.seo-meta.md index 6beae21b880..c997658c299 100644 --- a/docs/content/1.getting-started/5.seo-meta.md +++ b/docs/content/1.getting-started/5.seo-meta.md @@ -31,7 +31,7 @@ export default defineNuxtConfig({ app: { head: { charset: 'utf-16', - viewport: 'width=500, initial-scale=1', + viewport: 'width=500, initial-scale=1', title: 'My App', meta: [ // @@ -72,7 +72,7 @@ useHead({ ## Components -Nuxt provides ``, `<Base>`, `<Script>`, `<NoScript>`, `<Style>`, `<Meta>`, `<Link>`, `<Body>`, `<Html>` and `<Head>` components so that you can interact directly with your metadata within your component's template. +Nuxt provides `<Title>`, `<Base>`, `<NoScript>`, `<Style>`, `<Meta>`, `<Link>`, `<Body>`, `<Html>` and `<Head>` components so that you can interact directly with your metadata within your component's template. Because these component names match native HTML elements, it is very important that they are capitalized in the template. @@ -134,7 +134,7 @@ It's recommended to use computed getters (`() => {}`) over computed (`computed(( ```vue [useHead] <script setup lang="ts"> const desc = ref('My amazing site.') - + useHead({ meta: [ { name: 'description', content: desc } @@ -186,30 +186,18 @@ You can use the `body: true` option on the `link` and `script` meta tags to appe For example: -::code-group - - ```vue [useHead] - <script setup lang="ts"> - useHead({ - script: [ - { - src: 'https://third-party-script.com', - body: true - } - ] - }) - </script> - ``` - - ```vue [Components] - <template> - <div> - <Script src="https://third-party-script.com" body="true" /> - </div> - </template> - ``` - -:: +```vue +<script setup lang="ts"> +useHead({ + script: [ + { + src: 'https://third-party-script.com', + body: true + } + ] +}) +</script> +``` ## Examples @@ -234,7 +222,7 @@ And then in your layout file, you might use the route's metadata you have previo const route = useRoute() useHead({ - meta: [{ name: 'og:title', content: `App Name - ${route.meta.title}` }] + meta: [{ property: 'og:title', content: `App Name - ${route.meta.title}` }] }) </script> ``` @@ -254,7 +242,7 @@ In the example below, `titleTemplate` is set either as a string with the `%s` pl // as a string, // where `%s` is replaced with the title titleTemplate: '%s - Site Title', - // ... or as a function + // ... or as a function titleTemplate: (productCategory) => { return productCategory ? `${productCategory} - Site Title` @@ -273,17 +261,17 @@ The example below inserts Google Fonts using the `link` property of the `useHead ::code-group ```vue [useHead] - <script setup lang="ts"> + <script setup lang="ts"> useHead({ link: [ - { - rel: 'preconnect', + { + rel: 'preconnect', href: 'https://fonts.googleapis.com' }, - { - rel: 'stylesheet', - href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', - crossorigin: '' + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', + crossorigin: '' } ] }) diff --git a/docs/content/1.getting-started/6.data-fetching.md b/docs/content/1.getting-started/6.data-fetching.md index 93c1f23484b..921d71d9ab5 100644 --- a/docs/content/1.getting-started/6.data-fetching.md +++ b/docs/content/1.getting-started/6.data-fetching.md @@ -238,9 +238,8 @@ The example below adds the request headers to an isomorphic `$fetch` call to ens ```vue <script setup> -const { data } = await useFetch('/api/me', { - headers: useRequestHeaders(['cookie']) -}) +const headers = useRequestHeaders(['cookie']) +const { data } = await useFetch('/api/me', { headers }) </script> ``` @@ -262,11 +261,11 @@ Here is a list of common headers that are NOT to be proxied: If you want to pass on/proxy cookies in the other direction, from an internal request back to the client, you will need to handle this yourself. ```ts [composables/fetch.ts] -export const fetchWithCookie = async (url: string) => { +export const fetchWithCookie = async (event: H3Event, url: string) => { const res = await $fetch.raw(url) const cookies = (res.headers.get('set-cookie') || '').split(',') for (const cookie of cookies) { - appendHeader(useRequestEvent(), 'set-cookie', cookie) + appendHeader(event, 'set-cookie', cookie) } return res._data } @@ -275,7 +274,8 @@ export const fetchWithCookie = async (url: string) => { ```vue <script setup lang="ts"> // This composable will automatically pass cookies to the client -const result = await fetchWithCookie('/api/with-cookie') +const event = useRequestEvent() +const result = await fetchWithCookie(event, '/api/with-cookie') onMounted(() => console.log(document.cookie)) </script> ``` @@ -352,7 +352,7 @@ export default defineComponent({ ## Directly Calling an API Endpoint -There are instances where you may need to directly call the API. Nuxt 3 provides a globally available `$fetch` method using [unjs/ohmyfetch](https://github.com/unjs/ohmyfetch) (in addition to `fetch`) +There are instances where you may need to directly call the API. Nuxt 3 provides a globally available `$fetch` method using [unjs/ofetch](https://github.com/unjs/ofetch) (in addition to `fetch`) with the same API as the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). Using `$fetch` has a number of benefits, including: diff --git a/docs/content/2.guide/1.concepts/4.server-engine.md b/docs/content/2.guide/1.concepts/4.server-engine.md index 000e3bdc20b..47bbbe0bdfb 100644 --- a/docs/content/2.guide/1.concepts/4.server-engine.md +++ b/docs/content/2.guide/1.concepts/4.server-engine.md @@ -32,12 +32,12 @@ Learn more about the API layer in the [`server/`](/guide/directory-structure/ser Nitro allows 'direct' calling of routes via the globally-available `$fetch` helper. This will make an API call to the server if run on the browser, but will directly call the relevant function if run on the server, **saving an additional API call**. -`$fetch` API is using [ohmyfetch](https://github.com/unjs/ohmyfetch), with key features including: +`$fetch` API is using [ofetch](https://github.com/unjs/ofetch), with key features including: - Automatic parsing of JSON responses (with access to raw response if needed) - Request body and params are automatically handled, with correct `Content-Type` headers -For more information on `$fetch` features, check out [ohmyfetch](https://github.com/unjs/ohmyfetch). +For more information on `$fetch` features, check out [ofetch](https://github.com/unjs/ofetch). ## Typed API Routes diff --git a/docs/content/2.guide/2.directory-structure/1.components.md b/docs/content/2.guide/2.directory-structure/1.components.md index 6149e8b7d2f..9e959c11ce7 100644 --- a/docs/content/2.guide/2.directory-structure/1.components.md +++ b/docs/content/2.guide/2.directory-structure/1.components.md @@ -225,8 +225,6 @@ This feature only works with Nuxt auto-imports and `#components` imports. Explic ## `<DevOnly>` Component -:StabilityEdge - Nuxt provides the `<DevOnly>` component to render a component only during development. The content will not be included in production builds and tree-shaken. diff --git a/docs/content/2.guide/2.directory-structure/1.composables.md b/docs/content/2.guide/2.directory-structure/1.composables.md index ee087f4481f..a72160895d2 100644 --- a/docs/content/2.guide/2.directory-structure/1.composables.md +++ b/docs/content/2.guide/2.directory-structure/1.composables.md @@ -11,7 +11,7 @@ Nuxt 3 uses the `composables/` directory to automatically import your Vue compos Under the hood, Nuxt auto generates the file `.nuxt/imports.d.ts` to declare the types. -Be aware that you have to run `nuxi prepare`, `nuxi dev` or `nuxi build` in order to let Nuxt generates the types. If you create a composable without having the dev server running, typescript will throw an error `Cannot find name 'useBar'.` +Be aware that you have to run `nuxi prepare`, `nuxi dev` or `nuxi build` in order to let Nuxt generate the types. If you create a composable without having the dev server running, TypeScript will throw an error, such as `Cannot find name 'useBar'.` ## Usage diff --git a/docs/content/2.guide/2.directory-structure/1.server.md b/docs/content/2.guide/2.directory-structure/1.server.md index e4a7d1c6ae2..f52580236a6 100644 --- a/docs/content/2.guide/2.directory-structure/1.server.md +++ b/docs/content/2.guide/2.directory-structure/1.server.md @@ -11,7 +11,7 @@ Nuxt automatically scans files inside the `~/server/api`, `~/server/routes`, and Each file should export a default function defined with `defineEventHandler()`. -The handler can directly return JSON data, a `Promise` or use `event.res.end()` to send response. +The handler can directly return JSON data, a `Promise` or use `event.node.res.end()` to send response. ::ReadMore{link="https://nitro.unjs.io/guide/introduction/routing" title="Nitro Route Handling Docs"} :: @@ -57,7 +57,7 @@ Middleware handlers should not return anything (nor close or respond to the requ ```ts [server/middleware/log.ts] export default defineEventHandler((event) => { - console.log('New request: ' + event.req.url) + console.log('New request: ' + event.node.req.url) }) ``` @@ -264,7 +264,8 @@ export default defineNuxtConfig({ host: "127.0.0.1", // Redis host username: "", // needs Redis >= 6 password: "", - db: 0 // Defaults to 0 + db: 0, // Defaults to 0 + tls: {} // tls/ssl } } } diff --git a/docs/content/2.guide/2.directory-structure/1.utils.md b/docs/content/2.guide/2.directory-structure/1.utils.md new file mode 100644 index 00000000000..d73223b457a --- /dev/null +++ b/docs/content/2.guide/2.directory-structure/1.utils.md @@ -0,0 +1,16 @@ +--- +navigation.icon: IconDirectory +title: 'utils' +head.title: Utils +description: Use the utils/ directory to auto-import your utility functions throughout your application. +--- + +# Utils Directory + +Nuxt 3 uses the `utils/` directory to automatically import helper functions and other utilities throughout your application using [auto-imports](/guide/concepts/auto-imports)! + +::alert{type=info} +The main purpose of the `utils/` directory is to allow a semantic distinction between your Vue composables and other auto-imported utility functions. + +The way `utils/` auto-imports work and are scanned is identical to [the composables/ directory](/guide/directory-structure/composables). You can see examples and more information about how they work in that section of the docs. +:: diff --git a/docs/content/3.api/1.composables/on-before-route-leave.md b/docs/content/3.api/1.composables/on-before-route-leave.md new file mode 100644 index 00000000000..ff484625bd8 --- /dev/null +++ b/docs/content/3.api/1.composables/on-before-route-leave.md @@ -0,0 +1,11 @@ +--- +title: "onBeforeRouteLeave" +description: The onBeforeRouteLeave composable allows registering a route guard within a component. +--- + +# `onBeforeRouteLeave` + +The `onBeforeRouteLeave` composable adds a navigation guard that triggers whenever the component for the current location is about to be left. + +::ReadMore{link="https://router.vuejs.org/api/index.html#onbeforerouteleave"} +:: diff --git a/docs/content/3.api/1.composables/on-before-route-update.md b/docs/content/3.api/1.composables/on-before-route-update.md new file mode 100644 index 00000000000..16166a52882 --- /dev/null +++ b/docs/content/3.api/1.composables/on-before-route-update.md @@ -0,0 +1,11 @@ +--- +title: "onBeforeRouteUpdate" +description: The onBeforeRouteUpdate composable allows registering a route guard within a component. +--- + +# `onBeforeRouteUpdate` + +The `onBeforeRouteUpdate` composable adds a navigation guard that triggers whenever the component for the current location is about to be updated. + +::ReadMore{link="https://router.vuejs.org/api/index.html#onbeforerouteupdate"} +:: diff --git a/docs/content/3.api/1.composables/use-async-data.md b/docs/content/3.api/1.composables/use-async-data.md index 29825ec5104..f45124556f1 100644 --- a/docs/content/3.api/1.composables/use-async-data.md +++ b/docs/content/3.api/1.composables/use-async-data.md @@ -25,7 +25,6 @@ type AsyncDataOptions<DataT> = { transform?: (input: DataT) => DataT pick?: string[] watch?: WatchSource[] - initialCache?: boolean immediate?: boolean } @@ -55,7 +54,6 @@ type AsyncData<DataT, ErrorT> = { * _transform_: a function that can be used to alter `handler` function result after resolving * _pick_: only pick specified keys in this array from the `handler` function result * _watch_: watch reactive sources to auto-refresh - * _initialCache_: When set to `false`, will skip payload cache for initial fetch. (defaults to `true`) * _immediate_: When set to `false`, will prevent the request from firing immediately. (defaults to `true`) Under the hood, `lazy: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `lazy: true` and implementing a loading state instead for a snappier user experience. diff --git a/docs/content/3.api/1.composables/use-fetch.md b/docs/content/3.api/1.composables/use-fetch.md index 7e3ef8e9be7..ba511bf979d 100644 --- a/docs/content/3.api/1.composables/use-fetch.md +++ b/docs/content/3.api/1.composables/use-fetch.md @@ -15,6 +15,7 @@ function useFetch( type UseFetchOptions = { key?: string method?: string + query?: SearchParams params?: SearchParams body?: RequestInit['body'] | Record<string, any> headers?: { key: string, value: string }[] @@ -26,7 +27,6 @@ type UseFetchOptions = { transform?: (input: DataT) => DataT pick?: string[] watch?: WatchSource[] - initialCache?: boolean } type AsyncData<DataT> = { @@ -41,9 +41,10 @@ type AsyncData<DataT> = { ## Params * **Url**: The URL to fetch. -* **Options (extends [unjs/ohmyfetch](https://github.com/unjs/ohmyfetch) options & [AsyncDataOptions](/api/composables/use-async-data#params))**: +* **Options (extends [unjs/ofetch](https://github.com/unjs/ofetch) options & [AsyncDataOptions](/api/composables/use-async-data#params))**: * `method`: Request method. - * `params`: Query params. + * `query`: Adds query search params to URL using [ufo](https://github.com/unjs/ufo) + * `params`: Alias for `query` * `body`: Request body - automatically stringified (if an object is passed). * `headers`: Request headers. * `baseURL`: Base URL for the request. @@ -53,12 +54,11 @@ All fetch options can be given a `computed` or `ref` value. These will be watche :: * **Options (from `useAsyncData`)**: - * `key`: a unique key to ensure that data fetching can be properly de-duplicated across requests, if not provided, it will be generated based on the static code location where `useAyncData` is used. + * `key`: a unique key to ensure that data fetching can be properly de-duplicated across requests, if not provided, it will be generated based on the static code location where `useAsyncData` is used. * `server`: Whether to fetch the data on the server (defaults to `true`). * `default`: A factory function to set the default value of the data, before the async function resolves - particularly useful with the `lazy: true` option. * `pick`: Only pick specified keys in this array from the `handler` function result. * `watch`: watch reactive sources to auto-refresh. - * `initialCache`: When set to `false`, will skip payload cache for initial fetch (defaults to `true`). * `transform`: A function that can be used to alter `handler` function result after resolving. * `immediate`: When set to `false`, will prevent the request from firing immediately. (defaults to `true`) @@ -87,7 +87,20 @@ const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev }) ``` -Using [interceptors](https://github.com/unjs/ohmyfetch#%EF%B8%8F-interceptors): +Adding Query Search Params: + +Using the `query` option, you can add search parameters to your query. This option is extended from [unjs/ofetch](https://github.com/unjs/ofetch) and is using [unjs/ufo](https://github.com/unjs/ufo) to create the URL. Objects are automatically stringified. + +```ts +const param1 = ref('value1') +const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains',{ + query: { param1, param2: 'value2' } +}) +``` + +Results in `https://api.nuxtjs.dev/mountains?param1=value1¶m2=value2` + +Using [interceptors](https://github.com/unjs/ofetch#%EF%B8%8F-interceptors): ```ts const { data, pending, error, refresh } = await useFetch('/api/auth/login', { diff --git a/docs/content/3.api/1.composables/use-head.md b/docs/content/3.api/1.composables/use-head.md index 8fb170a0df2..4a96f0b8388 100644 --- a/docs/content/3.api/1.composables/use-head.md +++ b/docs/content/3.api/1.composables/use-head.md @@ -4,11 +4,9 @@ description: useHead customizes the head properties of individual pages of your # `useHead` -Nuxt provides the `useHead` composable to add and customize the head properties of individual pages of your Nuxt app. It uses [@vueuse/head](https://github.com/vueuse/head) under the hood. +Nuxt provides the `useHead` composable to add and customize the head properties of individual pages of your Nuxt app. -::alert{icon=πŸ‘‰} -`useHead` only works during `setup` or `Lifecycle Hooks`. -:: +`useHead` is powered by [@vueuse/head](https://github.com/vueuse/head), you can find more in-depth documentation [here](https://unhead.harlanzw.com/) ::ReadMore{link="/getting-started/seo-meta"} :: @@ -19,7 +17,7 @@ Nuxt provides the `useHead` composable to add and customize the head properties useHead(meta: MaybeComputedRef<MetaObject>): void ``` -Below are the non-reactive types for `useMeta`. See [zhead](https://github.com/harlan-zw/zhead/tree/main/packages/schema/src) for more detailed types. +Below are the non-reactive types for `useHead`. See [zhead](https://github.com/harlan-zw/zhead/tree/main/packages/schema/src) for more detailed types. ```ts interface MetaObject { diff --git a/docs/content/3.api/1.composables/use-hydration.md b/docs/content/3.api/1.composables/use-hydration.md index c3684b0811f..d7d5a12ac0c 100644 --- a/docs/content/3.api/1.composables/use-hydration.md +++ b/docs/content/3.api/1.composables/use-hydration.md @@ -2,8 +2,37 @@ Allows full control of the hydration cycle to set and receive data from the server. -::ReadMore{link="/getting-started/data-fetching"} -:: +`useHydration` is a built-in composable that provides a way to set data on the server side every time a new HTTP request is made and receive that data on the client side. This way `useHydration` allows you to take full control of the hydration cycle. + +## Type + +```ts [signature] +useHydration <T> (key: string, get: () => T, set: (value: T) => void) => {} +``` + +You can use `useHydration()` within composables, plugins and components. + +`useHydration` accepts three parameters: + +- `key` + + **Type**: `String` + + `key` is a unique key that identifies the data in your Nuxt application -::NeedContribution +- `get` + + **Type**: `Function` + + `get` is a function that returns the value to set the initial data + +- `set` + + **Type**: `Function` + + `set` a function that receives the data on the client-side + +Once the initial data is returned using the `get` function on the server side, you can access that data within `nuxtApp.payload` using the unique key that is passed as the first parameter in `useHydration` composable. + +::ReadMore{link="/getting-started/data-fetching"} :: diff --git a/docs/content/3.api/1.composables/use-nuxt-app.md b/docs/content/3.api/1.composables/use-nuxt-app.md index 4e4af44efed..c4f0f7d4f0c 100644 --- a/docs/content/3.api/1.composables/use-nuxt-app.md +++ b/docs/content/3.api/1.composables/use-nuxt-app.md @@ -36,7 +36,7 @@ Hooks available in `nuxtApp` allows you to customize the runtime aspects of your `hook` function is useful for adding custom logic by hooking into the rendering lifecycle at a specific point. `hook` function is mostly used when creating Nuxt plugins. -See [Runtime Hooks](/api/advanced/hooks#app-hooks-runtime) for avialble runtime hooks called by Nuxt. +See [Runtime Hooks](/api/advanced/hooks#app-hooks-runtime) for available runtime hooks called by Nuxt. ```js [plugins/test.ts] export default defineNuxtPlugin((nuxtApp) => { diff --git a/docs/content/3.api/1.composables/use-request-event.md b/docs/content/3.api/1.composables/use-request-event.md index 54d1fb1a0a2..bb71f4e75fc 100644 --- a/docs/content/3.api/1.composables/use-request-event.md +++ b/docs/content/3.api/1.composables/use-request-event.md @@ -12,7 +12,7 @@ Within your pages, components, and plugins you can use `useRequestEvent` to acce const event = useRequestEvent() // Get the URL -const url = event.req.url +const url = event.node.req.url ``` ::alert{icon=πŸ‘‰} diff --git a/docs/content/3.api/1.composables/use-request-headers.md b/docs/content/3.api/1.composables/use-request-headers.md index 90115ece837..4b928a8fa21 100644 --- a/docs/content/3.api/1.composables/use-request-headers.md +++ b/docs/content/3.api/1.composables/use-request-headers.md @@ -5,7 +5,7 @@ description: "Use useRequestHeaders to access the incoming request headers." # `useRequestHeaders` -Within your pages, components, and plugins you can use `useRequestHeaders` to access the incoming request headers. +You can use built-in `useRequestHeaders` composable to access the incoming request headers within your pages, components, and plugins. ```js // Get all request headers @@ -18,3 +18,21 @@ const headers = useRequestHeaders(['cookie']) ::alert{icon=πŸ‘‰} In the browser, `useRequestHeaders` will return an empty object. :: + +## Example + +We can use `useRequestHeaders` to access and proxy the initial request's `authorization` header to any future internal requests during SSR. + +The example below adds the `authorization` request header to an isomorphic `$fetch` call. + +```vue [pages/some-page.vue] +<script setup> +const { data } = await useFetch('/api/confidential', { + headers: useRequestHeaders(['authorization']) +}) +</script> +``` + +::alert{icon=πŸ‘‰} +[Another example](/getting-started/data-fetching#example-pass-client-headers-to-the-api) shows how we can pass cookies from the initial request to another API route. +:: diff --git a/docs/content/3.api/1.composables/use-router.md b/docs/content/3.api/1.composables/use-router.md index 36696c54995..9eab3028f6a 100644 --- a/docs/content/3.api/1.composables/use-router.md +++ b/docs/content/3.api/1.composables/use-router.md @@ -45,7 +45,7 @@ router.replace({ hash: "#bio" }); ## Navigation Guards -`useRouter` composable provides `afterEach`, `beforeEach` and `beforeResolve` helper methods that acts as nagivation guards. +`useRouter` composable provides `afterEach`, `beforeEach` and `beforeResolve` helper methods that acts as navigation guards. However, Nuxt has a concept of **route middleware** that simplifies the implementation of navigation guards and provides a better developer experience. diff --git a/docs/content/3.api/1.composables/use-runtime-config.md b/docs/content/3.api/1.composables/use-runtime-config.md index 6f8aeb08d10..3007bcfdf77 100644 --- a/docs/content/3.api/1.composables/use-runtime-config.md +++ b/docs/content/3.api/1.composables/use-runtime-config.md @@ -43,7 +43,7 @@ Variables that need to be accessible on the server are added directly inside `ru ::ReadMore{link="/guide/going-further/runtime-config"} :: -## Acess Runtime Config +## Access Runtime Config To access runtime config, we can use `useRuntimeConfig()` composable: diff --git a/docs/content/3.api/2.components/2.nuxt-page.md b/docs/content/3.api/2.components/2.nuxt-page.md index 1419691bf5d..95ec0234a37 100644 --- a/docs/content/3.api/2.components/2.nuxt-page.md +++ b/docs/content/3.api/2.components/2.nuxt-page.md @@ -31,7 +31,7 @@ For example, passing `static` key, `NuxtPage` component is rendered only once wh ```html <!-- static key --> -<NuxtPage page-key=β€œstatic” /> +<NuxtPage page-key="static" /> ``` Alternatively, `pageKey` can be passed as a `key` value via `definePageMeta` from the `<script>` section of your Vue component in the `/pages` directory. @@ -51,7 +51,7 @@ definePageMeta({ In addition, `NuxtPage` also accepts custom props that you may need to pass further down the hierarchy. These custom props are accessible via `attrs` in the Nuxt app. ```html -<NuxtPage :foobar=β€œ123” /> +<NuxtPage :foobar="123" /> ``` For example, in above example, value of `foobar` will be available using `attrs.foobar`. diff --git a/docs/content/3.api/3.utils/$fetch.md b/docs/content/3.api/3.utils/$fetch.md index 35830f027bc..d08a51bdc5f 100644 --- a/docs/content/3.api/3.utils/$fetch.md +++ b/docs/content/3.api/3.utils/$fetch.md @@ -1,11 +1,11 @@ --- title: "$fetch" -description: Nuxt uses ohmyfetch to expose globally the $fetch helper for making HTTP requests. +description: Nuxt uses ofetch to expose globally the $fetch helper for making HTTP requests. --- # `$fetch` -Nuxt uses [ohmyfetch](https://github.com/unjs/ohmyfetch) to expose globally the `$fetch` helper for making HTTP requests within your Vue app or API routes. +Nuxt uses [ofetch](https://github.com/unjs/ofetch) to expose globally the `$fetch` helper for making HTTP requests within your Vue app or API routes. ::ReadMore{link="/getting-started/data-fetching"} :: diff --git a/docs/content/3.api/3.utils/define-nuxt-component.md b/docs/content/3.api/3.utils/define-nuxt-component.md index 49c0960b9b6..d245c5b4bb6 100644 --- a/docs/content/3.api/3.utils/define-nuxt-component.md +++ b/docs/content/3.api/3.utils/define-nuxt-component.md @@ -5,10 +5,10 @@ description: defineNuxtComponent() is a helper function for defining type safe c # `defineNuxtComponent` -`defineNuxtComponent()` is a helper function for defining type safe Vue components using options API similar to [defineComponent()](https://vuejs.org/api/general.html#definecomponent). `defineNuxtComponent()` wrapper also adds support for `asyncData` component option. +`defineNuxtComponent()` is a helper function for defining type safe Vue components using options API similar to [defineComponent()](https://vuejs.org/api/general.html#definecomponent). `defineNuxtComponent()` wrapper also adds support for `asyncData` and `head` component options. ::alert{type=warning} -Options API support for `asyncData` may well change before the stable release of Nuxt 3. +Options API support for `asyncData` and `head` may well change before the stable release of Nuxt 3. :: ::Alert @@ -34,3 +34,19 @@ export default defineNuxtComponent({ }) </script> ``` + +## `head()` + +If you choose not to use `setup()` in your app, you can use the `head()` method within your component definition: + +```vue [pages/index.vue] +<script lang="ts"> +export default defineNuxtComponent({ + head(nuxtApp) { + return { + title: 'My site' + } + }, +}) +</script> +``` diff --git a/docs/content/3.api/3.utils/refresh-nuxt-data.md b/docs/content/3.api/3.utils/refresh-nuxt-data.md index 6e1bd435a0e..35387d05ee6 100644 --- a/docs/content/3.api/3.utils/refresh-nuxt-data.md +++ b/docs/content/3.api/3.utils/refresh-nuxt-data.md @@ -5,15 +5,67 @@ description: refreshNuxtData refetches all data from the server and updates the # `refreshNuxtData` -`refreshNuxtData` refetches all data from the server and updates the page. +`refreshNuxtData` re-fetches all data from the server and updates the page as well as invalidates the cache of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch`. -::ReadMore{link="/getting-started/data-fetching"} -:: +## Type ```ts refreshNuxtData(keys?: string | string[]) ``` -Available options: +**Parameters:** + +* `keys`: + + **Type**: `String | String[]` + + `refreshNuxtData` accepts a single or an array of strings as `keys` that are used to fetch the data. This parameter is **optional**. All `useAsyncData` and `useFetch` are re-fetched when no `keys` are specified. + +## Examples + +### Refresh All data + +This example below refreshes all data being fetched using `useAsyncData` and `useFetch` on the current page. + +```vue [pages/some-page.vue] +<template> + <div> + <button :disabled="refreshing" @click="refreshAll"> + Refetch All Data + </button> + </div> +</template> + +<script setup> +const refreshing = ref(false) +const refreshAll = async () => { + refreshing.value = true + try { + await refreshNuxtData() + } finally { + refreshing.value = false + } +} +</script> +``` + +### Refresh Specific Data + +This example below refreshes only data where the key matches to `count`. + +```vue [pages/some-page.vue] +<template> + <div> + {{ pending ? 'Loading' : count }} + </div> + <button @click="refresh">Refresh</button> +</template> -* `keys`: Provides an array of keys that are used in `useAsyncData` to refetch. When it's not specified, all `useAsyncData` and `useFetch` will be refetched. +<script setup> +const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count')) +const refresh = () => refreshNuxtData('count') +</script> +``` + +::ReadMore{link="/getting-started/data-fetching"} +:: diff --git a/docs/content/3.api/4.advanced/2.kit.md b/docs/content/3.api/4.advanced/2.kit.md index 59132a038a4..5e4d79d473b 100644 --- a/docs/content/3.api/4.advanced/2.kit.md +++ b/docs/content/3.api/4.advanced/2.kit.md @@ -40,8 +40,8 @@ description: Nuxt Kit provides composable utilities to help interacting with Nux [source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/imports.ts) - `addImports(imports)` -- `addImportsDir(autoImportDirs)` -- `addImportsSources(autoImportSources)` +- `addImportsDir(importDirs)` +- `addImportsSources(importSources)` ### Components @@ -56,6 +56,12 @@ description: Nuxt Kit provides composable utilities to help interacting with Nux - `useNuxt()` +### Pages + +[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/pages.ts) + +- `extendPages (callback: pages => void)` + ### Plugins [source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/plugin.ts) diff --git a/docs/content/3.api/5.commands/add.md b/docs/content/3.api/5.commands/add.md index a7b2589eba7..75f552ddc85 100644 --- a/docs/content/3.api/5.commands/add.md +++ b/docs/content/3.api/5.commands/add.md @@ -89,7 +89,7 @@ npx nuxi add middleware auth ## `nuxi add api` -* Modifier flags: `--method=connect|delete|get|head|options|patch|post|put|trace` or `--get`, `--post`, etc. +* Modifier flags: `--method` (can accept `connect`, `delete`, `get`, `head`, `options`, `patch`, `post`, `put` or `trace`) or alternatively you can directly use `--get`, `--post`, etc. Example: diff --git a/docs/content/4.examples/0.essentials/hello-world.md b/docs/content/4.examples/0.essentials/hello-world.md index 69586e6201f..c225b96a973 100644 --- a/docs/content/4.examples/0.essentials/hello-world.md +++ b/docs/content/4.examples/0.essentials/hello-world.md @@ -1,9 +1,9 @@ --- -title: "Hello World" -description: "A minimal Nuxt 3 application only requires the `app.vue` and `nuxt.config.js` files." toc: false --- +# Hello World + A minimal Nuxt 3 application only requires the `app.vue` and `nuxt.config.js` files. ::ReadMore{link="/getting-started/introduction"} diff --git a/docs/content/4.examples/1.app/app-config.md b/docs/content/4.examples/1.app/app-config.md index 527ddf5555e..374f381edf9 100644 --- a/docs/content/4.examples/1.app/app-config.md +++ b/docs/content/4.examples/1.app/app-config.md @@ -1,5 +1,5 @@ --- -template: Example +toc: false --- # `app.config` diff --git a/docs/content/4.examples/1.app/error-handling.md b/docs/content/4.examples/1.app/error-handling.md index 9488e6a23b4..c4036f262b8 100644 --- a/docs/content/4.examples/1.app/error-handling.md +++ b/docs/content/4.examples/1.app/error-handling.md @@ -1,6 +1,4 @@ --- -title: "Error Handling" -description: "This example shows how to handle errors in different contexts: pages, plugins, components and middleware." toc: false --- @@ -8,7 +6,7 @@ toc: false This example shows how to handle errors in different contexts: pages, plugins, components and middleware. -::ReadMore{link="/getting-started/error-handling"} +:ReadMore{link="/getting-started/error-handling"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/app/error-handling" file="app.vue"} diff --git a/docs/content/4.examples/1.app/plugins.md b/docs/content/4.examples/1.app/plugins.md index 6f69ab876d0..33176a97012 100644 --- a/docs/content/4.examples/1.app/plugins.md +++ b/docs/content/4.examples/1.app/plugins.md @@ -1,10 +1,12 @@ --- -title: "Plugins" -description: "This example shows how to use the plugins/ directory to auto-register plugins." toc: false --- -::ReadMore{link="/guide/directory-structure/plugins"} +# Plugins + +This example shows how to use the plugins/ directory to auto-register plugins. + +:ReadMore{link="/guide/directory-structure/plugins"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/app/plugins" file="app.vue"} diff --git a/docs/content/4.examples/1.app/teleport.md b/docs/content/4.examples/1.app/teleport.md index 274ac11847a..30cd4bd7a8f 100644 --- a/docs/content/4.examples/1.app/teleport.md +++ b/docs/content/4.examples/1.app/teleport.md @@ -1,9 +1,11 @@ --- -title: "Teleport" -description: "This example shows how to use the <Teleport> with client-side and server-side rendering." toc: false --- +# Teleport + +This example shows how to use the <Teleport> with client-side and server-side rendering. + Vue 3 provides the [`<Teleport>` component](https://vuejs.org/guide/built-ins/teleport.html) which allows content to be rendered elsewhere in the DOM, outside of the Vue application. This example shows how to use the `<Teleport>` with client-side and server-side rendering. diff --git a/docs/content/4.examples/2.auto-imports/components.md b/docs/content/4.examples/2.auto-imports/components.md index 1f881164df7..991dcb6523c 100644 --- a/docs/content/4.examples/2.auto-imports/components.md +++ b/docs/content/4.examples/2.auto-imports/components.md @@ -1,10 +1,10 @@ --- -title: "Components" -description: "You can configure other directories to support components auto-imports." toc: false --- -Components in the `components/` directory are auto-imported and can be used directly in your templates. +# Components + +Components in the `components/` directory are auto-imported and can be used directly in your templates. You can configure other directories to support components auto-imports. ::ReadMore{link="/guide/directory-structure/components"} :: diff --git a/docs/content/4.examples/2.auto-imports/composables.md b/docs/content/4.examples/2.auto-imports/composables.md index babd706eb05..a57a47bcdcb 100644 --- a/docs/content/4.examples/2.auto-imports/composables.md +++ b/docs/content/4.examples/2.auto-imports/composables.md @@ -1,10 +1,12 @@ --- -title: "Composables" -description: "This example shows how to use the composables/ directory to auto-import composables." toc: false --- -If the component file provides a default export, the name of the composable will be mapped to the name of the file. Named exports can be used as-is. +# Composables + +This example shows how to use the composables/ directory to auto-import composables. + +If the composable file provides a default export, the name of the composable will be mapped to the name of the file. Named exports can be used as-is. ::ReadMore{link="/guide/directory-structure/composables"} :: diff --git a/docs/content/4.examples/3.composables/use-async-data.md b/docs/content/4.examples/3.composables/use-async-data.md index 9a98adc2373..2410b161d16 100644 --- a/docs/content/4.examples/3.composables/use-async-data.md +++ b/docs/content/4.examples/3.composables/use-async-data.md @@ -1,9 +1,11 @@ --- -title: "useAsyncData" -description: "This example shows how to use useAsyncData to fetch data from an API endpoint." toc: false --- +# useAsyncData + +This example shows how to use useAsyncData to fetch data from an API endpoint. + ::alert{type=info icon=πŸ’‘} Nuxt will automatically read files in the `~/server/api` directory to create API endpoints. :: diff --git a/docs/content/4.examples/3.composables/use-cookie.md b/docs/content/4.examples/3.composables/use-cookie.md index 8d3ffc8f14e..1598ec1349f 100644 --- a/docs/content/4.examples/3.composables/use-cookie.md +++ b/docs/content/4.examples/3.composables/use-cookie.md @@ -1,9 +1,11 @@ --- -title: "useCookie" -description: "This example shows how to use the useCookie API to persist small amounts of data that both client and server can use." toc: false --- +# useCookie + +This example shows how to use the useCookie API to persist small amounts of data that both client and server can use. + ::ReadMore{link="/api/composables/use-cookie"} :: diff --git a/docs/content/4.examples/3.composables/use-fetch.md b/docs/content/4.examples/3.composables/use-fetch.md index 3bdfede2eb1..acebd0cc444 100644 --- a/docs/content/4.examples/3.composables/use-fetch.md +++ b/docs/content/4.examples/3.composables/use-fetch.md @@ -1,9 +1,11 @@ --- -title: "useFetch" -description: "This example shows how to use useFetch to fetch data from an API endpoint." toc: false --- +# useFetch + +This example shows how to use useFetch to fetch data from an API endpoint. + ::alert{type=info icon=πŸ’‘} Nuxt will automatically read files in the `~/server/api` directory to create API endpoints. :: diff --git a/docs/content/4.examples/3.composables/use-head.md b/docs/content/4.examples/3.composables/use-head.md index 6251ed68ca9..e516220a318 100644 --- a/docs/content/4.examples/3.composables/use-head.md +++ b/docs/content/4.examples/3.composables/use-head.md @@ -1,9 +1,11 @@ --- toc: false -description: "This example shows how to use useHead and Nuxt built-in components to bind meta data to the head of the page." -title: "useHead" --- +# useHead + +This example shows how to use useHead and Nuxt built-in components to bind meta data to the head of the page. + ::ReadMore{link="/api/composables/use-head"} :: diff --git a/docs/content/4.examples/3.composables/use-state.md b/docs/content/4.examples/3.composables/use-state.md index 2bbb42ec340..637fff22e4a 100644 --- a/docs/content/4.examples/3.composables/use-state.md +++ b/docs/content/4.examples/3.composables/use-state.md @@ -1,9 +1,11 @@ --- -title: "useState" -description: "useState is an SSR-friendly ref replacement." toc: false --- +# useState + +This example showcase the `useState` composable, an SSR-friendly ref replacement. + Its value will be preserved after server-side rendering and shared across all components using a unique key. ::alert{type=info icon=πŸ‘‰} diff --git a/docs/content/4.examples/4.routing/layouts.md b/docs/content/4.examples/4.routing/layouts.md index fc4c715b918..9f072e4bc58 100644 --- a/docs/content/4.examples/4.routing/layouts.md +++ b/docs/content/4.examples/4.routing/layouts.md @@ -1,9 +1,11 @@ --- -title: "Layouts" -description: "This example shows how to define default and custom layouts." toc: false --- +# Layouts + +This example shows how to define default and custom layouts. + ::ReadMore{link="/guide/directory-structure/layouts"} :: diff --git a/docs/content/4.examples/4.routing/middleware.md b/docs/content/4.examples/4.routing/middleware.md index 863f19edd6a..51365bca169 100644 --- a/docs/content/4.examples/4.routing/middleware.md +++ b/docs/content/4.examples/4.routing/middleware.md @@ -1,9 +1,11 @@ --- -title: "Middleware" -description: "This example shows how to add route middleware with the middleware/ directory or with a plugin, and how to use them globally or per page." toc: false --- +# Middleware + +This example shows how to add route middleware with the middleware/ directory or with a plugin, and how to use them globally or per page. + ::ReadMore{link="/guide/directory-structure/middleware"} :: diff --git a/docs/content/4.examples/4.routing/nuxt-link.md b/docs/content/4.examples/4.routing/nuxt-link.md index a4c7f0e5b21..efdb896f751 100644 --- a/docs/content/4.examples/4.routing/nuxt-link.md +++ b/docs/content/4.examples/4.routing/nuxt-link.md @@ -1,9 +1,11 @@ --- -title: "<NuxtLink>" -description: "This example shows different ways to use <NuxtLink>." toc: false --- +# `<NuxtLink>` + +This example shows different ways to navigate between page with the `<NuxtLink>` component. + ::alert{type=info icon=πŸ’‘} `components/MyNuxtLink.ts` defines a custom `<NuxtLink>`. :: diff --git a/docs/content/4.examples/4.routing/pages.md b/docs/content/4.examples/4.routing/pages.md index 9276619beaf..f300a8c14c0 100644 --- a/docs/content/4.examples/4.routing/pages.md +++ b/docs/content/4.examples/4.routing/pages.md @@ -1,9 +1,11 @@ --- -title: "Pages" -description: "This example shows how to use the pages/ directory to create application routes." toc: false --- +# Pages + +This example shows how to use the pages/ directory to create application routes. + ::ReadMore{link="/guide/directory-structure/pages"} :: diff --git a/docs/content/4.examples/4.routing/universal-router.md b/docs/content/4.examples/4.routing/universal-router.md index 30a85337428..03149de87e6 100644 --- a/docs/content/4.examples/4.routing/universal-router.md +++ b/docs/content/4.examples/4.routing/universal-router.md @@ -1,6 +1,4 @@ --- -title: "Universal Router" -description: "This example demonstrates Nuxt universal routing utilities without depending on pages/ and vue-router." toc: false --- diff --git a/docs/content/4.examples/5.server/routes.md b/docs/content/4.examples/5.server/routes.md index d2a093ac062..8666e02968d 100644 --- a/docs/content/4.examples/5.server/routes.md +++ b/docs/content/4.examples/5.server/routes.md @@ -1,6 +1,4 @@ --- -title: "Server Routes" -description: "This example shows how to create server routes inside the server/api directory." toc: false --- diff --git a/docs/content/4.examples/6.advanced/config-extends.md b/docs/content/4.examples/6.advanced/config-extends.md index e8f93e6aa8e..aabd1a742d8 100644 --- a/docs/content/4.examples/6.advanced/config-extends.md +++ b/docs/content/4.examples/6.advanced/config-extends.md @@ -1,9 +1,11 @@ --- -title: "Config Extends" -description: "This example shows how to use the extends key in nuxt.config.ts." toc: false --- +# Config Extends + +This example shows how to use the extends key in `nuxt.config.ts`. + This example shows how to use the `extends` key in nuxt.config.ts to use the `base/` directory as a base Nuxt application, and use its components, composables or config and override them if necessary. ::sandbox{repo="nuxt/framework" branch="main" dir="examples/advanced/config-extends" file="nuxt.config.ts"} diff --git a/docs/content/4.examples/6.advanced/jsx.md b/docs/content/4.examples/6.advanced/jsx.md index 1139e3fb38c..2c85e32898d 100644 --- a/docs/content/4.examples/6.advanced/jsx.md +++ b/docs/content/4.examples/6.advanced/jsx.md @@ -1,5 +1,5 @@ --- -template: Example +toc: false --- # JSX / TSX diff --git a/docs/content/4.examples/6.advanced/module-extend-pages.md b/docs/content/4.examples/6.advanced/module-extend-pages.md index 36bac698203..a36fb41b4ed 100644 --- a/docs/content/4.examples/6.advanced/module-extend-pages.md +++ b/docs/content/4.examples/6.advanced/module-extend-pages.md @@ -1,9 +1,9 @@ --- -title: "Module Extend Pages" -description: "This example defines a new test page using extendPages within a module." toc: false --- +# Module Extend Pages + This example defines a new `test` page using `extendPages` within a module. ::ReadMore{link="/guide/going-further/modules"} diff --git a/docs/content/4.examples/6.advanced/testing.md b/docs/content/4.examples/6.advanced/testing.md index 659227d76f9..a5c0eec42de 100644 --- a/docs/content/4.examples/6.advanced/testing.md +++ b/docs/content/4.examples/6.advanced/testing.md @@ -1,9 +1,11 @@ --- -title: "Testing" -description: "This example shows how to test your Nuxt application." toc: false --- +# Testing + +This example shows how to test your Nuxt application. + ::alert{type=info icon=πŸ‘‰} Learn more about [testing](/guide/going-further/testing). :: diff --git a/docs/content/4.examples/7.experimental/reactivity-transform.md b/docs/content/4.examples/7.experimental/reactivity-transform.md index cdda17773e3..9d22a6738c3 100644 --- a/docs/content/4.examples/7.experimental/reactivity-transform.md +++ b/docs/content/4.examples/7.experimental/reactivity-transform.md @@ -1,9 +1,11 @@ --- -title: "Reactivity Transform" -description: "This example demonstrates the support of Reactivity Transform in Nuxt 3." toc: false --- +# Reactivity Transform + +This example demonstrates the support of Reactivity Transform in Nuxt 3. + ::ReadMore{link="https://vuejs.org/guide/extras/reactivity-transform.html" title="Reactivity Transform"} :: diff --git a/docs/content/4.examples/7.experimental/wasm.md b/docs/content/4.examples/7.experimental/wasm.md index 3607c6ec72f..17272507e88 100644 --- a/docs/content/4.examples/7.experimental/wasm.md +++ b/docs/content/4.examples/7.experimental/wasm.md @@ -1,8 +1,10 @@ --- -title: "WASM" -description: "This example demonstrates the server-side support of WebAssembly in Nuxt 3." toc: false --- +# WASM + +This example demonstrates the server-side support of WebAssembly in Nuxt 3. + ::sandbox{repo="nuxt/framework" branch="main" dir="examples/experimental/wasm" file="app.vue"} :: diff --git a/docs/content/4.examples/8.other/locale.md b/docs/content/4.examples/8.other/locale.md index f21a56fbcec..8c33b8f3465 100644 --- a/docs/content/4.examples/8.other/locale.md +++ b/docs/content/4.examples/8.other/locale.md @@ -1,8 +1,11 @@ --- -title: "Locale" -description: "This example shows how to define a locale composable to handle the application's locale, both server and client side." +toc: false --- +# Locale + +This example shows how to define a locale composable to handle the application's locale, both server and client side. + ::alert{type=info icon=πŸ’‘} You can right-click to "View Page Source" and see that Nuxt renders the correct date in SSR based on the visitor's locale. :: diff --git a/docs/content/5.community/5.roadmap.md b/docs/content/5.community/5.roadmap.md index f11bfceacf3..84cbb7d680a 100644 --- a/docs/content/5.community/5.roadmap.md +++ b/docs/content/5.community/5.roadmap.md @@ -22,10 +22,10 @@ This page lists the current status and schedule of our planned releases. ## πŸ“… Release Schedule -Release | Expected date | Description ---------------------|-----------------|--------------------------------------------------- -`nuxt@2.16` | Autumn, 2022 | Nuxt v2 cumulative updates for future compatibility with Bridge -`nuxt@3.0.0` | Autumn, 2022 | Nuxt v3 final release +Release | Expected date | Description +--------------------|------------------------|--------------------------------------------------- +`nuxt@2.16` | Autumn, 2022 | Nuxt v2 cumulative updates for future compatibility with Bridge +`nuxt@3.0.0` | 16th November, 2022 | Nuxt v3 final release ### Current Releases @@ -50,14 +50,13 @@ In roadmap below are the major expected features that are coming soon with Nuxt Milestone | Expected date | Notes | Description -------------|------------------|--------|----------------------- -Test Utils | 2022 | [nuxt/framework#3198](https://github.com/nuxt/framework/issues/3198) | A rewrite of [nuxt/test-utils](https://github.com/nuxt/test-utils) for testing Nuxt 3 and new modules Image | 2022 | [nuxt/image#548](https://github.com/nuxt/image/discussions/548) | Stable image optimization for Nuxt 3 +Test Utils | 2022 | [nuxt/framework#3198](https://github.com/nuxt/framework/issues/3198) | A rewrite of [nuxt/test-utils](https://github.com/nuxt/test-utils) for testing Nuxt 3 and new modules SEO & PWA | 2022 | [nuxt/framework#1823](https://github.com/nuxt/framework/discussions/1823) | Migrating from [nuxt-community/pwa-module](https://github.com/nuxt-community/pwa-module) for built-in SEO utils and service worker support -Hybrid Rendering | 2022 | [nuxt/framework#560](https://github.com/nuxt/framework/discussions/560) | Flexible routing routes for caching strategies, proxy and more -Scripts | 2022 | [nuxt/framework#5856](https://github.com/nuxt/framework/discussions/5856) | Easy 3rd party script management. -Devtools | 2022 | - | Integrated and modular devtools experience for Nuxt -Translations | 2022 | [nuxt/translations#4](https://github.com/nuxt/translations/discussions/4) ([request access](https://github.com/nuxt/framework/discussions/765)) | A collaborative project for a stable translation process for Nuxt 3 docs. Currently pending for ideas and documentation tooling support (content v2 with remote sources). -Auth | 2022 | - | A rewrite of [nuxt-community/auth-module](https://github.com/nuxt-community/auth-module) for Nuxt 3 support +Scripts | - | [nuxt/framework#5856](https://github.com/nuxt/framework/discussions/5856) | Easy 3rd party script management. +Devtools | - | - | Integrated and modular devtools experience for Nuxt +Translations | - | [nuxt/translations#4](https://github.com/nuxt/translations/discussions/4) ([request access](https://github.com/nuxt/framework/discussions/765)) | A collaborative project for a stable translation process for Nuxt 3 docs. Currently pending for ideas and documentation tooling support (content v2 with remote sources). +Auth | - | - | A rewrite of [nuxt-community/auth-module](https://github.com/nuxt-community/auth-module) for Nuxt 3 support ## πŸ“¦ Core Modules @@ -65,8 +64,7 @@ In addition to the Nuxt framework, there are modules that are vital for the ecos Module | Status | Nuxt Support | Repository | Description ---------------|---------------------|--------------|------------|------------------- -Content 1.x | Maintenance | 2.x | [nuxt/content](https://github.com/nuxt/content/tree/v1) | Maintenance only -Content 2.x | Active | 3.x | [nuxt/content](https://github.com/nuxt/content) | Released -Auth | WIP | 3.x | `nuxt/auth` to be announced | Nuxt 3 support is planned after session support +Content | Active | 3.x | [nuxt/content](https://github.com/nuxt/content) | Released +Auth | Planned | 3.x | `nuxt/auth` to be announced | Nuxt 3 support is planned after session support Image | Active | 2.x and 3.x | [nuxt/image](https://github.com/nuxt/image) | Nuxt 3 support is in progress: [nuxt/image#548](https://github.com/nuxt/image/discussions/548) Telemetry | Active | 2.x and 3.x | [nuxt/telemetry](https://github.com/nuxt/telemetry/) | Nuxt 3 is supported. Stats to be public soon! diff --git a/docs/content/7.migration/20.module-authors.md b/docs/content/7.migration/20.module-authors.md index 75d4a5e721e..2d6f10183f1 100644 --- a/docs/content/7.migration/20.module-authors.md +++ b/docs/content/7.migration/20.module-authors.md @@ -22,7 +22,7 @@ By using [vue-demi](https://github.com/vueuse/vue-demi) they should be compatibl ## Module Migration -When Nuxt 3 users add your module, a compatible module container layer from `@nuxt/kit` is **automatically injected**, so as long as your code is following the guidelines below, it should continue working as-is. +When Nuxt 3 users add your module, you will not have access to the module container (`this.*`) so you will need to use utilities from `@nuxt/kit` to access the container functionality. ### Test with `@nuxt/bridge` diff --git a/docs/content/7.migration/7.component-options.md b/docs/content/7.migration/7.component-options.md index 13abbfcb431..a6998cff20e 100644 --- a/docs/content/7.migration/7.component-options.md +++ b/docs/content/7.migration/7.component-options.md @@ -11,7 +11,7 @@ Nuxt 3 provides new options for [fetching data from an API](/getting-started/dat In Nuxt 2 you might use `@nuxtjs/axios` or `@nuxt/http` to fetch your data - or just the polyfilled global `fetch`. -In Nuxt 3 you can use a globally available `fetch` method that has the same API as [the Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) or `$fetch` method which is using [unjs/ohmyfetch](https://github.com/unjs/ohmyfetch). It has a number of benefits, including: +In Nuxt 3 you can use a globally available `fetch` method that has the same API as [the Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) or `$fetch` method which is using [unjs/ofetch](https://github.com/unjs/ofetch). It has a number of benefits, including: 1. It will handle 'smartly' making [direct API calls](/guide/concepts/server-engine#direct-api-calls) if it's running on the server, or making a client-side call to your API if it's running on the client. (It can also handle calling third-party APIs.) diff --git a/docs/package.json b/docs/package.json index 38db4770d2c..f03a23d23fb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -12,9 +12,9 @@ "@nuxt-themes/website": "0.1.9", "jiti": "^1.16.0", "nuxt": "^3.0.0-rc.12", - "pathe": "^0.3.9", - "scule": "^0.3.2", - "untyped": "^0.5.0" + "pathe": "^1.0.0", + "scule": "^1.0.0", + "untyped": "^1.0.0" }, "packageManager": "yarn@3.2.4" } diff --git a/docs/yarn.lock b/docs/yarn.lock index 1866b00ea49..b428bfbf925 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -257,6 +257,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.20.2": + version: 7.20.2 + resolution: "@babel/core@npm:7.20.2" + dependencies: + "@ampproject/remapping": ^2.1.0 + "@babel/code-frame": ^7.18.6 + "@babel/generator": ^7.20.2 + "@babel/helper-compilation-targets": ^7.20.0 + "@babel/helper-module-transforms": ^7.20.2 + "@babel/helpers": ^7.20.1 + "@babel/parser": ^7.20.2 + "@babel/template": ^7.18.10 + "@babel/traverse": ^7.20.1 + "@babel/types": ^7.20.2 + convert-source-map: ^1.7.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.1 + semver: ^6.3.0 + checksum: 98faaaef26103a276a30a141b951a93bc8418d100d1f668bf7a69d12f3e25df57958e8b6b9100d95663f720db62da85ade736f6629a5ebb1e640251a1b43c0e4 + languageName: node + linkType: hard + "@babel/generator@npm:^7.19.6, @babel/generator@npm:^7.20.1": version: 7.20.1 resolution: "@babel/generator@npm:7.20.1" @@ -268,6 +291,17 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.20.2": + version: 7.20.4 + resolution: "@babel/generator@npm:7.20.4" + dependencies: + "@babel/types": ^7.20.2 + "@jridgewell/gen-mapping": ^0.3.2 + jsesc: ^2.5.1 + checksum: 967b59f18e5ce999e5a741825bcecb2be4bbfc1824a92c21b47d0b5694e0eb09314a70f8b9142e9591c149c7fb83d51f73ae8fbd96d30a42666425889e51ceb1 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-annotate-as-pure@npm:7.18.6" @@ -277,7 +311,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.19.3": +"@babel/helper-compilation-targets@npm:^7.19.3, @babel/helper-compilation-targets@npm:^7.20.0": version: 7.20.0 resolution: "@babel/helper-compilation-targets@npm:7.20.0" dependencies: @@ -368,6 +402,22 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.20.2": + version: 7.20.2 + resolution: "@babel/helper-module-transforms@npm:7.20.2" + dependencies: + "@babel/helper-environment-visitor": ^7.18.9 + "@babel/helper-module-imports": ^7.18.6 + "@babel/helper-simple-access": ^7.20.2 + "@babel/helper-split-export-declaration": ^7.18.6 + "@babel/helper-validator-identifier": ^7.19.1 + "@babel/template": ^7.18.10 + "@babel/traverse": ^7.20.1 + "@babel/types": ^7.20.2 + checksum: 33a60ca115f6fce2c9d98e2a2e5649498aa7b23e2ae3c18745d7a021487708fc311458c33542f299387a0da168afccba94116e077f2cce49ae9e5ab83399e8a2 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-optimise-call-expression@npm:7.18.6" @@ -406,6 +456,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.20.2": + version: 7.20.2 + resolution: "@babel/helper-simple-access@npm:7.20.2" + dependencies: + "@babel/types": ^7.20.2 + checksum: ad1e96ee2e5f654ffee2369a586e5e8d2722bf2d8b028a121b4c33ebae47253f64d420157b9f0a8927aea3a9e0f18c0103e74fdd531815cf3650a0a4adca11a1 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-split-export-declaration@npm:7.18.6" @@ -436,7 +495,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.19.4": +"@babel/helpers@npm:^7.19.4, @babel/helpers@npm:^7.20.1": version: 7.20.1 resolution: "@babel/helpers@npm:7.20.1" dependencies: @@ -467,6 +526,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.20.2": + version: 7.20.3 + resolution: "@babel/parser@npm:7.20.3" + bin: + parser: ./bin/babel-parser.js + checksum: 33bcdb45de65a3cf27ed376cb34f32be3c3485a10e3252f8d0126f6a034efc3145c0d219e57fcd5a8956361552008bc30b9bae4a723823fb3633027071be8a45 + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.0.0": version: 7.18.6 resolution: "@babel/plugin-syntax-jsx@npm:7.18.6" @@ -518,6 +586,13 @@ __metadata: languageName: node linkType: hard +"@babel/standalone@npm:^7.20.4": + version: 7.20.4 + resolution: "@babel/standalone@npm:7.20.4" + checksum: cfc549333b0e779b7b33e3fe491912562818d4b2fab82e475fd51c92302a03265bb845e8a9c95c765bb5f33625e4d3c24d33075694221241c5555060102721e8 + languageName: node + linkType: hard + "@babel/template@npm:^7.0.0, @babel/template@npm:^7.18.10": version: 7.18.10 resolution: "@babel/template@npm:7.18.10" @@ -558,6 +633,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.20.2": + version: 7.20.2 + resolution: "@babel/types@npm:7.20.2" + dependencies: + "@babel/helper-string-parser": ^7.19.4 + "@babel/helper-validator-identifier": ^7.19.1 + to-fast-properties: ^2.0.0 + checksum: 57e76e5f21876135f481bfd4010c87f2d38196bb0a2bc60a28d6e55e3afa90cdd9accf164e4cb71bdfb620517fa0a0cb5600cdce36c21d59fdaccfbb899c024c + languageName: node + linkType: hard + "@cloudflare/kv-asset-handler@npm:^0.2.0": version: 0.2.0 resolution: "@cloudflare/kv-asset-handler@npm:0.2.0" @@ -3546,9 +3632,9 @@ __metadata: "@nuxt-themes/website": 0.1.9 jiti: ^1.16.0 nuxt: ^3.0.0-rc.12 - pathe: ^0.3.9 - scule: ^0.3.2 - untyped: ^0.5.0 + pathe: ^1.0.0 + scule: ^1.0.0 + untyped: ^1.0.0 languageName: unknown linkType: soft @@ -7594,6 +7680,13 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.0.0": + version: 1.0.0 + resolution: "pathe@npm:1.0.0" + checksum: 7b71a4930a5b46111c92149632f74b0e87bade3eabe6c9168dcc4846857a4e124eacc0c2bf044fe0d2a8b7f87ae62b9b2cb11938c61899d485cc36dd1a243a23 + languageName: node + linkType: hard + "perfect-debounce@npm:^0.1.3": version: 0.1.3 resolution: "perfect-debounce@npm:0.1.3" @@ -8884,6 +8977,13 @@ __metadata: languageName: node linkType: hard +"scule@npm:^1.0.0": + version: 1.0.0 + resolution: "scule@npm:1.0.0" + checksum: 57f745022ef391868c6adfc77cd8bf1e8a10096cb4e7ba7bbb04f57fab5651804b419da9435692cd012abf1fd020f4b3f823385536f4ddc7247ea725488451c4 + languageName: node + linkType: hard + "search-insights@npm:^2.1.0": version: 2.2.1 resolution: "search-insights@npm:2.2.1" @@ -9965,6 +10065,18 @@ __metadata: languageName: node linkType: hard +"untyped@npm:^1.0.0": + version: 1.0.0 + resolution: "untyped@npm:1.0.0" + dependencies: + "@babel/core": ^7.20.2 + "@babel/standalone": ^7.20.4 + "@babel/types": ^7.20.2 + scule: ^1.0.0 + checksum: 79359734c6fa02565339f15f4afba0397b18709a7cc6fb9884eba9d63c8362382d8788844e6b19f0a938ac88ad6ed2bbe1dd51842cadeca6e1ec95e3e0aa6c51 + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.0.9": version: 1.0.10 resolution: "update-browserslist-db@npm:1.0.10" diff --git a/examples/advanced/config-extends/package.json b/examples/advanced/config-extends/package.json index 11bb431d3e2..a52661b5402 100644 --- a/examples/advanced/config-extends/package.json +++ b/examples/advanced/config-extends/package.json @@ -3,7 +3,7 @@ "private": true, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" }, "scripts": { "dev": "nuxi dev", diff --git a/examples/advanced/jsx/package.json b/examples/advanced/jsx/package.json index 24f56476d10..e7f53ab6380 100644 --- a/examples/advanced/jsx/package.json +++ b/examples/advanced/jsx/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/advanced/module-extend-pages/package.json b/examples/advanced/module-extend-pages/package.json index 1775183a7f0..95d8f992965 100644 --- a/examples/advanced/module-extend-pages/package.json +++ b/examples/advanced/module-extend-pages/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/advanced/testing/package.json b/examples/advanced/testing/package.json index a4b8bc57aef..57273de7051 100644 --- a/examples/advanced/testing/package.json +++ b/examples/advanced/testing/package.json @@ -5,11 +5,11 @@ "build": "nuxi build", "dev": "nuxi dev", "start": "nuxi preview", - "test": "vitest run" + "test": "nuxi test" }, "devDependencies": { - "@nuxt/test-utils": "^3.0.0-rc.12", - "nuxt": "^3.0.0-rc.12", + "@nuxt/test-utils": "^3.0.0-rc.13", + "nuxt": "^3.0.0-rc.13", "vitest": "latest" } } diff --git a/examples/advanced/testing/tests/basic.test.ts b/examples/advanced/testing/tests/basic.test.ts index 9768bca1bd8..696e3ec9404 100644 --- a/examples/advanced/testing/tests/basic.test.ts +++ b/examples/advanced/testing/tests/basic.test.ts @@ -1,13 +1,7 @@ -import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' -import { setup, $fetch, isDev } from '@nuxt/test-utils' - -describe('example', async () => { - await setup({ - rootDir: fileURLToPath(new URL('..', import.meta.url)), - server: true - }) +import { $fetch, isDev } from '@nuxt/test-utils' +describe('example', () => { it('Renders Hello Nuxt', async () => { expect(await $fetch('/')).toMatch('Hello Nuxt!') }) diff --git a/examples/app-config/package.json b/examples/app-config/package.json index 575c41ab7cc..fca3db828e9 100644 --- a/examples/app-config/package.json +++ b/examples/app-config/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/app/error-handling/package.json b/examples/app/error-handling/package.json index efe7e9a5f9f..b6ac76dd820 100644 --- a/examples/app/error-handling/package.json +++ b/examples/app/error-handling/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/app/plugins/package.json b/examples/app/plugins/package.json index 34ff41c9bad..8dd698d62f5 100644 --- a/examples/app/plugins/package.json +++ b/examples/app/plugins/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/app/teleport/package.json b/examples/app/teleport/package.json index 72eda7a3323..9f448979184 100644 --- a/examples/app/teleport/package.json +++ b/examples/app/teleport/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/auto-imports/components/package.json b/examples/auto-imports/components/package.json index b1c9d42db5d..0f9a6da90fa 100644 --- a/examples/auto-imports/components/package.json +++ b/examples/auto-imports/components/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/auto-imports/composables/package.json b/examples/auto-imports/composables/package.json index eb0f4f93df0..f72a89922ff 100644 --- a/examples/auto-imports/composables/package.json +++ b/examples/auto-imports/composables/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/composables/use-async-data/package.json b/examples/composables/use-async-data/package.json index 13bb4cc66f8..70e08924b15 100644 --- a/examples/composables/use-async-data/package.json +++ b/examples/composables/use-async-data/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/composables/use-async-data/server/api/hello/[slug].ts b/examples/composables/use-async-data/server/api/hello/[slug].ts index ef0eb68aba8..0cec73da7fd 100644 --- a/examples/composables/use-async-data/server/api/hello/[slug].ts +++ b/examples/composables/use-async-data/server/api/hello/[slug].ts @@ -1 +1 @@ -export default defineEventHandler(event => `Hello world (${event.req.url.substr(1)}) (Generated at ${new Date().toUTCString()})`) +export default defineEventHandler(event => `Hello world (${event.node.req.url.substr(1)}) (Generated at ${new Date().toUTCString()})`) diff --git a/examples/composables/use-cookie/package.json b/examples/composables/use-cookie/package.json index 1015f1e58cf..577e2c3ff4c 100644 --- a/examples/composables/use-cookie/package.json +++ b/examples/composables/use-cookie/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/composables/use-fetch/package.json b/examples/composables/use-fetch/package.json index 627b0f7cbee..4f62631fa78 100644 --- a/examples/composables/use-fetch/package.json +++ b/examples/composables/use-fetch/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/composables/use-head/app.vue b/examples/composables/use-head/app.vue index 3c19f0731ac..335ffbd8f90 100644 --- a/examples/composables/use-head/app.vue +++ b/examples/composables/use-head/app.vue @@ -12,7 +12,6 @@ <Title>Luck number: {{ dynamic }} - diff --git a/examples/composables/use-head/package.json b/examples/composables/use-head/package.json index 47bd9676050..e2942df1e44 100644 --- a/examples/composables/use-head/package.json +++ b/examples/composables/use-head/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/composables/use-state/package.json b/examples/composables/use-state/package.json index 907ee596dcc..da41d9d5c09 100644 --- a/examples/composables/use-state/package.json +++ b/examples/composables/use-state/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/essentials/hello-world/package.json b/examples/essentials/hello-world/package.json index d32d33ac4e5..49c49dd361b 100644 --- a/examples/essentials/hello-world/package.json +++ b/examples/essentials/hello-world/package.json @@ -7,6 +7,6 @@ "start": "nuxi preview" }, "devDependencies": { - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/experimental/reactivity-transform/package.json b/examples/experimental/reactivity-transform/package.json index e7a05492170..3c44ef44329 100644 --- a/examples/experimental/reactivity-transform/package.json +++ b/examples/experimental/reactivity-transform/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/experimental/vite-node/package.json b/examples/experimental/vite-node/package.json index 94cea58bde6..885d16d8d03 100644 --- a/examples/experimental/vite-node/package.json +++ b/examples/experimental/vite-node/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/experimental/wasm/package.json b/examples/experimental/wasm/package.json index 06040a826f3..b5a3f51f58e 100644 --- a/examples/experimental/wasm/package.json +++ b/examples/experimental/wasm/package.json @@ -3,7 +3,7 @@ "private": true, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" }, "scripts": { "dev": "nuxi dev", diff --git a/examples/experimental/wasm/server/api/sum.ts b/examples/experimental/wasm/server/api/sum.ts index 67861970131..fbfd774cd88 100644 --- a/examples/experimental/wasm/server/api/sum.ts +++ b/examples/experimental/wasm/server/api/sum.ts @@ -1,6 +1,6 @@ -import { defineLazyHandler } from 'h3' +import { defineLazyEventHandler } from 'h3' -export default defineLazyHandler(async () => { +export default defineLazyEventHandler(async () => { const { exports: { sum } } = await loadWasmInstance( // @ts-ignore () => import('~/server/wasm/sum.wasm') diff --git a/examples/other/locale/composables/locale.ts b/examples/other/locale/composables/locale.ts index 991ab9678f7..931a0124bb3 100644 --- a/examples/other/locale/composables/locale.ts +++ b/examples/other/locale/composables/locale.ts @@ -6,8 +6,7 @@ export const useDefaultLocale = (fallback = 'en-US') => { const locale = ref(fallback) if (process.server) { // Learn more about the nuxtApp interface on https://v3.nuxtjs.org/docs/usage/nuxt-app#nuxtapp-interface-advanced - const nuxtApp = useNuxtApp() - const reqLocale = nuxtApp.ssrContext?.req.headers['accept-language']?.split(',')[0] + const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0] if (reqLocale) { locale.value = reqLocale } diff --git a/examples/other/locale/package.json b/examples/other/locale/package.json index 6a6c6eb6eb5..f65ab3c3302 100644 --- a/examples/other/locale/package.json +++ b/examples/other/locale/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/routing/layouts/package.json b/examples/routing/layouts/package.json index 6a6f0cb7ffb..996d84532ed 100644 --- a/examples/routing/layouts/package.json +++ b/examples/routing/layouts/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/routing/middleware/package.json b/examples/routing/middleware/package.json index 1698a171626..094951d53fb 100644 --- a/examples/routing/middleware/package.json +++ b/examples/routing/middleware/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/routing/nuxt-link/package.json b/examples/routing/nuxt-link/package.json index b7fb1a206d8..888886e957b 100644 --- a/examples/routing/nuxt-link/package.json +++ b/examples/routing/nuxt-link/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/routing/pages/package.json b/examples/routing/pages/package.json index 074981653d4..b5d0b137853 100644 --- a/examples/routing/pages/package.json +++ b/examples/routing/pages/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/routing/universal-router/package.json b/examples/routing/universal-router/package.json index 96cbd4a87a5..0a85260d4b4 100644 --- a/examples/routing/universal-router/package.json +++ b/examples/routing/universal-router/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/examples/server/routes/package.json b/examples/server/routes/package.json index f472b0a0d4d..717b3952b69 100644 --- a/examples/server/routes/package.json +++ b/examples/server/routes/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.3", - "nuxt": "^3.0.0-rc.12" + "nuxt": "^3.0.0-rc.13" } } diff --git a/package.json b/package.json index c23699cda1a..29d3c166146 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,9 @@ "nuxi": "workspace:*", "nuxt": "workspace:*", "nuxt3": "workspace:nuxt@*", - "unbuild": "^0.9.4", - "vite": "^3.2.2", - "vue": "3.2.41" + "unbuild": "^1.0.0", + "vite": "^3.2.4", + "vue": "3.2.45" }, "devDependencies": { "@actions/core": "^1.10.0", @@ -51,11 +51,11 @@ "@types/node": "^18.11.9", "@types/rimraf": "^3", "@types/semver": "^7", - "@unocss/reset": "^0.46.3", + "@unocss/reset": "^0.46.5", "case-police": "^0.5.10", - "changelogen": "^0.3.5", + "changelogen": "^0.4.0", "crawler": "^1.3.0", - "eslint": "^8.26.0", + "eslint": "^8.27.0", "eslint-plugin-jsdoc": "^39.6.2", "execa": "^6.1.0", "expect-type": "^0.15.0", @@ -64,19 +64,19 @@ "markdownlint-cli": "^0.32.2", "nuxi": "workspace:*", "nuxt": "workspace:*", - "ohmyfetch": "^0.4.21", - "pathe": "^0.3.9", + "ofetch": "^1.0.0", + "pathe": "^1.0.0", "rimraf": "^3.0.2", "semver": "^7.3.8", - "std-env": "^3.3.0", - "typescript": "^4.8.4", - "ufo": "^0.8.6", - "unbuild": "^0.9.4", - "vite": "^3.2.2", - "vitest": "^0.24.5", + "std-env": "^3.3.1", + "typescript": "^4.9.3", + "ufo": "^1.0.0", + "unbuild": "^1.0.0", + "vite": "^3.2.4", + "vitest": "^0.25.2", "vue-tsc": "^1.0.9" }, - "packageManager": "pnpm@7.14.2", + "packageManager": "pnpm@7.16.0", "engines": { "node": "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } diff --git a/packages/kit/package.json b/packages/kit/package.json index 1c359112b73..53833957c88 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -1,6 +1,6 @@ { "name": "@nuxt/kit", - "version": "3.0.0-rc.13", + "version": "3.0.0-rc.14", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -13,24 +13,24 @@ "prepack": "unbuild" }, "dependencies": { - "@nuxt/schema": "3.0.0-rc.13", - "c12": "^0.2.13", + "@nuxt/schema": "3.0.0-rc.14", + "c12": "^1.0.1", "consola": "^2.15.3", - "defu": "^6.1.0", + "defu": "^6.1.1", "globby": "^13.1.2", "hash-sum": "^2.0.0", "ignore": "^5.2.0", "jiti": "^1.16.0", - "knitwork": "^0.1.2", + "knitwork": "^1.0.0", "lodash.template": "^4.5.0", - "mlly": "^0.5.16", - "pathe": "^0.3.9", - "pkg-types": "^0.3.6", - "scule": "^0.3.2", + "mlly": "^1.0.0", + "pathe": "^1.0.0", + "pkg-types": "^1.0.1", + "scule": "^1.0.0", "semver": "^7.3.8", - "unctx": "^2.0.2", - "unimport": "^0.7.0", - "untyped": "^0.5.0" + "unctx": "^2.1.0", + "unimport": "^1.0.0", + "untyped": "^1.0.0" }, "devDependencies": { "@types/lodash.template": "^4", diff --git a/packages/kit/src/build.ts b/packages/kit/src/build.ts index b602b8a45d8..aefc7e629a0 100644 --- a/packages/kit/src/build.ts +++ b/packages/kit/src/build.ts @@ -30,13 +30,6 @@ export interface ExtendConfigOptions { } export interface ExtendWebpackConfigOptions extends ExtendConfigOptions { - /** - * Install plugin on modern build - * - * @default true - * @deprecated Nuxt 2 only - */ - modern?: boolean } export interface ExtendViteConfigOptions extends ExtendConfigOptions {} @@ -73,13 +66,6 @@ export function extendWebpackConfig ( fn(config) } } - // Nuxt 2 backwards compatibility - if (options.modern !== false) { - const config = configs.find(i => i.name === 'modern') - if (config) { - fn(config) - } - } }) } diff --git a/packages/kit/src/components.ts b/packages/kit/src/components.ts index 81181fda4ed..8bd96e41014 100644 --- a/packages/kit/src/components.ts +++ b/packages/kit/src/components.ts @@ -1,6 +1,5 @@ import { pascalCase, kebabCase } from 'scule' import type { ComponentsDir, Component } from '@nuxt/schema' -import { genDynamicImport } from 'knitwork' import { useNuxt } from './context' import { assertNuxtCompatibility } from './compatibility' @@ -40,14 +39,7 @@ export async function addComponent (opts: AddComponentOptions) { prefetch: false, preload: false, mode: 'all', - - // Nuxt 2 support shortPath: opts.filePath, - async: false, - level: 0, - asyncImport: `${genDynamicImport(opts.filePath)}.then(r => r['${opts.export || 'default'}'])`, - import: `require(${JSON.stringify(opts.filePath)})['${opts.export || 'default'}']`, - ...opts } diff --git a/packages/kit/src/imports.ts b/packages/kit/src/imports.ts index d8ce03ef87f..cd532351cfa 100644 --- a/packages/kit/src/imports.ts +++ b/packages/kit/src/imports.ts @@ -6,40 +6,26 @@ import { assertNuxtCompatibility } from './compatibility' export function addImports (imports: Import | Import[]) { assertNuxtCompatibility({ bridge: true }) - // TODO: Use imports:* when widely adopted - useNuxt().hook('autoImports:extend', (_imports) => { + useNuxt().hook('imports:extend', (_imports) => { _imports.push(...(Array.isArray(imports) ? imports : [imports])) - }, { allowDeprecated: true }) + }) } -/** - * @deprecated Please use `addImports` instead with nuxt>=3.0.0-rc.9 - */ -export const addAutoImport = addImports - export function addImportsDir (dirs: string | string[]) { assertNuxtCompatibility({ bridge: true }) - // TODO: Use imports:* when widely adopted - useNuxt().hook('autoImports:dirs', (_dirs: string[]) => { + useNuxt().hook('imports:dirs', (_dirs: string[]) => { for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) { _dirs.push(dir) } - }, { allowDeprecated: true }) + }) } - -/** - * @deprecated Please use `addImportsDir` instead with nuxt>=3.0.0-rc.9 - */ -export const addAutoImportDir = addImportsDir - export function addImportsSources (presets: ImportPresetWithDeprecation | ImportPresetWithDeprecation[]) { assertNuxtCompatibility({ bridge: true }) - // TODO: Use imports:* when widely adopted - useNuxt().hook('autoImports:sources', (_presets: ImportPresetWithDeprecation[]) => { + useNuxt().hook('imports:sources', (_presets: ImportPresetWithDeprecation[]) => { for (const preset of (Array.isArray(presets) ? presets : [presets])) { _presets.push(preset) } - }, { allowDeprecated: true }) + }) } diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts index e5f991dee8f..5c05b74ed71 100644 --- a/packages/kit/src/index.ts +++ b/packages/kit/src/index.ts @@ -1,5 +1,4 @@ // Module -export * from './module/container' export * from './module/define' export * from './module/install' diff --git a/packages/kit/src/internal/cjs.ts b/packages/kit/src/internal/cjs.ts index 8103c5ea37b..fbc724959b8 100644 --- a/packages/kit/src/internal/cjs.ts +++ b/packages/kit/src/internal/cjs.ts @@ -6,10 +6,12 @@ import jiti from 'jiti' // TODO: use create-require for jest environment const _require = jiti(process.cwd(), { interopDefault: true, esmResolve: true }) +/** @deprecated Do not use CJS utils */ export interface ResolveModuleOptions { paths?: string | string[] } +/** @deprecated Do not use CJS utils */ export interface RequireModuleOptions extends ResolveModuleOptions { // TODO: use create-require for jest environment // native?: boolean @@ -20,11 +22,13 @@ export interface RequireModuleOptions extends ResolveModuleOptions { interopDefault?: boolean } +/** @deprecated Do not use CJS utils */ export function isNodeModules (id: string) { // TODO: Follow symlinks return /[/\\]node_modules[/\\]/.test(id) } +/** @deprecated Do not use CJS utils */ export function clearRequireCache (id: string) { if (isNodeModules(id)) { return @@ -48,6 +52,7 @@ export function clearRequireCache (id: string) { delete _require.cache[id] } +/** @deprecated Do not use CJS utils */ export function scanRequireTree (id: string, files = new Set()) { if (isNodeModules(id) || files.has(id)) { return files @@ -69,7 +74,7 @@ export function scanRequireTree (id: string, files = new Set()) { return files } -/** Access the require cache by module id. */ +/** @deprecated Do not use CJS utils */ export function getRequireCacheItem (id: string) { try { return _require.cache[id] @@ -82,7 +87,7 @@ export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) { return requireModule(join(id, 'package.json'), opts) } -/** Resolve the path of a module. */ +/** @deprecated Do not use CJS utils */ export function resolveModule (id: string, opts: ResolveModuleOptions = {}) { return normalize(_require.resolve(id, { paths: ([] as string[]).concat( @@ -96,7 +101,7 @@ export function resolveModule (id: string, opts: ResolveModuleOptions = {}) { })) } -/** Try to resolve the path of a module, but don't emit an error if it can't be found. */ +/** @deprecated Do not use CJS utils */ export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}): string | null { try { return resolveModule(path, opts) @@ -108,7 +113,7 @@ export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}) return null } -/** Require a module and return it. */ +/** @deprecated Do not use CJS utils */ export function requireModule (id: string, opts: RequireModuleOptions = {}) { // Resolve id const resolvedPath = resolveModule(id, opts) @@ -124,6 +129,7 @@ export function requireModule (id: string, opts: RequireModuleOptions = {}) { return requiredModule } +/** @deprecated Do not use CJS utils */ export function importModule (id: string, opts: RequireModuleOptions = {}) { const resolvedPath = resolveModule(id, opts) if (opts.interopDefault !== false) { @@ -132,13 +138,14 @@ export function importModule (id: string, opts: RequireModuleOptions = {}) { return import(pathToFileURL(resolvedPath).href) } +/** @deprecated Do not use CJS utils */ export function tryImportModule (id: string, opts: RequireModuleOptions = {}) { try { return importModule(id, opts).catch(() => undefined) } catch { } } -/** Try to require a module, but don't emit an error if the module can't be required. */ +/** @deprecated Do not use CJS utils */ export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) { try { return requireModule(id, opts) diff --git a/packages/kit/src/internal/template.ts b/packages/kit/src/internal/template.ts index 19115415154..cb2414b7a55 100644 --- a/packages/kit/src/internal/template.ts +++ b/packages/kit/src/internal/template.ts @@ -4,6 +4,7 @@ import { genSafeVariableName, genDynamicImport, genImport } from 'knitwork' import type { NuxtTemplate } from '@nuxt/schema' +/** @deprecated */ export async function compileTemplate (template: NuxtTemplate, ctx: any) { const data = { ...ctx, options: template.options } if (template.src) { diff --git a/packages/kit/src/module/container.ts b/packages/kit/src/module/container.ts deleted file mode 100644 index 3d732695295..00000000000 --- a/packages/kit/src/module/container.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { relative } from 'pathe' -import type { Nuxt, ModuleContainer } from '@nuxt/schema' -import { chainFn } from '../internal/task' -import { addTemplate } from '../template' -import { addLayout } from '../layout' -import { isNuxt2 } from '../compatibility' -import { addPluginTemplate } from '../plugin' -import { useNuxt } from '../context' -import { installModule } from './install' - -const MODULE_CONTAINER_KEY = '__module_container__' - -export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer { - // @ts-ignore - if (nuxt[MODULE_CONTAINER_KEY]) { return nuxt[MODULE_CONTAINER_KEY] } - - async function requireModule (moduleOpts: any) { - let src, inlineOptions - if (typeof moduleOpts === 'string') { - src = moduleOpts - } else if (Array.isArray(moduleOpts)) { - [src, inlineOptions] = moduleOpts - } else if (typeof moduleOpts === 'object') { - if (moduleOpts.src || moduleOpts.handler) { - src = moduleOpts.src || moduleOpts.handler - inlineOptions = moduleOpts.options - } else { - src = moduleOpts - } - } else { - src = moduleOpts - } - await installModule(src, inlineOptions) - } - - const container: ModuleContainer = { - nuxt, - options: nuxt.options, - - ready () { return Promise.resolve() }, - addVendor () {}, - - requireModule, - addModule: requireModule, - - // TODO - addServerMiddleware: () => { }, - - addTemplate (template) { - if (typeof template === 'string') { - template = { src: template } - } - if (template.write === undefined) { - template.write = true - } - return addTemplate(template) - }, - - addPlugin (pluginTemplate) { - return addPluginTemplate(pluginTemplate) - }, - - addLayout (tmpl, name) { - return addLayout(tmpl, name) - }, - - addErrorLayout (dst) { - const relativeBuildDir = relative(nuxt.options.rootDir, nuxt.options.buildDir) - ;(nuxt as any).options.ErrorPage = `~/${relativeBuildDir}/${dst}` - }, - - extendBuild (fn) { - // @ts-ignore - nuxt.options.build.extend = chainFn(nuxt.options.build.extend, fn) - - if (!isNuxt2(nuxt)) { - console.warn('[kit] [compat] Using `extendBuild` in Nuxt 3 has no effect. Instead call extendWebpackConfig and extendViteConfig.') - } - }, - - extendRoutes (fn) { - if (isNuxt2(nuxt)) { - (nuxt.options.router as any).extendRoutes = chainFn((nuxt.options.router as any).extendRoutes, fn) - } else { - nuxt.hook('pages:extend', async (pages, ...args) => { - const maybeRoutes = await fn(pages, ...args) - if (maybeRoutes) { - console.warn('[kit] [compat] Using `extendRoutes` in Nuxt 3 needs to directly modify first argument instead of returning updated routes. Skipping extended routes.') - } - }) - } - } - } - - // @ts-ignore - nuxt[MODULE_CONTAINER_KEY] = container - - // @ts-ignore - return nuxt[MODULE_CONTAINER_KEY] -} diff --git a/packages/kit/src/module/define.ts b/packages/kit/src/module/define.ts index 861f65d1aac..26d46f04e6b 100644 --- a/packages/kit/src/module/define.ts +++ b/packages/kit/src/module/define.ts @@ -13,20 +13,10 @@ import { templateUtils, compileTemplate } from '../internal/template' * any hooks that are provided, and calling an optional setup function for full control. */ export function defineNuxtModule (definition: ModuleDefinition): NuxtModule { - // Legacy format. TODO: Remove in RC - if (typeof definition === 'function') { - // @ts-ignore - definition = definition(useNuxt()) - logger.warn('Module definition as function is deprecated and will be removed in the future versions', definition) - } - // Normalize definition and meta if (!definition.meta) { definition.meta = {} } - if (!definition.meta.configKey) { - // @ts-ignore TODO: Remove non-meta fallbacks in RC - definition.meta.name = definition.meta.name || definition.name - // @ts-ignore - definition.meta.configKey = definition.configKey || definition.meta.name + if (definition.meta.configKey === undefined) { + definition.meta.configKey = definition.meta.name } // Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema diff --git a/packages/kit/src/module/install.ts b/packages/kit/src/module/install.ts index e27492e49f1..733bfe8ca66 100644 --- a/packages/kit/src/module/install.ts +++ b/packages/kit/src/module/install.ts @@ -2,7 +2,6 @@ import type { Nuxt, NuxtModule } from '@nuxt/schema' import { useNuxt } from '../context' import { resolveModule, requireModule, importModule } from '../internal/cjs' import { resolveAlias } from '../resolve' -import { useModuleContainer } from './container' /** Installs a module on a Nuxt instance. */ export async function installModule (moduleToInstall: string | NuxtModule, _inlineOptions?: any, _nuxt?: Nuxt) { @@ -10,12 +9,11 @@ export async function installModule (moduleToInstall: string | NuxtModule, _inli const { nuxtModule, inlineOptions } = await normalizeModule(moduleToInstall, _inlineOptions) // Call module - await nuxtModule.call( - // Provide this context for backwards compatibility with Nuxt 2 - useModuleContainer() as any, - inlineOptions, - nuxt - ) + await nuxtModule(inlineOptions, nuxt) + + if (typeof moduleToInstall === 'string') { + nuxt.options.build.transpile.push(moduleToInstall) + } nuxt.options._installedModules = nuxt.options._installedModules || [] nuxt.options._installedModules.push({ @@ -29,14 +27,6 @@ export async function installModule (moduleToInstall: string | NuxtModule, _inli async function normalizeModule (nuxtModule: string | NuxtModule, inlineOptions?: any) { const nuxt = useNuxt() - // Detect if `installModule` used with older signuture (nuxt, nuxtModule) - // TODO: Remove in RC - // @ts-ignore - if (nuxtModule?._version || nuxtModule?.version || nuxtModule?.constructor?.version || '') { - [nuxtModule, inlineOptions] = [inlineOptions, {}] - console.warn(new Error('`installModule` is being called with old signature!')) - } - // Import if input is string if (typeof nuxtModule === 'string') { const _src = resolveModule(resolveAlias(nuxtModule), { paths: nuxt.options.modulesDir }) diff --git a/packages/kit/src/resolve.ts b/packages/kit/src/resolve.ts index a9e6d3300bb..9964a904b4c 100644 --- a/packages/kit/src/resolve.ts +++ b/packages/kit/src/resolve.ts @@ -83,7 +83,7 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}): /** * Try to resolve first existing file in paths */ -export async function findPath (paths: string|string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise { +export async function findPath (paths: string | string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise { if (!Array.isArray(paths)) { paths = [paths] } @@ -110,8 +110,8 @@ export function resolveAlias (path: string, alias?: Record): str } export interface Resolver { - resolve(...path: string[]): string - resolvePath(path: string, opts?: ResolvePathOptions): Promise + resolve (...path: string[]): string + resolvePath (path: string, opts?: ResolvePathOptions): Promise } /** diff --git a/packages/kit/src/template.ts b/packages/kit/src/template.ts index 01e2f481ac7..cbf0682eab5 100644 --- a/packages/kit/src/template.ts +++ b/packages/kit/src/template.ts @@ -45,7 +45,7 @@ export function normalizeTemplate (template: NuxtTemplate | string): Resolv } if (!template.filename) { const srcPath = parse(template.src) - template.filename = template.fileName || + template.filename = (template as any).fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(template.src)}${srcPath.ext}` } } diff --git a/packages/nuxi/package.json b/packages/nuxi/package.json index 8496d1edb13..b2913ee0672 100644 --- a/packages/nuxi/package.json +++ b/packages/nuxi/package.json @@ -1,6 +1,6 @@ { "name": "nuxi", - "version": "3.0.0-rc.13", + "version": "3.0.0-rc.14", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -18,32 +18,32 @@ "prepack": "unbuild" }, "devDependencies": { - "@nuxt/kit": "3.0.0-rc.13", - "@nuxt/schema": "3.0.0-rc.13", + "@nuxt/kit": "3.0.0-rc.14", + "@nuxt/schema": "3.0.0-rc.14", "@types/clear": "^0", "@types/flat": "^5.0.2", "@types/mri": "^1.1.1", "@types/semver": "^7", - "c12": "^0.2.13", + "c12": "^1.0.1", "chokidar": "^3.5.3", "clear": "^0.1.0", "clipboardy": "^3.0.0", "colorette": "^2.0.19", "consola": "^2.15.3", - "deep-object-diff": "^1.1.7", - "destr": "^1.2.0", + "deep-object-diff": "^1.1.9", + "destr": "^1.2.1", "execa": "^6.1.0", "flat": "^5.0.2", - "giget": "^0.1.7", - "h3": "^0.8.6", + "giget": "^1.0.0", + "h3": "^1.0.1", "jiti": "^1.16.0", - "listhen": "^0.3.5", - "mlly": "^0.5.16", + "listhen": "^1.0.0", + "mlly": "^1.0.0", "mri": "^1.2.0", - "pathe": "^0.3.9", + "pathe": "^1.0.0", "perfect-debounce": "^0.1.3", - "pkg-types": "^0.3.6", - "scule": "^0.3.2", + "pkg-types": "^1.0.1", + "scule": "^1.0.0", "semver": "^7.3.8", "unbuild": "latest" }, diff --git a/packages/nuxi/src/cli.ts b/packages/nuxi/src/cli.ts index 4796dec7fe7..cd6cddf2104 100755 --- a/packages/nuxi/src/cli.ts +++ b/packages/nuxi/src/cli.ts @@ -1,6 +1,6 @@ import mri from 'mri' import { red } from 'colorette' -import consola from 'consola' +import consola, { ConsolaReporter } from 'consola' import { checkEngines } from './utils/engines' import { commands, Command, NuxtCommand } from './commands' import { showHelp } from './utils/help' @@ -39,7 +39,29 @@ async function _main () { } // Wrap all console logs with consola for better DX -consola.wrapConsole() +consola.wrapAll() + +// Filter out unwanted logs +// TODO: Use better API from consola for intercepting logs +const wrapReporter = (reporter: ConsolaReporter) => { + log (logObj, ctx) { + if (!logObj.args || !logObj.args.length) { return } + const msg = logObj.args[0] + if (typeof msg === 'string' && !process.env.DEBUG) { + // Hide vue-router 404 warnings + if (msg.startsWith('[Vue Router warn]: No match found for location with path')) { + return + } + // Hide sourcemap warnings related to node_modules + if (msg.startsWith('Sourcemap') && msg.includes('node_modules')) { + return + } + } + return reporter.log(logObj, ctx) + } +} +// @ts-expect-error +consola._reporters = consola._reporters.map(wrapReporter) process.on('unhandledRejection', err => consola.error('[unhandledRejection]', err)) process.on('uncaughtException', err => consola.error('[uncaughtException]', err)) diff --git a/packages/nuxi/src/commands/analyze.ts b/packages/nuxi/src/commands/analyze.ts index 43b5be5d36e..019f2689fc3 100644 --- a/packages/nuxi/src/commands/analyze.ts +++ b/packages/nuxi/src/commands/analyze.ts @@ -39,7 +39,7 @@ export default defineNuxtCommand({ const serveFile = (filePath: string) => lazyEventHandler(async () => { const contents = await fsp.readFile(filePath, 'utf-8') - return eventHandler((event) => { event.res.end(contents) }) + return eventHandler((event) => { event.node.res.end(contents) }) }) console.warn('Do not deploy analyze results! Use `nuxi build` before deploying.') diff --git a/packages/nuxi/src/commands/build.ts b/packages/nuxi/src/commands/build.ts index da19795a5fc..9ac44668d8f 100644 --- a/packages/nuxi/src/commands/build.ts +++ b/packages/nuxi/src/commands/build.ts @@ -27,6 +27,11 @@ export default defineNuxtCommand({ cwd: rootDir, fileName: args.dotenv }, + defaults: { + experimental: { + payloadExtraction: args.prerender ? true : undefined + } + }, overrides: { _generate: args.prerender } diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index 6864894555c..ce4845c9d24 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -131,7 +131,7 @@ export default defineNuxtCommand({ const isDirChange = ['addDir', 'unlinkDir'].includes(event) const isFileChange = ['add', 'unlink'].includes(event) const pagesDir = resolve(currentNuxt.options.srcDir, currentNuxt.options.dir.pages) - const reloadDirs = ['components', 'composables'].map(d => resolve(currentNuxt.options.srcDir, d)) + const reloadDirs = ['components', 'composables', 'utils'].map(d => resolve(currentNuxt.options.srcDir, d)) if (isDirChange) { if (reloadDirs.includes(file)) { diff --git a/packages/nuxi/src/commands/info.ts b/packages/nuxi/src/commands/info.ts index e613135355f..781f4f9cc19 100644 --- a/packages/nuxi/src/commands/info.ts +++ b/packages/nuxi/src/commands/info.ts @@ -68,7 +68,7 @@ export default defineNuxtCommand({ Builder: builder, UserConfig: Object.keys(nuxtConfig).map(key => '`' + key + '`').join(', '), RuntimeModules: listModules(nuxtConfig.modules), - BuildModules: listModules(nuxtConfig.buildModules) + BuildModules: listModules(nuxtConfig.buildModules || []) } console.log('RootDir:', rootDir) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index acc6a98e89d..fee448cfea4 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -1,3 +1,4 @@ +import { writeFile } from 'node:fs/promises' import { downloadTemplate, startShell } from 'giget' import { relative } from 'pathe' import consola from 'consola' @@ -27,9 +28,16 @@ export default defineNuxtCommand({ // Show next steps const relativeDist = rpath(t.dir) + + // Write .nuxtrc with `shamefully-hoist=true` for pnpm + const usingPnpm = (process.env.npm_config_user_agent || '').includes('pnpm') + if (usingPnpm) { + await writeFile(`${relativeDist}/.npmrc`, 'shamefully-hoist=true') + } + const nextSteps = [ !args.shell && relativeDist.length > 1 && `\`cd ${relativeDist}\``, - 'Install dependencies with `npm install` or `yarn install` or `pnpm install --shamefully-hoist`', + 'Install dependencies with `npm install` or `yarn install` or `pnpm install`', 'Start development server with `npm run dev` or `yarn dev` or `pnpm run dev`' ].filter(Boolean) diff --git a/packages/nuxi/src/commands/test.ts b/packages/nuxi/src/commands/test.ts index ad6e94ae148..1761dc634f2 100644 --- a/packages/nuxi/src/commands/test.ts +++ b/packages/nuxi/src/commands/test.ts @@ -33,7 +33,9 @@ async function importTestUtils (): Promise { throw new Error('Invalid version of `@nuxt/test-utils` is installed!') } return exports - } catch (_err) { err = _err } + } catch (_err) { + err = _err + } } console.error(err) throw new Error('`@nuxt/test-utils-edge` seems missing. Run `npm i -D @nuxt/test-utils-edge` or `yarn add -D @nuxt/test-utils-edge` to install.') diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts index 7edd8b9222f..e1ba9405d50 100644 --- a/packages/nuxi/src/utils/prepare.ts +++ b/packages/nuxi/src/utils/prepare.ts @@ -29,6 +29,10 @@ export const writeTypes = async (nuxt: Nuxt) => { join(relative(nuxt.options.buildDir, nuxt.options.rootDir), '**/*'), ...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [], ...nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : [] + ], + exclude: [ + // nitro generate output: https://github.com/nuxt/framework/blob/main/packages/nuxt/src/core/nitro.ts#L186 + relative(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist')) ] }) @@ -59,7 +63,6 @@ export const writeTypes = async (nuxt: Nuxt) => { } const references: TSReference[] = [ - ...nuxt.options.buildModules, ...nuxt.options.modules, ...nuxt.options._modules ] diff --git a/packages/nuxt/build.config.ts b/packages/nuxt/build.config.ts index 231e8e3538d..eaa4f097204 100644 --- a/packages/nuxt/build.config.ts +++ b/packages/nuxt/build.config.ts @@ -17,7 +17,7 @@ export default defineBuildConfig({ dependencies: [ 'nuxi', 'vue-router', - 'ohmyfetch' + 'ofetch' ], externals: [ '@vue/reactivity', diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index acfcc1b0271..241f4a48830 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "nuxt", - "version": "3.0.0-rc.13", + "version": "3.0.0-rc.14", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -37,45 +37,47 @@ }, "dependencies": { "@nuxt/devalue": "^2.0.0", - "@nuxt/kit": "3.0.0-rc.13", - "@nuxt/schema": "3.0.0-rc.13", - "@nuxt/telemetry": "^2.1.6", + "@nuxt/kit": "3.0.0-rc.14", + "@nuxt/schema": "3.0.0-rc.14", + "@nuxt/telemetry": "^2.1.7", "@nuxt/ui-templates": "^0.4.0", - "@nuxt/vite-builder": "3.0.0-rc.13", - "@vue/reactivity": "^3.2.41", - "@vue/shared": "^3.2.41", - "@vueuse/head": "~1.0.0-rc.14", + "@nuxt/vite-builder": "3.0.0-rc.14", + "@vue/reactivity": "^3.2.45", + "@vue/shared": "^3.2.45", + "@vueuse/head": "^1.0.13", + "unhead": "^0.6.9", + "@unhead/ssr": "^0.6.9", "chokidar": "^3.5.3", "cookie-es": "^0.5.0", - "defu": "^6.1.0", - "destr": "^1.2.0", + "defu": "^6.1.1", + "destr": "^1.2.1", "escape-string-regexp": "^5.0.0", "estree-walker": "^3.0.1", "fs-extra": "^10.1.0", "globby": "^13.1.2", - "h3": "^0.8.6", + "h3": "^1.0.1", "hash-sum": "^2.0.0", - "hookable": "^5.4.1", - "knitwork": "^0.1.2", + "hookable": "^5.4.2", + "knitwork": "^1.0.0", "magic-string": "^0.26.7", - "mlly": "^0.5.16", - "nitropack": "^0.6.1", - "nuxi": "3.0.0-rc.13", - "ohash": "^0.1.5", - "ohmyfetch": "^0.4.21", - "pathe": "^0.3.9", + "mlly": "^1.0.0", + "nitropack": "^1.0.0", + "nuxi": "3.0.0-rc.14", + "ohash": "^1.0.0", + "ofetch": "^1.0.0", + "pathe": "^1.0.0", "perfect-debounce": "^0.1.3", - "scule": "^0.3.2", - "strip-literal": "^0.4.2", - "ufo": "^0.8.6", - "ultrahtml": "^0.4.0", - "unctx": "^2.0.2", - "unenv": "^0.6.2", - "unimport": "^0.7.0", - "unplugin": "^0.10.2", - "untyped": "^0.5.0", - "vue": "^3.2.41", - "vue-bundle-renderer": "^0.5.0", + "scule": "^1.0.0", + "strip-literal": "^1.0.0", + "ufo": "^1.0.0", + "ultrahtml": "^1.0.0", + "unctx": "^2.1.0", + "unenv": "^1.0.0", + "unimport": "^1.0.0", + "unplugin": "^1.0.0", + "untyped": "^1.0.0", + "vue": "^3.2.45", + "vue-bundle-renderer": "^1.0.0", "vue-devtools-stub": "^0.1.0", "vue-router": "^4.1.6" }, diff --git a/packages/nuxt/src/app/components/client-only.mjs b/packages/nuxt/src/app/components/client-only.mjs index e6530f74298..5bc55149a54 100644 --- a/packages/nuxt/src/app/components/client-only.mjs +++ b/packages/nuxt/src/app/components/client-only.mjs @@ -2,9 +2,10 @@ import { ref, onMounted, defineComponent, createElementBlock, h, createElementVN export default defineComponent({ name: 'ClientOnly', + inheritAttrs: false, // eslint-disable-next-line vue/require-prop-types props: ['fallback', 'placeholder', 'placeholderTag', 'fallbackTag'], - setup (_, { slots }) { + setup (_, { slots, attrs }) { const mounted = ref(false) onMounted(() => { mounted.value = true }) return (props) => { @@ -13,7 +14,7 @@ export default defineComponent({ if (slot) { return slot() } const fallbackStr = props.fallback || props.placeholder || '' const fallbackTag = props.fallbackTag || props.placeholderTag || 'span' - return createElementBlock(fallbackTag, null, fallbackStr) + return createElementBlock(fallbackTag, attrs, fallbackStr) } } }) diff --git a/packages/nuxt/src/app/components/nuxt-link.ts b/packages/nuxt/src/app/components/nuxt-link.ts index 42dbc3d5ae2..ee9225da2da 100644 --- a/packages/nuxt/src/app/components/nuxt-link.ts +++ b/packages/nuxt/src/app/components/nuxt-link.ts @@ -265,6 +265,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) { route: router.resolve(href!), rel, target, + isExternal: isExternal.value, isActive: false, isExactActive: false }) diff --git a/packages/nuxt/src/app/components/nuxt-root.vue b/packages/nuxt/src/app/components/nuxt-root.vue index 5fb19ec758b..e703fef657d 100644 --- a/packages/nuxt/src/app/components/nuxt-root.vue +++ b/packages/nuxt/src/app/components/nuxt-root.vue @@ -1,13 +1,14 @@ -${joinTags(html.bodyPreprend)}${joinTags(html.body)}${joinTags(html.bodyAppend)} +${joinTags(html.bodyPrepend)}${joinTags(html.body)}${joinTags(html.bodyAppend)} ` } @@ -308,8 +307,8 @@ async function renderInlineStyles (usedModules: Set | string[]) { function renderPayloadResponse (ssrContext: NuxtSSRContext) { return { body: `export default ${devalue(splitPayload(ssrContext).payload)}`, - statusCode: ssrContext.event.res.statusCode, - statusMessage: ssrContext.event.res.statusMessage, + statusCode: ssrContext.event.node.res.statusCode, + statusMessage: ssrContext.event.node.res.statusMessage, headers: { 'content-type': 'text/javascript;charset=UTF-8', 'x-powered-by': 'Nuxt' diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index 263ced169b3..e83ab330c72 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -2,7 +2,7 @@ import { resolve } from 'pathe' import { addComponent, addPlugin, defineNuxtModule } from '@nuxt/kit' import { distDir } from '../dirs' -const components = ['Script', 'NoScript', 'Link', 'Base', 'Title', 'Meta', 'Style', 'Head', 'Html', 'Body'] +const components = ['NoScript', 'Link', 'Base', 'Title', 'Meta', 'Style', 'Head', 'Html', 'Body'] export default defineNuxtModule({ meta: { @@ -29,9 +29,6 @@ export default defineNuxtModule({ }) } - // Add mixin plugin - addPlugin({ src: resolve(runtimeDir, 'mixin-plugin') }) - // Add library specific plugin addPlugin({ src: resolve(runtimeDir, 'lib/vueuse-head.plugin') }) } diff --git a/packages/nuxt/src/head/runtime/components.ts b/packages/nuxt/src/head/runtime/components.ts index 663da5a4326..b4029ed07a4 100644 --- a/packages/nuxt/src/head/runtime/components.ts +++ b/packages/nuxt/src/head/runtime/components.ts @@ -65,57 +65,6 @@ const globalProps = { translate: String } -// ') - expect(headHtml).toContain('') + expect(headHtml).toContain('') const indexHtml = await $fetch('/') // should render charset by default @@ -778,7 +778,7 @@ describe.skipIf(process.env.NUXT_TEST_DEV || isWindows)('payload rendering', () it('renders a payload', async () => { const payload = await $fetch('/random/a/_payload.js', { responseType: 'text' }) expect(payload).toMatch( - /export default \{data:\{\$frand_a:\[[^\]]*\]\},prerenderedAt:\d*\}/ + /export default \{data:\{rand_a:\[[^\]]*\]\},prerenderedAt:\d*\}/ ) }) diff --git a/test/bundle.test.ts b/test/bundle.test.ts index fa515f9116e..465eb6a34e3 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -29,6 +29,7 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { expect(stats.client.totalBytes).toBeLessThan(110000) expect(stats.client.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(` [ + "_nuxt/composables.js", "_nuxt/entry.js", "_nuxt/error-404.js", "_nuxt/error-500.js", @@ -51,6 +52,9 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { expect(packages).toMatchInlineSnapshot(` [ "@babel/parser", + "@unhead/dom", + "@unhead/ssr", + "@unhead/vue", "@vue/compiler-core", "@vue/compiler-dom", "@vue/compiler-ssr", @@ -59,7 +63,6 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { "@vue/runtime-dom", "@vue/server-renderer", "@vue/shared", - "@vueuse/shared", "buffer-from", "cookie-es", "defu", @@ -68,8 +71,8 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { "h3", "hookable", "node-fetch-native", + "ofetch", "ohash", - "ohmyfetch", "pathe", "radix3", "scule", @@ -81,7 +84,6 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { "unstorage", "vue", "vue-bundle-renderer", - "vue-demi", ] `) }) diff --git a/test/fixtures/basic/extends/node_modules/foo/nuxt.config.ts b/test/fixtures/basic/extends/node_modules/foo/nuxt.config.ts index 2221b92fc94..f716d9f9da9 100644 --- a/test/fixtures/basic/extends/node_modules/foo/nuxt.config.ts +++ b/test/fixtures/basic/extends/node_modules/foo/nuxt.config.ts @@ -1,3 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' +import { defineNuxtConfig } from 'nuxt/config' export default defineNuxtConfig({}) diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts index 65664c7d715..5553166e344 100644 --- a/test/fixtures/basic/nuxt.config.ts +++ b/test/fixtures/basic/nuxt.config.ts @@ -40,11 +40,11 @@ export default defineNuxtConfig({ ] } }, - publicRuntimeConfig: { - testConfig: 123 - }, - privateRuntimeConfig: { - privateConfig: 'secret_key' + runtimeConfig: { + privateConfig: 'secret_key', + public: { + testConfig: 123 + } }, modules: [ '~/modules/example', @@ -105,7 +105,8 @@ export default defineNuxtConfig({ experimental: { inlineSSRStyles: id => !!id && !id.includes('assets.vue'), reactivityTransform: true, - treeshakeClientOnly: true + treeshakeClientOnly: true, + payloadExtraction: true }, appConfig: { fromNuxtConfig: true, diff --git a/test/fixtures/basic/pages/head.vue b/test/fixtures/basic/pages/head.vue index ee3328b8a3f..58ce42d2668 100644 --- a/test/fixtures/basic/pages/head.vue +++ b/test/fixtures/basic/pages/head.vue @@ -1,35 +1,32 @@ - -