diff --git a/.github/workflows/docs-e2e.yml b/.github/workflows/docs-e2e.yml new file mode 100644 index 000000000000..b6a329e214df --- /dev/null +++ b/.github/workflows/docs-e2e.yml @@ -0,0 +1,32 @@ +name: docs-e2e + +on: + workflow_dispatch: + inputs: + url: + required: false + description: The URL to run the test suite against. + type: string + deployment_status: + +jobs: + crawl-docs: + environment: + name: ${{ github.event.deployment.environment || 'Production' }} + url: ${{ github.event.inputs.url || github.event.deployment.payload.web_url || github.event.deployment_status.target_url }} + if: github.event.deployment_status.state == 'success' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + cache: "yarn" + + - name: Install dependencies + run: yarn --immutable + + - run: node ./scripts/crawl.mjs + env: + BASE_URL: ${{ github.event.inputs.url || github.event.deployment.payload.web_url || github.event.deployment_status.target_url }} diff --git a/docs/.gitignore b/docs/.gitignore index b4a500fb84f4..988de6ce14af 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,2 +1,3 @@ schema **/*.configuration/nuxt.config.md +**/*.configuration/nuxt-config.md diff --git a/docs/content/2.guide/1.concepts/1.introduction.md b/docs/content/1.getting-started/1.introduction.md similarity index 99% rename from docs/content/2.guide/1.concepts/1.introduction.md rename to docs/content/1.getting-started/1.introduction.md index a5b82621ade7..69fd45cb70ff 100644 --- a/docs/content/2.guide/1.concepts/1.introduction.md +++ b/docs/content/1.getting-started/1.introduction.md @@ -42,7 +42,7 @@ Nuxt is the backbone of your Vue.js project, giving structure to build your proj Extendable with a strong module ecosystem and hooks engine, it makes it easy to connect your REST or GraphQL endpoints, favorite CMS, CSS frameworks and more. PWA and AMP support is only a module away from your Nuxt project. ::alert{type=info icon=πŸ‘} -Ready to try? Head over to the [Installation section](/getting-started/quick-start). +Ready to try? Head over to the [Installation section](/getting-started/installation). :: ### Are You *Courageously* Nuxt? diff --git a/docs/content/1.getting-started/10.deployment.md b/docs/content/1.getting-started/10.deployment.md new file mode 100644 index 000000000000..6ef4a6a4a87b --- /dev/null +++ b/docs/content/1.getting-started/10.deployment.md @@ -0,0 +1,145 @@ +# Deployment + +A Nuxt application can be deployed on a Node.js server, pre-rendered for static hosting, or deployed to serverless or edge (CDN) environments. + +::alert{type=info} +If you are looking for a list of cloud providers that support Nuxt 3, see the [list below](#supported-hosting-providers). +:: + +## Node.js Server + +Discover the Node.js server preset with Nitro to deploy on any Node hosting. + +::list + +- **Default output format** if none is specified or auto-detected
+- Loads only the required chunks to render the request for optimal cold start timing
+- Useful for deploying Nuxt apps to any Node.js hosting +:: + +### Entry Point + +When running `nuxt build` with the Node server preset, the result will be an entry point that launches a ready-to-run Node server. + +```bash +node .output/server/index.mjs +``` + +### Example + +```bash +$ node .output/server/index.mjs +Listening on http://localhost:3000 +``` + +### Configuring Defaults at Runtime + +This preset will respect the following runtime environment variables: + +- `NITRO_PORT` or `PORT` (defaults to `3000`) +- `NITRO_HOST` or `HOST` (defaults to `'0.0.0.0'`) +- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL. + +#### Using PM2 + +To use `pm2`, use an `ecosystem.config.js`: + +```js [ecosystem.config.js] +module.exports = { + apps: [ + { + name: 'NuxtAppName', + exec_mode: 'cluster', + instances: 'max', + script: './.output/server/index.mjs' + } + ] +} +``` + +#### Using Cluster Mode + +You can use `NITRO_PRESET=node_cluster` in order to leverage multi-process performance using Node.js [cluster](https://nodejs.org/dist/latest/docs/api/cluster.html) module. + +By default, the workload gets distributed to the workers with the round robin strategy. + +### Learn More + +:ReadMore{link="https://nitro.unjs.io/deploy/node" title="the Nitro documentation for node-server preset"} + +## Static Hosting + +There are two ways to deploy a Nuxt application to any static hosting services: + +- Static site generation (SSG) pre-renders routes of your application at build time. +- Using `ssr: false` to produce a pure client-side output. + +### Crawl-based Pre-rendering + +Use the [`nuxi generate` command](/api/commands/generate) to build your application. For every page, Nuxt uses a crawler to generate a corresponding HTML and payload files. The built files will be generated in the `.output/public` directory. + +```bash +npx nuxi generate +``` + +### Manual Pre-rendering + +You can manually specify routes that [Nitro](/guide/concepts/server-engine) will fetch and pre-render during the build. + +```ts [nuxt.config.ts|js] +defineNuxtConfig({ + nitro: { + prerender: { + routes: ['/user/1', '/user/2'] + } + } +}) +``` + +### Client-side Only Rendering + +If you don't want to pre-render your routes, another way of using static hosting is to set the `ssr` property to `false` in the `nuxt.config` file. The `nuxi generate` command will then output an `.output/public/index.html` entrypoint and JavaScript bundles like a classic client-side Vue.js application. + +```ts [nuxt.config.ts|js] +defineNuxtConfig({ + ssr: false +}) +``` + +## Presets + +In addition to Node.js servers and static hosting services, a Nuxt 3 project can be deployed with several well-tested presets and minimal amount of configuration. + +You can explicitly set the desired preset in the [`nuxt.config`](/guide/directory-structure/nuxt.config) file: + +```js [nuxt.config.js|ts] +export default { + nitro: { + preset: 'node-server' + } +} +``` + +... or use the `NITRO_PRESET` environment variable when running `nuxt build`: + +```bash +NITRO_PRESET=node-server nuxt build +``` + +πŸ”Ž Check [the Nitro deployment](https://nitro.unjs.io/deploy) for all possible deployment presets and providers. + +### Supported Hosting Providers + +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) +- :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) diff --git a/docs/content/1.getting-started/10.upgrade.md b/docs/content/1.getting-started/10.upgrade.md new file mode 100644 index 000000000000..37d5dd875ec7 --- /dev/null +++ b/docs/content/1.getting-started/10.upgrade.md @@ -0,0 +1,59 @@ +# Upgrade Guide + +Have a Nuxt 2 project to migrate? Use these guides to upgrade your Nuxt applications to Nuxt 3 or take the first step in that direction with Nuxt Bridge. + +If you are already using Nuxt 3 and want to upgrade to the latest release or test new features before their release, head over to the [Upgrading Nuxt 3](#upgrading-nuxt-3) section. + +## Feature Comparison + +In the table below, there is a quick comparison between 3 versions of Nuxt: + +Feature / Version | Nuxt 2 | Nuxt Bridge | Nuxt 3 +-------------------------|-----------------|------------------|--------- +Vue | 2 | 2 | 3 +Stability | 😊 Stable | 😌 Semi-stable | Release candidate +Performance | 🏎 Fast | ✈️ Faster | πŸš€ Fastest +Nitro Engine | ❌ | βœ… | βœ… +ESM support | πŸŒ™ Partial | πŸ‘ Better | βœ… +TypeScript | β˜‘οΈ Opt-in | 🚧 Partial | βœ… +Composition API | ❌ | 🚧 Partial | βœ… +Options API | βœ… | βœ… | βœ… +Components Auto Import | βœ… | βœ… | βœ… +` +``` + +:ReadMore{link="/guide/going-further/runtime-config"} + +## App Configuration + +The `app.config.ts` file, also located at the root of a Nuxt project, is used to expose public variables that can be determined at build time. Contrary to the `runtimeConfig` option, these can not be overriden using environment variables. + +A minimal configuration file exports the `defineAppConfig` function containing an object with your configuration. The `defineAppConfig` helper is globally available without import. + +```ts [app.config.ts] +export default defineAppConfig({ + title: 'Hello Nuxt', + theme: { + dark: true, + colors: { + primary: '#ff0000' + } + } +}) +``` + +These variables are exposed to the rest of your application using the [`useAppConfig`](/api/composables/use-app-config) composable. + +```vue [pages/index.vue] + +``` + +:ReadMore{link="/guide/directory-structure/app.config"} + +## `runtimeConfig` vs `app.config` + +As stated above, `runtimeConfig` and `app.config` are both used to expose variables to the rest of your application. To determine whether you should use one or the other, here are some guidelines: + +- `runtimeConfig`: Private or public tokens that need to be specified after build using environment variables. +- `app.config` : Public tokens that are determined at build time, website configuration such as theme variant, title and any project config that are not sensitive. + +Feature | `runtimeConfig` | `app.config` +-------------------------------|------------------|------------------- +Client Side | Hydrated | Bundled +Environment Variables | βœ… Yes | ❌ No +Reactive | βœ… Yes | βœ… Yes +Types support | βœ… Partial | βœ… Yes +Configuration per Request | ❌ No | βœ… Yes +Hot Module Replacement | ❌ No | βœ… Yes +Non primitive JS types | ❌ No | βœ… Yes diff --git a/docs/content/1.getting-started/3.views.md b/docs/content/1.getting-started/3.views.md new file mode 100644 index 000000000000..ad1f82f7e9af --- /dev/null +++ b/docs/content/1.getting-started/3.views.md @@ -0,0 +1,130 @@ +# Views + +Nuxt provides several component layers to implement the user interface of your application. + +## `app.vue` + +![The `app.vue` file is the entry point of your application](/img/getting-started/views/app.svg) + +By default, Nuxt will treat this file as the **entrypoint** and render its content for every route of the application. + +```vue [app.vue] + +``` + +::alert +If you are familiar with Vue, you might wonder where `main.js` is (the file is that normally creates a Vue app). Nuxt does this behind the scene. +:: + +## Components + +![Components are reusable pieces of UI](/img/getting-started/views/components.svg) + +Most components are reusable pieces of the user interface, like buttons and menus. In Nuxt, you can create these components in the `components/` directory, and they will be automatically available across your application without having to explicitly import them. + +::code-group + +```vue [App.vue] + +``` + +```vue [components/AppAlert.vue] + +``` + +:: + +## Pages + +![Pages are views tied to a specific route](/img/getting-started/views/pages.svg) + +Pages represent views use for each specific route pattern. Every file in the `pages/` directory represents a different route displaying its content. + +To use pages, create `pages/index.vue` file and add `` component to the `app.vue` (or remove `app.vue` for default entry). You can now create more pages and their corresponding routes by adding new files in the `pages/` directory. + +::code-group + +```vue [pages/index.vue] + +``` + +```vue [pages/about.vue] + +``` + +:: + +::alert +You will learn more about pages in the [Routing section](/getting-started/routing) +:: + +## Layouts + +![Layouts are wrapper around pages](/img/getting-started/views/layouts.svg) + +Layouts are wrappers around pages that contain a common User Interface for several pages, such as a header and footer display. Layouts are Vue files using `` components to display the **page** content. The `layouts/default.vue` file will be used by default. Custom layouts can be set as part of your page metadata. + +::alert +If you only have a single layout in your application, we recommend using app.vue with the [`` component](/api/components/nuxt-page) instead. +:: + +::code-group + +```vue [layouts/default.vue] + +``` + +```vue [pages/index.vue] + +``` + +```vue [pages/about.vue] + +``` + +:: + +If you want to create more layouts and learn how to use them in your pages, find more information in the [Layouts section](/guide/directory-structure/layouts). diff --git a/docs/content/2.guide/2.features/3.assets.md b/docs/content/1.getting-started/4.assets.md similarity index 95% rename from docs/content/2.guide/2.features/3.assets.md rename to docs/content/1.getting-started/4.assets.md index b98a4f668e9a..0b38397c330e 100644 --- a/docs/content/2.guide/2.features/3.assets.md +++ b/docs/content/1.getting-started/4.assets.md @@ -70,8 +70,6 @@ In your `nuxt.config` ::code-group ```ts [SCSS] -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ vite: { css: { @@ -86,14 +84,12 @@ export default defineNuxtConfig({ ``` ```ts [SASS] -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { sass: { - additionalData: '@use "@/assets/_colors.sass" as *' + additionalData: '@use "@/assets/_colors.sass" as *\n' } } } diff --git a/docs/content/1.getting-started/5.routing.md b/docs/content/1.getting-started/5.routing.md new file mode 100644 index 000000000000..ac3f40c8c8d7 --- /dev/null +++ b/docs/content/1.getting-started/5.routing.md @@ -0,0 +1,115 @@ +# Routing + +One of Nuxt core feature is the file-system router. Every Vue file created inside the pages/ directory creates a corresponding URL (or route) that displays the content of the file. Nuxt leverages code-splitting on each page by using dynamic imports to ship the minimum of JavaScript for the requested route. + +## Pages + +Nuxt routing is based on [vue-router](https://router.vuejs.org/) and generates the routes from every component created in the [`pages/`](/guide/directory-structure/pages) directory, based on their filename. + +This file system routing uses naming conventions to create dynamic and nested routes: + +::code-group + +```text [pages/ directory] +pages/ +--| about.vue +--| posts/ +----| [id].vue +``` + +```js [Generated Router file] +{ + "routes": [ + { + "path": "/about", + "component": "pages/about.vue" + }, + { + "path": "/posts/:id", + "component": "pages/posts/[id].vue" + } + ] +} +``` + +:: + +## Navigation + +The `` component links pages between them. It renders a `` tag with the `href` attribute set to the route of the page. Once the application is hydrated, pages transitions are performed in JavaScript by updating the browser URL. This prevents full-page refreshes and allow for animated transitions. + +When a `` enters the viewport on the client side, Nuxt will automatically prefetch components and payload (generated pages) of the linked pages ahead of time, resulting in faster navigation. + +```vue [pages/app.vue] + +``` + +:ReadMore{link="/api/components/nuxt-link"} + +## Route Parameters + +The `useRoute()` composable can be used in a ` +``` + +:ReadMore{link="/api/composables/use-route"} + +## Route Middleware + +Nuxt provides a customizable route middleware framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route. + +::alert{type=info} +Route middleware run within the Vue part of your Nuxt app. Despite the similar name, they are completely different from server middleware, which are run in the Nitro server part of your app. +:: + +There are three kinds of route middleware: + +1. Anonymous (or inline) route middleware, which are defined directly in the pages where they are used. +2. Named route middleware, which are placed in the `middleware/` directory and will be automatically loaded via asynchronous import when used on a page. (**Note**: The route middleware name is normalized to kebab-case, so `someMiddleware` becomes `some-middleware`.) +3. Global route middleware, which are placed in the `middleware/` directory (with a `.global` suffix) and will be automatically run on every route change. + +Example of an `auth` middleware protecting the `/dashboard` page: + +::code-group + +```ts [middleware/auth.ts] +export default defineNuxtRouteMiddleware((to, from) => { + // isAuthenticated() is an example method verifying if an user is authenticated + if (isAuthenticated() === false) { + return navigateTo('/login') + } +}) +``` + +```html [pages/dashboard.vue] + + + +``` + +:: + +:ReadMore{link="/guide/directory-structure/middleware"} diff --git a/docs/content/2.guide/2.features/4.head-management.md b/docs/content/1.getting-started/5.seo-meta.md similarity index 99% rename from docs/content/2.guide/2.features/4.head-management.md rename to docs/content/1.getting-started/5.seo-meta.md index 188a6df85c0c..b3f602840cc8 100644 --- a/docs/content/2.guide/2.features/4.head-management.md +++ b/docs/content/1.getting-started/5.seo-meta.md @@ -1,4 +1,4 @@ -# Head Management +# SEO and Meta Out-of-the-box, Nuxt provides good default values for `charset` and `viewport` meta tags, but you can override these if you need to, as well as customize other meta tags for your site in several different ways. diff --git a/docs/content/2.guide/2.features/5.data-fetching.md b/docs/content/1.getting-started/6.data-fetching.md similarity index 98% rename from docs/content/2.guide/2.features/5.data-fetching.md rename to docs/content/1.getting-started/6.data-fetching.md index 6104ad4df0ba..03c5cee2b758 100644 --- a/docs/content/2.guide/2.features/5.data-fetching.md +++ b/docs/content/1.getting-started/6.data-fetching.md @@ -203,6 +203,13 @@ export default defineNuxtComponent({ Options API support for `asyncData` may well change before the stable release of Nuxt 3. :: +::Alert +Using ` ``` + +::ReadMore{link="/guide/directory-structure/server"} diff --git a/docs/content/2.guide/3.directory-structure/14.gitignore.md b/docs/content/2.guide/2.directory-structure/2.gitignore.md similarity index 100% rename from docs/content/2.guide/3.directory-structure/14.gitignore.md rename to docs/content/2.guide/2.directory-structure/2.gitignore.md diff --git a/docs/content/2.guide/3.directory-structure/17.nuxtignore.md b/docs/content/2.guide/2.directory-structure/2.nuxtignore.md similarity index 100% rename from docs/content/2.guide/3.directory-structure/17.nuxtignore.md rename to docs/content/2.guide/2.directory-structure/2.nuxtignore.md diff --git a/docs/content/2.guide/2.features/10.app-config.md b/docs/content/2.guide/2.directory-structure/3.app.config.md similarity index 82% rename from docs/content/2.guide/2.features/10.app-config.md rename to docs/content/2.guide/2.directory-structure/3.app.config.md index f81e9335800d..5c4ab3df7b61 100644 --- a/docs/content/2.guide/2.features/10.app-config.md +++ b/docs/content/2.guide/2.directory-structure/3.app.config.md @@ -1,7 +1,21 @@ -# App Config +--- +icon: IconFile +title: app.config.ts +head.title: Nuxt App Config +--- + +# App Config File Nuxt 3 provides an `app.config` config file to expose reactive configuration within your application with the ability to update it at runtime within lifecycle or using a nuxt plugin and editing it with HMR (hot-module-replacement). +You can easily provide runtime app configuration using `app.config.ts` file. It can have either of `.ts`, `.js`, or `.mjs` extensions. + +```ts [app.config.ts] +export default defineAppConfig({ + foo: 'bar' +}) +``` + ::alert{type=warning} Do not put any secret values inside `app.config` file. It is exposed to the user client bundle. :: diff --git a/docs/content/2.guide/3.directory-structure/15.app.md b/docs/content/2.guide/2.directory-structure/3.app.md similarity index 100% rename from docs/content/2.guide/3.directory-structure/15.app.md rename to docs/content/2.guide/2.directory-structure/3.app.md diff --git a/docs/content/2.guide/3.directory-structure/18.nuxt.config.md b/docs/content/2.guide/2.directory-structure/3.nuxt.config.md similarity index 66% rename from docs/content/2.guide/3.directory-structure/18.nuxt.config.md rename to docs/content/2.guide/2.directory-structure/3.nuxt.config.md index 98eb67201c45..158d6bb4cf43 100644 --- a/docs/content/2.guide/3.directory-structure/18.nuxt.config.md +++ b/docs/content/2.guide/2.directory-structure/3.nuxt.config.md @@ -9,7 +9,20 @@ head.title: Nuxt Configuration file Nuxt can be easily configured with a single `nuxt.config` file, which can have either a `.js`, `.ts` or `.mjs` extension. ```ts -import { defineNuxtConfig } from 'nuxt' +export default defineNuxtConfig({ + // My Nuxt config +}) +``` + + +::alert +`defineNuxtConfig` helper is globally available without import. +:: + +You can explicitily import `defineNuxtConfig` from `nuxt/config` if you prefer: + +```js +import { defineNuxtConfig } from 'nuxt/config' export default defineNuxtConfig({ // My Nuxt config diff --git a/docs/content/2.guide/3.directory-structure/19.package.md b/docs/content/2.guide/2.directory-structure/3.package.md similarity index 80% rename from docs/content/2.guide/3.directory-structure/19.package.md rename to docs/content/2.guide/2.directory-structure/3.package.md index 359b94536bec..83edd28fccc6 100644 --- a/docs/content/2.guide/3.directory-structure/19.package.md +++ b/docs/content/2.guide/2.directory-structure/3.package.md @@ -1,9 +1,9 @@ --- icon: IconFile title: package.json -head.title: Package File +head.title: Package.json File --- -# Package File +# Package.json File TheΒ `package.json`Β file contains all the dependencies and scripts for your application ([learn more](https://docs.npmjs.com/cli/v7/configuring-npm/package-json)). diff --git a/docs/content/2.guide/3.directory-structure/20.tsconfig.md b/docs/content/2.guide/2.directory-structure/3.tsconfig.md similarity index 58% rename from docs/content/2.guide/3.directory-structure/20.tsconfig.md rename to docs/content/2.guide/2.directory-structure/3.tsconfig.md index e552d41211c4..138538f39745 100644 --- a/docs/content/2.guide/3.directory-structure/20.tsconfig.md +++ b/docs/content/2.guide/2.directory-structure/3.tsconfig.md @@ -14,4 +14,4 @@ Nuxt [automatically generates](/guide/concepts/typescript) a `.nuxt/tsconfig.jso } ``` -As you need to, you can customize the contents of this file. However, note that if you need to customize your `paths`, this will override the auto-generated path aliases. Instead, we recommend that you add any path aliases you need to the `alias` property within your `nuxt.config`, where they will get picked up and added to the autogenerated `tsconfig`. +As you need to, you can customize the contents of this file. However, it is recommended that you don't overwrite `target`, `module` and `moduleResolution`. Moreover, note that if you need to customize your `paths`, this will override the auto-generated path aliases. Instead, we recommend that you add any path aliases you need to the `alias` property within your `nuxt.config`, where they will get picked up and added to the auto-generated `tsconfig`. diff --git a/docs/content/2.guide/3.directory-structure/index.md b/docs/content/2.guide/2.directory-structure/index.md similarity index 100% rename from docs/content/2.guide/3.directory-structure/index.md rename to docs/content/2.guide/2.directory-structure/index.md diff --git a/docs/content/2.guide/2.features/1.views.md b/docs/content/2.guide/2.features/1.views.md deleted file mode 100644 index 53bf6eb1386f..000000000000 --- a/docs/content/2.guide/2.features/1.views.md +++ /dev/null @@ -1,13 +0,0 @@ -# Views - -::NeedContribution -:: - -::ReadMore{link="/guide/directory-structure/components"} -:: - -::ReadMore{link="/guide/directory-structure/pages"} -:: - -::ReadMore{link="/guide/directory-structure/layouts"} -:: diff --git a/docs/content/2.guide/2.features/2.routing.md b/docs/content/2.guide/2.features/2.routing.md deleted file mode 100644 index 6c8fbeddf451..000000000000 --- a/docs/content/2.guide/2.features/2.routing.md +++ /dev/null @@ -1,10 +0,0 @@ -# Routing - -::NeedContribution -:: - -::ReadMore{link="/guide/directory-structure/pages"} -:: - -::ReadMore{link="/guide/directory-structure/middleware"} -:: diff --git a/docs/content/2.guide/2.features/8.plugins.md b/docs/content/2.guide/2.features/8.plugins.md deleted file mode 100644 index 5841ab7f2f85..000000000000 --- a/docs/content/2.guide/2.features/8.plugins.md +++ /dev/null @@ -1,9 +0,0 @@ -# Plugins - -::NeedContribution -:: - -::ReadMore{link="/guide/directory-structure/plugins"} -:: - -:LinkExample{link="/examples/app/plugins"} diff --git a/docs/content/2.guide/2.features/index.md b/docs/content/2.guide/2.features/index.md deleted file mode 100644 index 3a10d396b11c..000000000000 --- a/docs/content/2.guide/2.features/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Features -layout.aside: true -layout.asideClass: '' -navigation.redirect: /guide/features/views ---- diff --git a/docs/content/2.guide/3.directory-structure/13.server.md b/docs/content/2.guide/3.directory-structure/13.server.md deleted file mode 100644 index 1ab2f61f5df4..000000000000 --- a/docs/content/2.guide/3.directory-structure/13.server.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -icon: IconDirectory -title: server -head.title: Server Directory ---- - -# Server Directory - -::ReadMore{link="/guide/features/server-routes"} diff --git a/docs/content/2.guide/3.directory-structure/16.app.config.md b/docs/content/2.guide/3.directory-structure/16.app.config.md deleted file mode 100644 index b8078593de24..000000000000 --- a/docs/content/2.guide/3.directory-structure/16.app.config.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -icon: IconFile -title: app.config.ts -head.title: Nuxt App Config ---- - -# Nuxt App Config - -You can easily provide runtime app configuration using `app.config.ts` file. It can have either of `.ts`, `.js`, or `.mjs` extensions. - -```ts [app.config.ts] -export default defineAppConfig({ - foo: 'bar' -}) -``` - -::alert{type=warning} -Do not put any secret values inside `app.config` file. It is exposed to the user client bundle. -:: - -::ReadMore{link="/guide/features/app-config"} diff --git a/docs/content/2.guide/6.going-further/1.internals.md b/docs/content/2.guide/4.going-further/1.internals.md similarity index 100% rename from docs/content/2.guide/6.going-further/1.internals.md rename to docs/content/2.guide/4.going-further/1.internals.md diff --git a/docs/content/2.guide/2.features/10.runtime-config.md b/docs/content/2.guide/4.going-further/10.runtime-config.md similarity index 100% rename from docs/content/2.guide/2.features/10.runtime-config.md rename to docs/content/2.guide/4.going-further/10.runtime-config.md diff --git a/docs/content/2.guide/6.going-further/8.edge-channel.md b/docs/content/2.guide/4.going-further/11.edge-channel.md similarity index 100% rename from docs/content/2.guide/6.going-further/8.edge-channel.md rename to docs/content/2.guide/4.going-further/11.edge-channel.md diff --git a/docs/content/2.guide/6.going-further/2.hooks.md b/docs/content/2.guide/4.going-further/2.hooks.md similarity index 60% rename from docs/content/2.guide/6.going-further/2.hooks.md rename to docs/content/2.guide/4.going-further/2.hooks.md index 05ce029a12cf..636db5e77ebd 100644 --- a/docs/content/2.guide/6.going-further/2.hooks.md +++ b/docs/content/2.guide/4.going-further/2.hooks.md @@ -45,3 +45,26 @@ export default defineNuxtPlugin((nuxtApp) => { ::alert{icon=πŸ‘‰} Learn more about [available lifecycle hooks](/api/advanced/hooks) :: + +## Nitro App Hooks (Runtime) + +These hooks are available for [Nitro plugins](https://nitro.unjs.io/guide/advanced/plugins) to hook into Nitro's runtime behavior. + +### Usage within a Nitro Plugin + +```js [~/server/plugins/test.ts] +export default defineNitroPlugin((nitroApp) => { + nitroApp.hooks.hook('render:html', (html, { event }) => { + console.log('render:html', html) + html.bodyAppend.push('
Appended by custom plugin') + }) + + nitroApp.hooks.hook('render:response', (response, { event }) => { + console.log('render:response', response) + }) +}) +``` + +::alert{icon=πŸ‘‰} +Learn more about available [Nitro lifecycle hooks](/api/advanced/hooks#nitro-hooks-runtime-server-side). +:: diff --git a/docs/content/2.guide/6.going-further/3.modules.md b/docs/content/2.guide/4.going-further/3.modules.md similarity index 76% rename from docs/content/2.guide/6.going-further/3.modules.md rename to docs/content/2.guide/4.going-further/3.modules.md index ed63c69aa484..cbe8daf106b1 100644 --- a/docs/content/2.guide/6.going-further/3.modules.md +++ b/docs/content/2.guide/4.going-further/3.modules.md @@ -174,6 +174,62 @@ By moving your modules to [nuxt-community](https://github.com/nuxt-community), t If you have an already published and working module and want to transfer it to nuxt-community, open an issue in [nuxt/modules](https://github.com/nuxt/modules/issues/new). +## Testing + +### `@nuxt/test-utils` + +#### Fixture Setup + +To test the modules we create, we could set up some Nuxt apps as fixtures and test their behaviors. For example, we can create a simple Nuxt app under `./test/fixture` with the configuration like: + +```ts +// nuxt.config.js +import MyModule from '../../src' + +export default defineNuxtConfig({ + modules: [ + MyModule + ] +}) +``` + +#### Tests Setup + +We can create a test file and use the `rootDir` to test the fixture. + +```ts +// basic.test.js +import { describe, it, expect } from 'vitest' +import { fileURLToPath } from 'node:url' +import { setup, $fetch } from '@nuxt/test-utils-edge' + +describe('ssr', async () => { + await setup({ + rootDir: fileURLToPath(new URL('./fixture', import.meta.url)), + }) + + it('renders the index page', async () => { + // Get response to a server-rendered page with `$fetch`. + const html = await $fetch('/') + + expect(html).toContain('
A Link') + }) +}) +``` + +For more usage, please refer to our [tests for Nuxt 3 framework](https://github.com/nuxt/framework/blob/main/test/basic.test.ts). + +### Mock utils + +- `mockFn()`: Returns a mocked function based on test runner. +- `mockLogger()`: Mocks logger using [`consola.mockTypes`](https://github.com/unjs/consola#mocktypes) and `mockFn()`. Returns an object of mocked logger types. + +### Testing Externally + +If you wish to test your module outside of the module playground before publishing to npm, you can use [`npm pack`](https://docs.npmjs.com/cli/v7/commands/npm-pack) command, or your package manager equivalent, to create a tarball from your module. Then in your test project, you can add your module to `package.json` packages as: `"nuxt-module-name": "file:/path/to/tarball.tgz"`. + +After that, you should be able to reference `nuxt-module-name` like in any regular project. + ## Examples ### Provide Nuxt Plugins @@ -210,6 +266,26 @@ export default defineNuxtModule({ }) ``` +### Adding Vue Components + +If your module should provide Vue components, you can use the `addComponent` utility to add them as auto-imports for Nuxt to resolve. + +```ts +import { defineNuxtModule, addComponent } from '@nuxt/kit' + +export default defineNuxtModule({ + setup(options, nuxt) { + addComponent({ + name: 'MyComponent', // name of the component to be used in vue templates + export: 'MyAwesomeComponent', // (optional) if the component is a named (rather than default) export + // filePath should be package name or resolved path + // if the component is created locally, preferably in `runtime` dir + filePath: '@vue/awesome-components' // resolve(runtimeDir, 'components', 'MyComponent.vue') + }) + } +}) +``` + ### Clean Up Module If your module opens, handles or starts a watcher, you should close it when the Nuxt lifecycle is done. For this, use the `close` hook: diff --git a/docs/content/2.guide/6.going-further/4.kit.md b/docs/content/2.guide/4.going-further/4.kit.md similarity index 100% rename from docs/content/2.guide/6.going-further/4.kit.md rename to docs/content/2.guide/4.going-further/4.kit.md diff --git a/docs/content/2.guide/6.going-further/6.nuxt-app.md b/docs/content/2.guide/4.going-further/6.nuxt-app.md similarity index 100% rename from docs/content/2.guide/6.going-further/6.nuxt-app.md rename to docs/content/2.guide/4.going-further/6.nuxt-app.md diff --git a/docs/content/2.guide/6.going-further/index.md b/docs/content/2.guide/4.going-further/index.md similarity index 100% rename from docs/content/2.guide/6.going-further/index.md rename to docs/content/2.guide/4.going-further/index.md diff --git a/docs/content/2.guide/5.deploy/1.node-server.md b/docs/content/2.guide/5.deploy/1.node-server.md deleted file mode 100644 index bfedf7f407fc..000000000000 --- a/docs/content/2.guide/5.deploy/1.node-server.md +++ /dev/null @@ -1,60 +0,0 @@ -# Node.js Server - -Discover the Node.js server preset with Nitro to deploy on any Node hosting. - -::list - -- **Default output format** if none is specified or auto-detected
-- Loads only the required chunks to render the request for optimal cold start timing
-- Useful for deploying Nuxt apps to any Node.js hosting -:: - -## Entry Point - -When running `nuxt build` with the Node server preset, the result will be an entry point that launches a ready-to-run Node server. - -```bash -node .output/server/index.mjs -``` - -## Example - -```bash -$ node .output/server/index.mjs -Listening on http://localhost:3000 -``` - -## Configuring Defaults at Runtime - -This preset will respect the following runtime environment variables: - -- `NITRO_PORT` or `PORT` (defaults to `3000`) -- `NITRO_HOST` or `HOST` (defaults to `'0.0.0.0'`) -- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL. - -### Using PM2 - -To use `pm2`, use an `ecosystem.config.js`: - -```js [ecosystem.config.js] -module.exports = { - apps: [ - { - name: 'NuxtAppName', - exec_mode: 'cluster', - instances: 'max', - script: './.output/server/index.mjs' - } - ] -} -``` - -### Using Cluster Mode - -You can use `NITRO_PRESET=node_cluster` in order to leverage multi-process performance using Node.js [cluster](https://nodejs.org/dist/latest/docs/api/cluster.html) module. - -By default, the workload gets distributed to the workers with the round robin strategy. - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/node" title="the Nitro documentation for node-server preset"} diff --git a/docs/content/2.guide/5.deploy/2.static-hosting.md b/docs/content/2.guide/5.deploy/2.static-hosting.md deleted file mode 100644 index 6694ca61e6f1..000000000000 --- a/docs/content/2.guide/5.deploy/2.static-hosting.md +++ /dev/null @@ -1,42 +0,0 @@ -# Static Hosting - -::alert{type=info} -The [full static feature](https://nuxtjs.org/announcements/going-full-static) is [under development](https://github.com/nuxt/framework/issues/6411) and will be available in the near future. -:: - -There are two ways to deploy a Nuxt application to any static hosting services: - -- Static site generation (SSG) prerenders every route of your application at build time. For every page, Nuxt uses a crawler to generate a corresponding HTML file. -- Using `ssr: false` to produce a pure client-side output. - -## Prerendering - -Use the [`nuxi generate` command](/api/commands/generate) to build your application. The HTML files will be generated in the `.output/public` directory. - -```bash -npx nuxi generate -``` - -## Client-side Only Rendering - -If you don't want to prerender your routes, another way of using static hosting is to set the `ssr` property to `false` in the `nuxt.config` file. The `nuxi generate` command will then output an `index.html` entrypoint like a classic client-side Vue.js application. - -```ts [nuxt.config.ts|js] -defineNuxtConfig({ - ssr: false -}) -``` - -## Advanced - -You can manually specify routes that [Nitro](/guide/concepts/server-engine) will fetch and prerender during the build. - -```ts [nuxt.config.ts|js] -defineNuxtConfig({ - nitro: { - prerender: { - routes: ['/user/1', '/user/2'] - } - } -}) -``` diff --git a/docs/content/2.guide/5.deploy/3.presets.md b/docs/content/2.guide/5.deploy/3.presets.md deleted file mode 100644 index e4a38aa8d713..000000000000 --- a/docs/content/2.guide/5.deploy/3.presets.md +++ /dev/null @@ -1,37 +0,0 @@ -# Deployment Presets - -In addition to Node.js servers and static hosting services, a Nuxt 3 project can be deployed with several well-tested presets and minimal amount of configuration. - -You can use the [Nuxt config](/guide/directory-structure/nuxt.config) to explicitly set the preset to use: - -```js [nuxt.config.js|ts] -export default { - nitro: { - preset: 'node-server' - } -} -``` - -Or directly use the `NITRO_PRESET` environment variable when running `nuxt build`: - -```bash -NITRO_PRESET=node-server nuxt build -``` - -πŸ”Ž Check [the Nitro deployment](https://nitro.unjs.io/deploy) for all possible deployment presets and providers. - -## Supported Hosting Providers - -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](/guide/deploy/providers/aws) -- :LogoAzure{class="h-5 w-4 inline mb-2"} [Azure](/guide/deploy/providers/azure) -- :LogoCloudFlare{class="h-5 w-4 inline mb-2"} [CloudFlare](/guide/deploy/providers/cloudflare) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Digital Ocean](/guide/deploy/providers/digitalocean) -- :LogoFirebase{class="h-5 w-4 inline mb-2"} [Firebase](/guide/deploy/providers/firebase) -- :IconCloud{class="h-5 w-4 inline mb-2"} [heroku](/guide/deploy/providers/heroku) -- :IconCloud{class="h-5 w-4 inline mb-2"} [layer0](/guide/deploy/providers/layer0) -- :LogoNetlify{class="h-5 w-4 inline mb-2"} [Netlify](/guide/deploy/providers/netlify) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Render](/guide/deploy/providers/render) -- :IconCloud{class="h-5 w-4 inline mb-2"} [Stormkit](/guide/deploy/providers/stormkit) -- :LogoVercel{class="h-5 w-4 inline mb-2"} [Vercel](/guide/deploy/providers/vercel) diff --git a/docs/content/2.guide/5.deploy/index.md b/docs/content/2.guide/5.deploy/index.md deleted file mode 100644 index b5130f0ce887..000000000000 --- a/docs/content/2.guide/5.deploy/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: - aside: true - asideClass: '' -navigation: - redirect: /guide/deploy/node-server ---- diff --git a/docs/content/2.guide/5.deploy/providers/aws.md b/docs/content/2.guide/5.deploy/providers/aws.md deleted file mode 100644 index b4d63cd19190..000000000000 --- a/docs/content/2.guide/5.deploy/providers/aws.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -icon: IconCloud ---- - -# AWS - -How to deploy Nuxt to [AWS Lambda](https://aws.amazon.com/lambda/) - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/aws" title="the Nitro documentation for AWS deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/azure.md b/docs/content/2.guide/5.deploy/providers/azure.md deleted file mode 100644 index 1de4e4ef72bf..000000000000 --- a/docs/content/2.guide/5.deploy/providers/azure.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -icon: LogoAzure ---- - -# Azure - -How to deploy to [Azure Static Web Apps](https://azure.microsoft.com/en-us/services/app-service/static/) or [Azure Functions](https://azure.microsoft.com/en-us/services/functions). - -::list - -- Support for serverless SSR build -- Auto-detected when deploying -- Minimal configuration required -:: - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/azure" title="the Nitro documentation for Azure deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/cloudflare.md b/docs/content/2.guide/5.deploy/providers/cloudflare.md deleted file mode 100644 index 4ae61ed81022..000000000000 --- a/docs/content/2.guide/5.deploy/providers/cloudflare.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -icon: LogoCloudFlare ---- - -# Cloudflare Workers - -How to deploy Nuxt to [Cloudflare Workers](https://workers.cloudflare.com/). - -::list - -- Support for Workers build output -- Zero-millisecond cold start with edge-side rendering -- Minimal configuration required -:: - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/cloudflare" title="the Nitro documentation for Cloudflare deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/digitalocean.md b/docs/content/2.guide/5.deploy/providers/digitalocean.md deleted file mode 100644 index 6dca370b3194..000000000000 --- a/docs/content/2.guide/5.deploy/providers/digitalocean.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -icon: IconCloud ---- - -# DigitalOcean - -Nitro supports deploying on the [Digital Ocean App Platform](https://docs.digitalocean.com/products/app-platform/) with minimal configuration. - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/digitalocean" title="the Nitro documentation for DigitalOcean deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/firebase.md b/docs/content/2.guide/5.deploy/providers/firebase.md deleted file mode 100644 index 40a0d83007dd..000000000000 --- a/docs/content/2.guide/5.deploy/providers/firebase.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -icon: LogoFirebase ---- - -# Firebase Hosting - -How to deploy Nuxt to [Firebase Hosting](https://firebase.google.com/docs/hosting). - -Nitro supports [Firebase Hosting](https://firebase.google.com/docs/hosting) with Cloud Functions out of the box. - -**Note**: You need to be on the **Blaze plan** to use Nitro with Cloud Functions. - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/firebase" title="the Nitro documentation for Firebase deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/heroku.md b/docs/content/2.guide/5.deploy/providers/heroku.md deleted file mode 100644 index e74b8a9b66e3..000000000000 --- a/docs/content/2.guide/5.deploy/providers/heroku.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -icon: IconCloud ---- - -# Heroku - -How to deploy Nuxt to [Heroku](https://www.heroku.com/). - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/heroku" title="the Nitro documentation for Heroku deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/index.md b/docs/content/2.guide/5.deploy/providers/index.md deleted file mode 100644 index dc762ec9a6c6..000000000000 --- a/docs/content/2.guide/5.deploy/providers/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -navigation: false ---- diff --git a/docs/content/2.guide/5.deploy/providers/layer0.md b/docs/content/2.guide/5.deploy/providers/layer0.md deleted file mode 100644 index 2d9718a001a2..000000000000 --- a/docs/content/2.guide/5.deploy/providers/layer0.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -icon: IconCloud ---- - -# Layer0 - -Nitro provides a built-in preset to generate output format compatible with [Layer0](https://www.layer0.co/). - -Layer0 extends the capabilities of a traditional CDN by not only hosting your static content, but also providing server-side rendering for progressive web applications as well as caching both your APIs and HTML at the network edge to provide your users with the fastest browsing experience. - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/layer0" title="the Nitro documentation for Layer0 deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/netlify.md b/docs/content/2.guide/5.deploy/providers/netlify.md deleted file mode 100644 index 1e244add2559..000000000000 --- a/docs/content/2.guide/5.deploy/providers/netlify.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -icon: LogoNetlify ---- - -# Netlify - -How to deploy Nuxt to [Netlify](https://www.netlify.com/). - -::list - -- Support for serverless SSR using Netlify Functions and Edge -- Auto-detected when deploying -- No configuration required - -:: - -## Setup - -Normally, the deployment to Netlify does not require any configuration. Nuxt will auto-detect that you are in a [Netlify](https://www.netlify.com) build environment and build the correct version of your Nuxt server. For new sites, Netlify will detect that you are using Nuxt and set the publish directory to `dist` and build command to `npm run build`. If you are upgrading an existing site, you should check these and update them if needed. - -To trigger a deploy, just push to your git repository [as you would normally do for Netlify](https://docs.netlify.com/configure-builds/get-started/). - -By default, Nuxt will server-render each page on server hit using [Netlify Functions](https://docs.netlify.com/functions/overview/). You can optionally configure deployment to use [Netlify Edge Functions](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) or [Netlify On-demand Builders](https://docs.netlify.com/configure-builds/on-demand-builders/). - -## Netlify Edge Functions - -[Netlify Edge Functions](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) use [Deno](https://deno.land) and the powerful V8 JavaScript runtime to let you run globally distributed functions for the fastest possible response times. Nuxt output can directly run the server at the edge - closer to your users! - -Read more in the [Netlify Edge Functions announcement](https://www.netlify.com/blog/announcing-serverless-compute-with-edge-functions). - -## On-demand Builders - -[Netlify On-demand Builders](https://docs.netlify.com/configure-builds/on-demand-builders/) are serverless functions used to generate web content as needed that’s automatically cached on Netlify’s Edge CDN. They enable you to build pages for your site when a user visits them for the first time and then cache them at the edge for subsequent visits (also known as Incremental Static Regeneration). - -## Custom Redirects - -If you want to add custom redirects, you can do so by adding a [`_redirects`](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file) file in the [`public`](/guide/directory-structure/public) directory. - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/netlify" title="the Nitro documentation for Netlify deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/render.md b/docs/content/2.guide/5.deploy/providers/render.md deleted file mode 100644 index 8ce480e61e3c..000000000000 --- a/docs/content/2.guide/5.deploy/providers/render.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -icon: IconCloud ---- - -# Render - -How to deploy Nuxt to [Render](https://render.com/) - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/render" title="the Nitro documentation for Render deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/stormkit.md b/docs/content/2.guide/5.deploy/providers/stormkit.md deleted file mode 100644 index 6ba1b1fadb40..000000000000 --- a/docs/content/2.guide/5.deploy/providers/stormkit.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -icon: IconCloud ---- - -# StormKit - -How to deploy Nuxt to [StormKit](https://app.stormkit.io/?referral=nuxtjs). - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/stormkit" title="the Nitro documentation for StormKit deployment"} diff --git a/docs/content/2.guide/5.deploy/providers/vercel.md b/docs/content/2.guide/5.deploy/providers/vercel.md deleted file mode 100644 index 9d0ae05c8385..000000000000 --- a/docs/content/2.guide/5.deploy/providers/vercel.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -icon: LogoVercel ---- - -# Vercel - -Nuxt on Vercel supports server-rendered pages and API routes. - -::list - -- Support for serverless build -- Auto-detected when deploying -- No configuration required -:: - -## Git - -1. Push your code to your git repository (GitHub, GitLab, Bitbucket). -2. [Import your project](https://vercel.com/new) into Vercel. -3. Vercel will detect that you are using Nuxt and will enable the correct settings for your deployment. -4. Your application is deployed! (e.g. [nuxt.vercel.app](https://nuxt.vercel.app/)) - -After your project has been imported and deployed, all subsequent pushes to branches will generate [Preview Deployments](https://vercel.com/docs/concepts/deployments/environments#preview), and all changes made to the Production Branch (commonly β€œmain”) will result in a [Production Deployment](https://vercel.com/docs/concepts/deployments/environments#production). - -Learn more about Vercel’s [Git Integration](https://vercel.com/docs/concepts/git). - -## CLI - -1. Install the [Vercel CLI](https://vercel.com/cli). -2. Vercel will detect that you are using Nuxt and will enable the correct settings for your deployment. -3. Your application is deployed! (e.g. [nuxt.vercel.app](https://nuxt.vercel.app/)) - -```bash -npm i -g vercel -npx nuxi init -t v3-vercel -vercel -``` - -## Learn More - -:ReadMore{link="https://nitro.unjs.io/deploy/providers/vercel" title="the Nitro documentation for Vercel deployment"} diff --git a/docs/content/2.guide/index.md b/docs/content/2.guide/index.md index 9efa4b2b220b..78b0134f5318 100644 --- a/docs/content/2.guide/index.md +++ b/docs/content/2.guide/index.md @@ -2,5 +2,5 @@ title: Guide layout.aside: true navigation.exclusive: true -navigation.redirect: /guide/concepts/introduction +navigation.redirect: /guide/concepts/auto-imports --- diff --git a/docs/content/3.api/1.composables/update-app-config.md b/docs/content/3.api/1.composables/update-app-config.md index f3038c26dbfd..21b1aed3b40a 100644 --- a/docs/content/3.api/1.composables/update-app-config.md +++ b/docs/content/3.api/1.composables/update-app-config.md @@ -1,6 +1,6 @@ # `updateAppConfig` -Updates [app config](/guide/features/app-config) using deep assignment. Existing (nested) properties will be preserved. +Updates [app config](/guide/directory-structure/app.config) using deep assignment. Existing (nested) properties will be preserved. **Usage:** @@ -14,4 +14,4 @@ updateAppConfig(newAppConfig) console.log(appConfig) // { foo: 'baz' } ``` -::ReadMore{link="/guide/features/app-config"} +::ReadMore{link="/guide/directory-structure/app.config"} diff --git a/docs/content/3.api/1.composables/use-app-config.md b/docs/content/3.api/1.composables/use-app-config.md index 7d71b901f58e..d018007e5666 100644 --- a/docs/content/3.api/1.composables/use-app-config.md +++ b/docs/content/3.api/1.composables/use-app-config.md @@ -10,4 +10,4 @@ const appConfig = useAppConfig() console.log(appConfig) ``` -::ReadMore{link="/guide/features/app-config"} +::ReadMore{link="/guide/directory-structure/app.config"} 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 da7845908922..6093917cc8e3 100644 --- a/docs/content/3.api/1.composables/use-async-data.md +++ b/docs/content/3.api/1.composables/use-async-data.md @@ -79,5 +79,5 @@ const { data, pending, error, refresh } = await useAsyncData( ) ``` -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: diff --git a/docs/content/3.api/1.composables/use-error.md b/docs/content/3.api/1.composables/use-error.md index 523428cf659b..5787fca62367 100644 --- a/docs/content/3.api/1.composables/use-error.md +++ b/docs/content/3.api/1.composables/use-error.md @@ -10,5 +10,5 @@ const error = useError() `useError` sets an error in the state and creates a reactive and SSR-friendly global Nuxt error across components. -::ReadMore{link="/guide/features/error-handling"} +::ReadMore{link="/getting-started/error-handling"} :: diff --git a/docs/content/3.api/1.composables/use-fetch.md b/docs/content/3.api/1.composables/use-fetch.md index 2c689672c12c..c44b6e4f2582 100644 --- a/docs/content/3.api/1.composables/use-fetch.md +++ b/docs/content/3.api/1.composables/use-fetch.md @@ -102,6 +102,6 @@ const { data, pending, error, refresh } = await useFetch('/api/auth/login', { }) ``` -:ReadMore{link="/guide/features/data-fetching"} +:ReadMore{link="/getting-started/data-fetching"} :LinkExample{link="/examples/composables/use-fetch"} diff --git a/docs/content/3.api/1.composables/use-hydration.md b/docs/content/3.api/1.composables/use-hydration.md index 088d8b0985b5..eba45d775d43 100644 --- a/docs/content/3.api/1.composables/use-hydration.md +++ b/docs/content/3.api/1.composables/use-hydration.md @@ -1,6 +1,6 @@ # `useHydration` -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: ::NeedContribution diff --git a/docs/content/3.api/1.composables/use-lazy-async-data.md b/docs/content/3.api/1.composables/use-lazy-async-data.md index 1d8b298777b2..22ce1cfc04e8 100644 --- a/docs/content/3.api/1.composables/use-lazy-async-data.md +++ b/docs/content/3.api/1.composables/use-lazy-async-data.md @@ -32,4 +32,4 @@ watch(count, (newCount) => { ``` -:ReadMore{link="/guide/features/data-fetching#uselazyasyncdata"} +:ReadMore{link="/getting-started/data-fetching#uselazyasyncdata"} diff --git a/docs/content/3.api/1.composables/use-lazy-fetch.md b/docs/content/3.api/1.composables/use-lazy-fetch.md index df8c26252cb8..e99e63b5949d 100644 --- a/docs/content/3.api/1.composables/use-lazy-fetch.md +++ b/docs/content/3.api/1.composables/use-lazy-fetch.md @@ -36,4 +36,4 @@ watch(posts, (newPosts) => { ``` -:ReadMore{link="/guide/features/data-fetching#uselazyfetch"} +:ReadMore{link="/getting-started/data-fetching#uselazyfetch"} diff --git a/docs/content/3.api/1.composables/use-route.md b/docs/content/3.api/1.composables/use-route.md index 48045f12bca4..202a9bd2d92e 100644 --- a/docs/content/3.api/1.composables/use-route.md +++ b/docs/content/3.api/1.composables/use-route.md @@ -36,6 +36,3 @@ Apart from dynamic parameters and query parameters, `useRoute()` also provides t ::ReadMore{link="https://router.vuejs.org/api/interfaces/RouteLocationNormalizedLoaded.html"} :: - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/1.composables/use-router.md b/docs/content/3.api/1.composables/use-router.md index 66d9e9f2a311..3c691fa202b2 100644 --- a/docs/content/3.api/1.composables/use-router.md +++ b/docs/content/3.api/1.composables/use-router.md @@ -57,6 +57,3 @@ However, Nuxt has a concept of **route middleware** that simplifies the implemen ## Universal Router Instance If you do not have a `pages/` folder, then `useRouter` will return a universal router instance with similar helper methods, but be aware that not all features may be supported or behave in exactly the same way as with `vue-router`. - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/1.composables/use-state.md b/docs/content/3.api/1.composables/use-state.md index f854881b3207..97d80007328b 100644 --- a/docs/content/3.api/1.composables/use-state.md +++ b/docs/content/3.api/1.composables/use-state.md @@ -13,5 +13,5 @@ useState(key: string, init?: () => T | Ref): Ref Because the data inside `useState` will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols. :: -::ReadMore{link="/guide/features/state-management"} +::ReadMore{link="/getting-started/state-management"} :: diff --git a/docs/content/3.api/2.components/4.nuxt-link.md b/docs/content/3.api/2.components/4.nuxt-link.md index ba49defcbd7d..b113d9e1c3ee 100644 --- a/docs/content/3.api/2.components/4.nuxt-link.md +++ b/docs/content/3.api/2.components/4.nuxt-link.md @@ -1,8 +1,5 @@ # `` -::ReadMore{link="/guide/features/routing"} -:: - Nuxt provides `` component to handle any kind of links within your application. `` is a drop-in replacement for both Vue Router's `` component and HTML's `` tag. It intelligently determines whether the link is _internal_ or _external_ and renders it accordingly with available optimizations (prefetching, default attributes, etc.) @@ -81,6 +78,8 @@ In this example, we use `` with `target`, `rel`, and `noRel` props. - **replace**: Works the same as [Vue Router's `replace` prop](https://router.vuejs.org/api/#replace) on internal links - **ariaCurrentValue**: An `aria-current` attribute value to apply on exact active links. Works the same as [Vue Router's `aria-current-value` prop](https://router.vuejs.org/api/#aria-current-value) on internal links - **external**: Forces the link to be considered as external (`true`) or internal (`false`). This is helpful to handle edge-cases +- **prefetch** and **noPrefetch**: Whether to enable prefetching assets for links that enter the view port. +- **prefetchedClass**: A class to apply to links that have been prefetched. - **custom**: Whether `` should wrap its content in an `` element. It allows taking full control of how a link is rendered and how navigation works when it is clicked. Works the same as [Vue Router's `custom` prop](https://router.vuejs.org/api/#custom) ::alert{icon=πŸ‘‰} @@ -110,6 +109,7 @@ defineNuxtLink({ externalRelAttribute?: string; activeClass?: string; exactActiveClass?: string; + prefetchedClass?: string; }) => Component ``` @@ -117,5 +117,6 @@ defineNuxtLink({ - **externalRelAttribute**: A default `rel` attribute value applied on external links. Defaults to `"noopener noreferrer"`. Set it to `""` to disable - **activeClass**: A default class to apply on active links. Works the same as [Vue Router's `linkActiveClass` option](https://router.vuejs.org/api/#linkactiveclass). Defaults to Vue Router's default (`"router-link-active"`) - **exactActiveClass**: A default class to apply on exact active links. Works the same as [Vue Router's `linkExactActiveClass` option](https://router.vuejs.org/api/#linkexactactiveclass). Defaults to Vue Router's default (`"router-link-exact-active"`) +- **prefetchedClass**: A default class to apply to links that have been prefetched. :LinkExample{link="/examples/routing/nuxt-link"} diff --git a/docs/content/3.api/2.components/4.nuxt-loading-indicator.md b/docs/content/3.api/2.components/4.nuxt-loading-indicator.md index 1bdb23a4bfac..517d5602e312 100644 --- a/docs/content/3.api/2.components/4.nuxt-loading-indicator.md +++ b/docs/content/3.api/2.components/4.nuxt-loading-indicator.md @@ -1,8 +1,5 @@ # `` -::ReadMore{link="/guide/features/routing"} -:: - Nuxt provides `` to display a progress bar on page navigation. ## Examples diff --git a/docs/content/3.api/2.components/5.nuxt-error-boundary.md b/docs/content/3.api/2.components/5.nuxt-error-boundary.md index 7cbe43de044e..ae4b8c2ffa1c 100644 --- a/docs/content/3.api/2.components/5.nuxt-error-boundary.md +++ b/docs/content/3.api/2.components/5.nuxt-error-boundary.md @@ -29,5 +29,5 @@ Nuxt provides the `` component to handle client-side errors h ``` -::ReadMore{link="/guide/features/error-handling"} +::ReadMore{link="/getting-started/error-handling"} :: diff --git a/docs/content/2.guide/2.features/11.teleports.md b/docs/content/3.api/2.components/7.teleports.md similarity index 98% rename from docs/content/2.guide/2.features/11.teleports.md rename to docs/content/3.api/2.components/7.teleports.md index 13253fdf964d..a21541b7c215 100644 --- a/docs/content/2.guide/2.features/11.teleports.md +++ b/docs/content/3.api/2.components/7.teleports.md @@ -1,4 +1,4 @@ -# Teleports +# `` Vue 3 provides the [`` component](https://vuejs.org/guide/built-ins/teleport.html) which allows content to be rendered elsewhere in the DOM, outside of the Vue application. diff --git a/docs/content/3.api/3.utils/$fetch.md b/docs/content/3.api/3.utils/$fetch.md index 2db7045b249d..63adb2bb1cf7 100644 --- a/docs/content/3.api/3.utils/$fetch.md +++ b/docs/content/3.api/3.utils/$fetch.md @@ -1,6 +1,6 @@ # `$fetch` -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: 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. diff --git a/docs/content/3.api/3.utils/abort-navigation.md b/docs/content/3.api/3.utils/abort-navigation.md index 9b636c5ab13c..119151b267c6 100644 --- a/docs/content/3.api/3.utils/abort-navigation.md +++ b/docs/content/3.api/3.utils/abort-navigation.md @@ -63,6 +63,3 @@ export default defineNuxtRouteMiddleware((to, from) => { } }) ``` - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/3.utils/add-route-middleware.md b/docs/content/3.api/3.utils/add-route-middleware.md index 4ad66bcd09fa..8add9a93d33c 100644 --- a/docs/content/3.api/3.utils/add-route-middleware.md +++ b/docs/content/3.api/3.utils/add-route-middleware.md @@ -71,6 +71,3 @@ export default defineNuxtPlugin(() => { ) }) ``` - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/3.utils/clear-error.md b/docs/content/3.api/3.utils/clear-error.md index e92a716eccae..4191a76756dc 100644 --- a/docs/content/3.api/3.utils/clear-error.md +++ b/docs/content/3.api/3.utils/clear-error.md @@ -20,5 +20,5 @@ clearError({ redirect: '/homepage' }) Errors are set in state using [`useError()`](/api/composables/use-error). The `clearError` composable will reset this state and calls the `app:error:cleared` hook with the provided options. -::ReadMore{link="/guide/features/error-handling"} +::ReadMore{link="/getting-started/error-handling"} :: diff --git a/docs/content/3.api/3.utils/clear-nuxt-data.md b/docs/content/3.api/3.utils/clear-nuxt-data.md index c00036bbeb56..be91e5c2aa94 100644 --- a/docs/content/3.api/3.utils/clear-nuxt-data.md +++ b/docs/content/3.api/3.utils/clear-nuxt-data.md @@ -1,8 +1,5 @@ # `clearNuxtData` -::StabilityEdge -:: - Delete cached data, error status and pending promises of `useAsyncData` and `useFetch`. This method is useful if you want to invalidate the data fetching for another page. diff --git a/docs/content/3.api/3.utils/create-error.md b/docs/content/3.api/3.utils/create-error.md index ae021d2b0b62..cdea2a6f8ddd 100644 --- a/docs/content/3.api/3.utils/create-error.md +++ b/docs/content/3.api/3.utils/create-error.md @@ -40,5 +40,5 @@ export default eventHandler(() => { } ``` -::ReadMore{link="/guide/features/error-handling"} +::ReadMore{link="/getting-started/error-handling"} :: 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 1a718a0a6cfb..ed55f5edebb7 100644 --- a/docs/content/3.api/3.utils/define-nuxt-component.md +++ b/docs/content/3.api/3.utils/define-nuxt-component.md @@ -1,4 +1,31 @@ # `defineNuxtComponent` -::NeedContribution +`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. + +::alert{type=warning} +Options API support for `asyncData` may well change before the stable release of Nuxt 3. +:: + +::Alert +Using ` +``` diff --git a/docs/content/3.api/3.utils/define-nuxt-route-middleware.md b/docs/content/3.api/3.utils/define-nuxt-route-middleware.md index 58cbcc68661c..747bf5f6072c 100644 --- a/docs/content/3.api/3.utils/define-nuxt-route-middleware.md +++ b/docs/content/3.api/3.utils/define-nuxt-route-middleware.md @@ -57,6 +57,3 @@ export default defineNuxtRouteMiddleware((to, from) => { ``` Both [navigateTo](/api/utils/navigate-to) and [abortNavigation](/api/utils/abort-navigation) are globally available helper functions that you can use inside `defineNuxtRouteMiddleware`. - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/3.utils/define-page-meta.md b/docs/content/3.api/3.utils/define-page-meta.md index a26061950221..ef8ef33ec9f3 100644 --- a/docs/content/3.api/3.utils/define-page-meta.md +++ b/docs/content/3.api/3.utils/define-page-meta.md @@ -19,6 +19,8 @@ definePageMeta(meta: PageMeta) => void interface PageMeta { + redirect?: RouteRecordRedirectOption + alias?: string | string[] pageTransition?: boolean | TransitionProps layoutTransition?: boolean | TransitionProps key?: false | string | ((route: RouteLocationNormalizedLoaded) => string) @@ -73,6 +75,20 @@ interface PageMeta { Define anonymous or named middleware directly within `definePageMeta`. Learn more about [route middleware](/docs/directory-structure/middleware). + **`redirect`** + + - **Type**: [`RouteRecordRedirectOption`](https://router.vuejs.org/guide/essentials/redirect-and-alias.html#redirect-and-alias) + + Where to redirect if the route is directly matched. The redirection happens before any navigation guard and triggers a new navigation with the new target location. + + :StabilityEdge + + **`alias`** + + - **Type**: `string | string[]` + + Aliases for the record. Allows defining extra paths that will behave like a copy of the record. Allows having paths shorthands like `/users/:id` and `/u/:id`. All `alias` and `path` values must share the same params. + **`[key: string]`** - **Type**: `any` @@ -147,6 +163,3 @@ You can define the layout that matches the layout's file name located (by defaul }) ``` - -::ReadMore{link="/guide/features/routing"} -:: diff --git a/docs/content/3.api/3.utils/navigate-to.md b/docs/content/3.api/3.utils/navigate-to.md index c48d0cbd60da..80c1de2fc9bf 100644 --- a/docs/content/3.api/3.utils/navigate-to.md +++ b/docs/content/3.api/3.utils/navigate-to.md @@ -71,13 +71,13 @@ An object accepting the following properties: ```vue ``` 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 79afabf7635d..6c38fb6fa35b 100644 --- a/docs/content/3.api/3.utils/refresh-nuxt-data.md +++ b/docs/content/3.api/3.utils/refresh-nuxt-data.md @@ -1,6 +1,6 @@ # `refreshNuxtData` -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: ```ts diff --git a/docs/content/3.api/3.utils/show-error.md b/docs/content/3.api/3.utils/show-error.md index f54bf7c72219..335891bb1bd6 100644 --- a/docs/content/3.api/3.utils/show-error.md +++ b/docs/content/3.api/3.utils/show-error.md @@ -17,5 +17,5 @@ The error is set in the state using [`useError()`](/api/composables/use-error) t `showError` calls the `app:error` hook. -::ReadMore{link="/guide/features/error-handling"} +::ReadMore{link="/getting-started/error-handling"} :: diff --git a/docs/content/3.api/4.advanced/1.hooks.md b/docs/content/3.api/4.advanced/1.hooks.md index 979f847a86e3..a55c987818b1 100644 --- a/docs/content/3.api/4.advanced/1.hooks.md +++ b/docs/content/3.api/4.advanced/1.hooks.md @@ -18,7 +18,8 @@ Hook | Arguments | Environment | Description `app:redirected` | - | Server | Called before SSR redirection. `app:beforeMount` | `vueApp` | Client | Called before mounting the app, called only on client side. `app:mounted` | `vueApp` | Client | Called when Vue app is initialized and mounted in browser. -`app:suspense:resolve` | `appComponent` | Client | On [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) resolved event +`app:suspense:resolve` | `appComponent` | Client | On [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) resolved event. +`link:prefetch` | `to` | Client | Called when a `` is observed to be prefetched. `page:start` | `pageComponent?` | Client | Called on [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) pending event. `page:finish` | `pageComponent?` | Client | Called on [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) resolved event. @@ -27,3 +28,10 @@ Hook | Arguments | Environment | Description Check the [schema source code](https://github.com/nuxt/framework/blob/main/packages/schema/src/types/hooks.ts#L55) for all available hooks. :NeedContribution + +# Nitro App Hooks (runtime, server-side) + +Hook | Arguments | Description | Types +-----------------------|-----------------------|--------------------------------------|------------------ +`render:response` | `response, { event }` | Called before sending the response. | [response](https://github.com/nuxt/framework/blob/71ef8bd3ff207fd51c2ca18d5a8c7140476780c7/packages/nuxt/src/core/runtime/nitro/renderer.ts#L24), [event](https://github.com/unjs/h3/blob/f6ceb5581043dc4d8b6eab91e9be4531e0c30f8e/src/types.ts#L38) +`render:html` | `html, { event }` | Called before constructing the HTML. | [html](https://github.com/nuxt/framework/blob/71ef8bd3ff207fd51c2ca18d5a8c7140476780c7/packages/nuxt/src/core/runtime/nitro/renderer.ts#L15), [event](https://github.com/unjs/h3/blob/f6ceb5581043dc4d8b6eab91e9be4531e0c30f8e/src/types.ts#L38) diff --git a/docs/content/3.api/4.advanced/2.kit.md b/docs/content/3.api/4.advanced/2.kit.md index 8807dd844efd..ecafb3c682c9 100644 --- a/docs/content/3.api/4.advanced/2.kit.md +++ b/docs/content/3.api/4.advanced/2.kit.md @@ -32,10 +32,11 @@ ### Auto-imports -[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/auto-import.ts) +[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/imports.ts) -- `addAutoImport(imports)` -- `addAutoImportDir(autoImportDirs)` +- `addImports(imports)` +- `addImportsDir(autoImportDirs)` +- `addImportsSources(autoImportSources)` ### Components @@ -63,13 +64,14 @@ - `addTemplate(templateOptions)` -### Server +### Nitro -[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/server.ts) +[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/nitro.ts) - ~~`addServerMiddleware(serverMiddleware)`~~ - `addServerHandler (handler)` - `addDevServerHandler (handler)` +- `useNitro()` (only usable after `ready` hook) ### Resolving diff --git a/docs/content/3.api/5.commands/build.md b/docs/content/3.api/5.commands/build.md index fbedf82429ad..696f3e8a728e 100644 --- a/docs/content/3.api/5.commands/build.md +++ b/docs/content/3.api/5.commands/build.md @@ -1,7 +1,7 @@ # `nuxi build` ```{bash} -npx nuxi build [rootDir] +npx nuxi build [rootDir] [--prerender] [--dotenv] ``` The `build` command creates a `.output` directory with all your application, server and dependencies ready for production. @@ -9,6 +9,7 @@ The `build` command creates a `.output` directory with all your application, ser Option | Default | Description -------------------------|-----------------|------------------ `rootDir` | `.` | The root directory of the application to bundle. -`prerender` | `false` | Pre-render every route of your application. (**note:** This is an experimental flag. The behavior might be changed.) +`--prerender` | `false` | Pre-render every route of your application. (**note:** This is an experimental flag. The behavior might be changed.) +`--dotenv` | `.` | Point to another `.env` file to load, **relative** to the root directory. This command sets `process.env.NODE_ENV` to `production`. diff --git a/docs/content/3.api/5.commands/dev.md b/docs/content/3.api/5.commands/dev.md index ef603dbbc856..fc74a0d5b070 100644 --- a/docs/content/3.api/5.commands/dev.md +++ b/docs/content/3.api/5.commands/dev.md @@ -1,7 +1,7 @@ # `nuxi dev` ```{bash} -npx nuxi dev [rootDir] [--clipboard] [--open, -o] [--no-clear] [--port, -p] [--host, -h] [--https] [--ssl-cert] [--ssl-key] +npx nuxi dev [rootDir] [--dotenv] [--clipboard] [--open, -o] [--no-clear] [--port, -p] [--host, -h] [--https] [--ssl-cert] [--ssl-key] ``` The `dev` command starts a development server with hot module replacement at [http://localhost:3000](https://localhost:3000) @@ -9,6 +9,7 @@ The `dev` command starts a development server with hot module replacement at [ht Option | Default | Description -------------------------|-----------------|------------------ `rootDir` | `.` | The root directory of the application to serve. +`--dotenv` | `.` | Point to another `.env` file to load, **relative** to the root directory. `--clipboard` | `false` | Copy URL to clipboard. `--open, -o` | `false` | Open URL in browser. `--no-clear` | `false` | Does not clear the console after startup. diff --git a/docs/content/3.api/5.commands/preview.md b/docs/content/3.api/5.commands/preview.md index c7d2b524d1bc..4b86222e9998 100644 --- a/docs/content/3.api/5.commands/preview.md +++ b/docs/content/3.api/5.commands/preview.md @@ -1,7 +1,7 @@ # `nuxi preview` ```{bash} -npx nuxi preview [rootDir] +npx nuxi preview [rootDir] [--dotenv] ``` The `preview` command starts a server to preview your Nuxt application after running the `build` command. @@ -9,6 +9,7 @@ The `preview` command starts a server to preview your Nuxt application after run Option | Default | Description -------------------------|-----------------|------------------ `rootDir` | `.` | The root directory of the application to preview. +`--dotenv` | `.` | Point to another `.env` file to load, **relative** to the root directory. This command sets `process.env.NODE_ENV` to `production`. To override, define `NODE_ENV` in a `.env` file or as command-line argument. diff --git a/docs/content/4.examples/0.essentials/hello-world.md b/docs/content/4.examples/0.essentials/hello-world.md index a2e1e20d5444..51ab227ac0ab 100644 --- a/docs/content/4.examples/0.essentials/hello-world.md +++ b/docs/content/4.examples/0.essentials/hello-world.md @@ -6,7 +6,7 @@ template: Example A minimal Nuxt 3 application only requires the `app.vue` and `nuxt.config.js` files. -::ReadMore{link="/getting-started/quick-start"} +::ReadMore{link="/getting-started/introduction"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/essentials/hello-world" file="app.vue"} diff --git a/docs/content/4.examples/1.app/error-handling.md b/docs/content/4.examples/1.app/error-handling.md index 820c6ea8c211..0d9185f34fef 100644 --- a/docs/content/4.examples/1.app/error-handling.md +++ b/docs/content/4.examples/1.app/error-handling.md @@ -6,7 +6,7 @@ template: Example This example shows how to handle errors in different contexts: pages, plugins, components and middleware. -::ReadMore{link="/guide/features/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/teleport.md b/docs/content/4.examples/1.app/teleport.md index 3832047238d6..4bcdd0e6f4db 100644 --- a/docs/content/4.examples/1.app/teleport.md +++ b/docs/content/4.examples/1.app/teleport.md @@ -8,7 +8,7 @@ Vue 3 provides the [`` component](https://vuejs.org/guide/built-ins/te This example shows how to use the `` with client-side and server-side rendering. -::ReadMore{link="/guide/features/teleports"} +::ReadMore{link="/api/components/teleports"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/app/teleport" file="app.vue"} 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 f4feee5202ee..e8c278988a96 100644 --- a/docs/content/4.examples/3.composables/use-async-data.md +++ b/docs/content/4.examples/3.composables/use-async-data.md @@ -13,7 +13,7 @@ Nuxt will automatically read files in the `~/server/api` directory to create API ::ReadMore{link="/api/composables/use-async-data"} :: -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-async-data" file="app.vue"} diff --git a/docs/content/4.examples/3.composables/use-fetch.md b/docs/content/4.examples/3.composables/use-fetch.md index c9eb401b2b96..113df4d33706 100644 --- a/docs/content/4.examples/3.composables/use-fetch.md +++ b/docs/content/4.examples/3.composables/use-fetch.md @@ -13,7 +13,7 @@ Nuxt will automatically read files in the `~/server/api` directory to create API ::ReadMore{link="/api/composables/use-fetch"} :: -::ReadMore{link="/guide/features/data-fetching"} +::ReadMore{link="/getting-started/data-fetching"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-fetch" file="app.vue"} diff --git a/docs/content/4.examples/3.composables/use-head.md b/docs/content/4.examples/3.composables/use-head.md index 3681424d2929..265afafb8d91 100644 --- a/docs/content/4.examples/3.composables/use-head.md +++ b/docs/content/4.examples/3.composables/use-head.md @@ -13,7 +13,7 @@ Learn more about [meta tags](/guide/features/head-management#meta-components). ::ReadMore{link="/api/composables/use-head"} :: -::ReadMore{link="/guide/features/head-management"} +::ReadMore{link="/getting-started/head-management"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-head" file="app.vue"} diff --git a/docs/content/4.examples/3.composables/use-state.md b/docs/content/4.examples/3.composables/use-state.md index 71e25358218f..d216941ffba8 100644 --- a/docs/content/4.examples/3.composables/use-state.md +++ b/docs/content/4.examples/3.composables/use-state.md @@ -13,7 +13,7 @@ Learn more about [useState](/api/composables/use-state). ::ReadMore{link="/api/composables/use-state"} :: -::ReadMore{link="/guide/features/state-management"} +::ReadMore{link="/getting-started/state-management"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-state" file="app.vue"} diff --git a/docs/content/4.examples/4.routing/universal-router.md b/docs/content/4.examples/4.routing/universal-router.md index 710906390514..f52df483701d 100644 --- a/docs/content/4.examples/4.routing/universal-router.md +++ b/docs/content/4.examples/4.routing/universal-router.md @@ -6,7 +6,4 @@ template: Example This example demonstrates Nuxt universal routing utilities without depending on `pages/` and `vue-router`. -::ReadMore{link="/guide/features/routing"} -:: - ::sandbox{repo="nuxt/framework" branch="main" dir="examples/routing/universal-router" file="app.vue"} diff --git a/docs/content/4.examples/5.server/routes.md b/docs/content/4.examples/5.server/routes.md index b7768bb461fc..ea49a72874cd 100644 --- a/docs/content/4.examples/5.server/routes.md +++ b/docs/content/4.examples/5.server/routes.md @@ -6,7 +6,7 @@ template: Example This example shows how to create server routes inside the `server/api` directory. -::ReadMore{link="/guide/features/server-routes"} +::ReadMore{link="/guide/directory-structure/server"} :: ::sandbox{repo="nuxt/framework" branch="main" dir="examples/server/routes" file="app.vue"} diff --git a/docs/content/5.community/2.reporting-bugs.md b/docs/content/5.community/2.reporting-bugs.md index 5489a0930349..59a629239bbf 100644 --- a/docs/content/5.community/2.reporting-bugs.md +++ b/docs/content/5.community/2.reporting-bugs.md @@ -25,7 +25,7 @@ If your issue concerns Vue 3 or Vite, please try to reproduce it first with the **Nuxt 3**: :button-link[Nuxt 3 on StackBlitz]{href="https://stackblitz.com/github/nuxt/starter/tree/v3-stackblitz" blank} -:button-link[Nuxt 3 on CodeSandbox]{href="https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox" blank} +:button-link[Nuxt 3 on CodeSandbox]{href="https://codesandbox.io/p/github/nuxt/starter/v3-codesandbox" blank} **Nuxt Bridge**: diff --git a/docs/content/5.community/5.roadmap.md b/docs/content/5.community/5.roadmap.md index 1288170a14d7..2b213a96c07d 100644 --- a/docs/content/5.community/5.roadmap.md +++ b/docs/content/5.community/5.roadmap.md @@ -18,8 +18,8 @@ Nuxt is constantly evolving, with new features and modules being added all the t Release | Expected date | Description --------------------|-----------------|--------------------------------------------------- -`nuxt@2.16` | Summer, 2022 | Nuxt v2 cumulative updates for future compatibility with Bridge -`nuxt@3.0.0` | Summer, 2022 | Nuxt v3 stable release +`nuxt@2.16` | Autumn, 2022 | Nuxt v2 cumulative updates for future compatibility with Bridge +`nuxt@3.0.0` | Autumn, 2022 | Nuxt v3 final release ### Current Releases @@ -61,6 +61,6 @@ 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](https://github.com/nuxt/auth) | Nuxt 3 support is planned after session support +Auth | WIP | 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/_collections/header.md b/docs/content/_collections/header.md index fbd2feb0b1d6..a956f0986bbc 100644 --- a/docs/content/_collections/header.md +++ b/docs/content/_collections/header.md @@ -2,10 +2,10 @@ links: - title: 'Getting Started' - to: '/getting-started/quick-start' + to: '/getting-started/introduction' - title: 'Guide' - to: '/guide/concepts/introduction' + to: '/guide/concepts/auto-imports' - title: 'API' to: '/api/composables/use-async-data' diff --git a/docs/content/bridge/1.overview.md b/docs/content/bridge/1.overview.md index eab7c11bd355..aec21984ba3c 100644 --- a/docs/content/bridge/1.overview.md +++ b/docs/content/bridge/1.overview.md @@ -9,11 +9,11 @@ head.titleTemplate: '' Experience Nuxt 3 features on existing Nuxt 2 projects. ::alert -If you're starting a fresh Nuxt 3 project, please skip this section and go to [Nuxt 3 Installation](/getting-started/quick-start). +If you're starting a fresh Nuxt 3 project, please skip this section and go to [Nuxt 3 Installation](/getting-started/introduction). :: ::alert{type=warning} -Nuxt Bridge provides identical features to Nuxt 3 ([docs](/guide/features)) but there are some limitations, notably that `useAsyncData` and `useFetch` composables are not available. Please read the rest of this page for details. +Nuxt Bridge provides identical features to Nuxt 3 ([docs](/guide)) but there are some limitations, notably that `useAsyncData` and `useFetch` composables are not available. Please read the rest of this page for details. :: Bridge is a forward-compatibility layer that allows you to experience many of the new Nuxt 3 features by simply installing and enabling a Nuxt module. @@ -149,6 +149,36 @@ Overwriting options such as `"compilerOptions.paths"` with your own configuratio In case you need to extend options provided by `./.nuxt/tsconfig.json` further, you can use the `alias` property withing your `nuxt.config`. `nuxi` will pick them up and extend `./.nuxt/tsconfig.json` accordingly. :: +## Update Runtime Config + +Nuxt 3 approaches runtime config differently than Nuxt 2, using a new combined `runtimeConfig` option. + +First, you'll need to combine your `publicRuntimeConfig` and `privateRuntimeConfig` properties into a new one called `runtimeConfig`, with the public config within a key called `public`. + +```diff +// nuxt.config.js +- privateRuntimeConfig: { +- apiKey: process.env.NUXT_API_KEY || 'super-secret-key' +- }, +- publicRuntimeConfig: { +- websiteURL: 'https://public-data.com' +- } ++ runtimeConfig: { ++ apiKey: process.env.NUXT_API_KEY || 'super-secret-key', ++ public: { ++ websiteURL: 'https://public-data.com' ++ } ++ } +``` + +This also means that when you need to access public runtime config, it's behind a property called `public`. If you use public runtime config, you'll need to update your code. + +```diff +// MyWidget.vue +-
Website: {{ $config.websiteURL }}
++
Website: {{ $config.public.websiteURL }}
+``` + ## Migrate Composition API If you were using `@vue/composition-api` or `@nuxtjs/composition-api`, please read the [composition api migration guide](/bridge/bridge-composition-api). @@ -179,7 +209,6 @@ Add the folder `.output` to the `.gitignore` file. ```ts [nuxt.config.js|ts] import { defineNuxtConfig } from '@nuxt/bridge' - export default defineNuxtConfig({ bridge: false // Temporarily disable bridge integration }) @@ -222,7 +251,6 @@ You will also need to enable this feature explicitly in your `nuxt.config`: ```js import { defineNuxtConfig } from '@nuxt/bridge' - export default defineNuxtConfig({ bridge: { meta: true @@ -233,7 +261,7 @@ export default defineNuxtConfig({ This `useHead` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your ``. Accordingly, we recommend not to use both the native Nuxt 2 `head()` properties as well as `useHead`, as they may conflict. -For more information on how to use this composable, see [the docs](/guide/features/head-management). +For more information on how to use this composable, see [the docs](/getting-started/head-management). ## Feature Flags @@ -243,7 +271,6 @@ You can check [bridge/src/module.ts](https://github.com/nuxt/bridge/blob/main/sr ```ts [nuxt.config.js|ts] import { defineNuxtConfig } from '@nuxt/bridge' - export default defineNuxtConfig({ bridge: { diff --git a/docs/content/bridge/2.bridge-composition-api.md b/docs/content/bridge/2.bridge-composition-api.md index 4180fc3cc5f0..6f05027370f1 100644 --- a/docs/content/bridge/2.bridge-composition-api.md +++ b/docs/content/bridge/2.bridge-composition-api.md @@ -187,7 +187,7 @@ const wrapProperty = (property, makeComputed = true) => () => { ### `useAsync` and `useFetch` -These two composables can be replaced with `useLazyAsyncData` and `useLazyFetch`, which are documented [in the Nuxt 3 docs](/guide/features/data-fetching). Just like the previous `@nuxtjs/composition-api` composables, these composables do not block route navigation on the client-side (hence the 'lazy' part of the name). +These two composables can be replaced with `useLazyAsyncData` and `useLazyFetch`, which are documented [in the Nuxt 3 docs](/getting-started/data-fetching). Just like the previous `@nuxtjs/composition-api` composables, these composables do not block route navigation on the client-side (hence the 'lazy' part of the name). ::alert Note that the API is entirely different, despite similar sounding names. Importantly, you should not attempt to change the value of other variables outside the composable (as you may have been doing with the previous `useFetch`). @@ -275,4 +275,4 @@ export default defineNuxtConfig({ This `useHead` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your ``. Accordingly, it is recommended not to use both the native Nuxt 2 `head()` properties as well as `useHead`, as they may conflict. -For more information on how to use this composable, see [the Nuxt 3 docs](/guide/features/head-management). +For more information on how to use this composable, see [the Nuxt 3 docs](/getting-started/head-management). diff --git a/docs/content/index.md b/docs/content/index.md index 4f8aa0b13d81..82884e68594a 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -21,7 +21,7 @@ Build your next application with Vue 3 and experience hybrid rendering, powerful Nuxt 3 is an open source framework making web development simple and powerful. #secondary-button -:button-link[Get started]{ href="/getting-started/quick-start" size="medium" aria-label="Get started" } +:button-link[Get started]{ href="/getting-started/introduction" size="medium" aria-label="Get started" } :: ::home-features{.dark:bg-secondary-darkest .bg-gray-50} diff --git a/docs/content/migration/2.configuration.md b/docs/content/migration/2.configuration.md index 89a705d1303e..8948aec5efef 100644 --- a/docs/content/migration/2.configuration.md +++ b/docs/content/migration/2.configuration.md @@ -26,8 +26,6 @@ Nuxt configuration will be loaded using [`unjs/jiti`](https://github.com/unjs/ji ``` ```ts [Nuxt 3] - import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ // ... }) @@ -50,8 +48,6 @@ Nuxt configuration will be loaded using [`unjs/jiti`](https://github.com/unjs/ji ``` ```ts [Nuxt 3] - import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ hooks: { 'pages:extend' (routes) { @@ -112,7 +108,7 @@ Nuxt can type-check your app using [`vue-tsc`](https://github.com/johnsoncodehk/ ``` 1. Run `npx nuxi prepare` to generate `.nuxt/tsconfig.json`. -1. Install Volar following the instructions in the [docs](/getting-started/quick-start#prerequisites). +1. Install Volar following the instructions in the [docs](/getting-started/introduction#prerequisites). ## Vue Changes diff --git a/docs/content/migration/3.auto-imports.md b/docs/content/migration/3.auto-imports.md index 4a8937322e41..3d0812c7477d 100644 --- a/docs/content/migration/3.auto-imports.md +++ b/docs/content/migration/3.auto-imports.md @@ -18,5 +18,5 @@ In the rest of the migration documentation, you will notice that key Nuxt and Vu 1. If you have been using `@nuxt/components` in Nuxt 2, you can remove `components: true` in your `nuxt.config`. If you had a more complex setup, then note that the component options have changed somewhat. See the [components documentation](/guide/directory-structure/components) for more information. ::alert{type=info} -You can look at `.nuxt/types/components.d.ts` and `.nuxt/types/auto-imports.d.ts` to see how Nuxt has resolved your components and composable auto-imports. +You can look at `.nuxt/types/components.d.ts` and `.nuxt/types/imports.d.ts` to see how Nuxt has resolved your components and composable auto-imports. :: diff --git a/docs/content/migration/4.meta.md b/docs/content/migration/4.meta.md index bdc1ede90154..427613130e0f 100644 --- a/docs/content/migration/4.meta.md +++ b/docs/content/migration/4.meta.md @@ -8,8 +8,8 @@ head.titleTemplate: '' Nuxt 3 provides several different ways to manage your meta tags. 1. Through your `nuxt.config`. -2. Through the `useHead` [composable](/guide/features/head-management) -3. Through [global meta components](/guide/features/head-management) +2. Through the `useHead` [composable](/getting-started/head-management) +3. Through [global meta components](/getting-started/head-management) You can customize `title`, `titleTemplate`, `base`, `script`, `noscript`, `style`, `meta`, `link`, `htmlAttrs` and `bodyAttrs`. @@ -17,7 +17,7 @@ You can customize `title`, `titleTemplate`, `base`, `script`, `noscript`, `style Nuxt currently uses [`vueuse/head`](https://github.com/vueuse/head) to manage your meta tags, but implementation details may change. :: -[Read more about meta tags](/guide/features/head-management). +[Read more about meta tags](/getting-started/head-management). ## Migration diff --git a/docs/content/migration/6.pages-and-layouts.md b/docs/content/migration/6.pages-and-layouts.md index 2020a5d356af..f7d1003baf4a 100644 --- a/docs/content/migration/6.pages-and-layouts.md +++ b/docs/content/migration/6.pages-and-layouts.md @@ -29,7 +29,7 @@ You will also need to change how you define the layout used by a page using the 1. Replace `` with `` 1. Use `definePageMeta` to select the layout used by your page. -1. Move `~/layouts/_error.vue` to `~/error.vue`. See [the error handling docs](/guide/features/error-handling). +1. Move `~/layouts/_error.vue` to `~/error.vue`. See [the error handling docs](/getting-started/error-handling). ### Example: `~/layouts/custom.vue` @@ -76,7 +76,7 @@ In Nuxt 2, you will have defined any nested routes (with parent and child compon If you were passing a custom page key or keep-alive props to ``, you will now use `definePageMeta` to set these options. -See [more about migrating Nuxt component hooks](/migration/nuxt-hooks). +See [more about migrating Nuxt component hooks](/migration/component-options). ### Page and Layout Transitions diff --git a/docs/content/migration/7.component-options.md b/docs/content/migration/7.component-options.md index 1afbde3289f6..49f03dcf7e18 100644 --- a/docs/content/migration/7.component-options.md +++ b/docs/content/migration/7.component-options.md @@ -7,7 +7,7 @@ head.titleTemplate: '' ## `asyncData` and `fetch` Component Options -Nuxt 3 provides new options for [fetching data from an API](/guide/features/data-fetching). +Nuxt 3 provides new options for [fetching data from an API](/getting-started/data-fetching). @@ -22,7 +22,7 @@ In Nuxt 3 you can use a globally available `fetch` method that has the same API 2. Plus, it comes with convenience features including automatically parsing responses and stringifying data. -You can read more [about direct API calls](/guide/concepts/server-engine#direct-api-calls) or [fetching data](/guide/features/data-fetching). +You can read more [about direct API calls](/guide/concepts/server-engine#direct-api-calls) or [fetching data](/getting-started/data-fetching). ### Using Composables diff --git a/docs/content/migration/8.runtime-config.md b/docs/content/migration/8.runtime-config.md index 2591f50e710b..e2120e7e8483 100644 --- a/docs/content/migration/8.runtime-config.md +++ b/docs/content/migration/8.runtime-config.md @@ -9,7 +9,7 @@ If you wish to reference environment variables within your Nuxt 3 app, you will When referencing these variables within your components, you will have to use the `useRuntimeConfig` composable in your setup method (or Nuxt plugin). In the `server/` portion of your app, you can use `useRuntimeConfig` without any import. -[Read more about runtime config](/guide/features/runtime-config). +[Read more about runtime config](/guide/going-further/runtime-config). ## Migration @@ -21,8 +21,6 @@ When referencing these variables within your components, you will have to use th ::code-group ```ts [nuxt.config.ts] -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ runtimeConfig: { // Private config that is only available on the server @@ -38,7 +36,7 @@ export default defineNuxtConfig({ ```vue [pages/index.vue] diff --git a/docs/package.json b/docs/package.json index 92388add72c0..285960739ba6 100644 --- a/docs/package.json +++ b/docs/package.json @@ -16,11 +16,11 @@ "@docus/theme": "1.2.2", "@nuxt/typescript-build": "^2.1.0", "fs-extra": "^10.1.0", - "jiti": "^1.15.0", - "pathe": "^0.3.7", + "jiti": "^1.16.0", + "pathe": "^0.3.8", "rimraf": "^3.0.2", "scule": "^0.3.2", - "untyped": "^0.4.7", + "untyped": "^0.5.0", "vue-mq": "^1.0.1", "vue-plausible": "^1.3.2" }, diff --git a/docs/static/_redirects b/docs/static/_redirects index 7dad3bd35f88..ccd1012a4b73 100644 --- a/docs/static/_redirects +++ b/docs/static/_redirects @@ -1,34 +1,66 @@ # Getting started -/getting-started/introduction /getting-started/quick-start 302! -/getting-started/installation /getting-started/quick-start 302! /getting-started/commands /api/commands/add 302! /getting-started/bridge /bridge 302! /getting-started/bridge-composition-api /bridge/bridge-composition-api 302! # Concepts -/concepts/introduction /guide/concepts/introduction 302! +/concepts/introduction /guide/getting-started/introduction 302! /concepts/vuejs-development /guide/concepts/vuejs-development 302! /concepts/rendering /guide/concepts/rendering 302! /concepts/auto-imports /guide/concepts/auto-imports 302! /concepts/server-engine /guide/concepts/server-engine 302! /concepts/typescript /guide/concepts/typescript 302! -/concepts/esm /guide/going-further/esm 302! +/concepts/esm /guide/concepts/esm 302! # Docs -/docs/usage/data-fetching /guide/features/data-fetching 302! -/docs/usage/state /guide/features/state-management 302! -/docs/usage/meta-tags /guide/features/head-management 302! +/docs/usage/data-fetching /guide/getting-started/data-fetching 302! +/docs/usage/state /guide/getting-started/state-management 302! +/docs/usage/meta-tags /guide/getting-started/seo-meta 302! /docs/usage/nuxt-app /guide/going-further/nuxt-app 302! /docs/usage/runtime-config /guide/going-further/runtime-config 302! /docs/usage/cookies /api/composables/use-cookie 302! /docs/usage/ssr /api/composables/use-request-headers 302! /docs/usage/cli /api/commands/add 302! -/docs/usage/error-handling /guide/features/error-handling 302! +/docs/usage/error-handling /guide/getting-started/error-handling 302! /docs/usage/nuxt-link /api/components/nuxt-link 302! -/docs/usage/teleports /guide/features/teleports 302! +/docs/usage/teleports /api/components/teleports 302! /docs/directory-structure/* /guide/directory-structure/:splat 302! -/docs/deployment/* /guide/deployment/:splat 302! -/docs/advanced/testing /guide/going-further/testing 302! +/docs/deployment/* /guide/deploy/:splat 302! +/docs/advanced/testing /guide/getting-started/testing 302! /docs/advanced/nuxt /guide/going-further/internals 302! /docs/advanced/modules /guide/going-further/modules 302! /docs/advanced/kit /guide/going-further/kit 302! /docs/advanced/hooks /guide/going-further/hooks 302! /docs/migration/* /migration/:splat 302! +# https://github.com/nuxt/framework/pull/7047 +/getting-started/quick-start /getting-started/installation 302! +/guide/concepts/introduction /getting-started/introduction 302! +/guide/features/views /getting-started/views 302! +/guide/features/assets /getting-started/assets 302! +/guide/features/head-management /getting-started/seo-meta 302! +/guide/features/data-fetching /getting-started/data-fetching 302! +/guide/features/state-management /getting-started/state-management 302! +/guide/features/error-handling /getting-started/error-handling 302! +/guide/going-further/testing /getting-started/testing 302! +/getting-started/migration /getting-started/upgrade-guide/migration 302 +/getting-started/upgrade-guide/migration /getting-started/upgrade 302! +/getting-started/upgrade-guide/edge-channel /guide/going-further/edge-channel 302! +/guide/features/modules /guide/concepts/modules 302! +/guide/features/server-routes /guide/directory-structure/server 302! +/guide/going-further/esm /guide/concepts/esm 302! +/guide/features/app-config /guide/directory-structure/app.config 302! +/guide/features/runtime-config /guide/going-further/runtime-config 302! +/guide/features/teleports /api/components/teleports 302! + +/guide/deploy/node-server /getting-started/deployment 302! +/guide/deploy/static-hosting /getting-started/deployment 302! +/guide/deploy/presets /getting-started/deployment 302! +/guide/deploy/providers/aws https://nitro.unjs.io/deploy/providers/aws 302! +/guide/deploy/providers/azure https://nitro.unjs.io/deploy/providers/azure 302! +/guide/deploy/providers/cloudflare https://nitro.unjs.io/deploy/providers/cloudflare 302! +/guide/deploy/providers/digitalocean https://nitro.unjs.io/deploy/providers/digitalocean 302! +/guide/deploy/providers/firebase https://nitro.unjs.io/deploy/providers/firebase 302! +/guide/deploy/providers/heroku https://nitro.unjs.io/deploy/providers/heroku 302! +/guide/deploy/providers/layer0 https://nitro.unjs.io/deploy/providers/layer0 302! +/guide/deploy/providers/netlify https://nitro.unjs.io/deploy/providers/netlify 302! +/guide/deploy/providers/render https://nitro.unjs.io/deploy/providers/render 302! +/guide/deploy/providers/stormkit https://nitro.unjs.io/deploy/providers/stormkit 302! +/guide/deploy/providers/vercel https://nitro.unjs.io/deploy/providers/vercel 302! diff --git a/docs/static/img/getting-started/views/app.svg b/docs/static/img/getting-started/views/app.svg new file mode 100644 index 000000000000..9732919e3e2c --- /dev/null +++ b/docs/static/img/getting-started/views/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/getting-started/views/components.svg b/docs/static/img/getting-started/views/components.svg new file mode 100644 index 000000000000..7b14322db1f0 --- /dev/null +++ b/docs/static/img/getting-started/views/components.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/getting-started/views/layouts.svg b/docs/static/img/getting-started/views/layouts.svg new file mode 100644 index 000000000000..afe8f72a66cd --- /dev/null +++ b/docs/static/img/getting-started/views/layouts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/getting-started/views/pages.svg b/docs/static/img/getting-started/views/pages.svg new file mode 100644 index 000000000000..14e5d34fa292 --- /dev/null +++ b/docs/static/img/getting-started/views/pages.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/utils/createTitle.js b/docs/utils/createTitle.js index 76d3430f23f2..9aee444c4fe9 100644 --- a/docs/utils/createTitle.js +++ b/docs/utils/createTitle.js @@ -1,5 +1,5 @@ import { splitByCase, upperFirst } from 'scule' export default (title, link) => { - return title || (link.startsWith('http') && link) || link.split('/').filter(Boolean).map(part => splitByCase(part).map(p => upperFirst(p)).join(' ')).join(' > ').replace('Api', 'API') + return title || (link.startsWith('http') && link) || link.split(/[/#]/).filter(Boolean).map(part => splitByCase(part).map(p => upperFirst(p)).join(' ')).join(' > ').replace('Api', 'API') } diff --git a/docs/yarn.lock b/docs/yarn.lock index cd10257913e7..2116e69f39c3 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -165,10 +165,10 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== -"@babel/compat-data@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" - integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== +"@babel/compat-data@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" + integrity sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg== "@babel/core@^7.15.5", "@babel/core@^7.15.8": version "7.15.8" @@ -191,21 +191,21 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/core@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.13.tgz#9be8c44512751b05094a4d3ab05fc53a47ce00ac" - integrity sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A== +"@babel/core@^7.19.0": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.1.tgz#c8fa615c5e88e272564ace3d42fbc8b17bfeb22b" + integrity sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.13" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helpers" "^7.18.9" - "@babel/parser" "^7.18.13" + "@babel/generator" "^7.19.0" + "@babel/helper-compilation-targets" "^7.19.1" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helpers" "^7.19.0" + "@babel/parser" "^7.19.1" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.18.13" - "@babel/types" "^7.18.13" + "@babel/traverse" "^7.19.1" + "@babel/types" "^7.19.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -221,21 +221,12 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.10.tgz#794f328bfabdcbaf0ebf9bf91b5b57b61fa77a2a" - integrity sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA== - dependencies: - "@babel/types" "^7.18.10" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/generator@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.13.tgz#59550cbb9ae79b8def15587bdfbaa388c4abf212" - integrity sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ== +"@babel/generator@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" + integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== dependencies: - "@babel/types" "^7.18.13" + "@babel/types" "^7.19.0" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -264,14 +255,14 @@ browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" - integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== +"@babel/helper-compilation-targets@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz#7f630911d83b408b76fe584831c98e5395d7a17c" + integrity sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg== dependencies: - "@babel/compat-data" "^7.18.8" + "@babel/compat-data" "^7.19.1" "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.20.2" + browserslist "^4.21.3" semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.4": @@ -329,13 +320,13 @@ "@babel/template" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/helper-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" - integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== dependencies: - "@babel/template" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" "@babel/helper-get-function-arity@^7.15.4": version "7.15.4" @@ -393,19 +384,19 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.6" -"@babel/helper-module-transforms@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" - integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== +"@babel/helper-module-transforms@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" + integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-module-imports" "^7.18.6" "@babel/helper-simple-access" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" "@babel/helper-optimise-call-expression@^7.15.4": version "7.15.4" @@ -517,14 +508,14 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/helpers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" - integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== +"@babel/helpers@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" + integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== dependencies: - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" "@babel/highlight@^7.14.5": version "7.14.5" @@ -549,15 +540,15 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== -"@babel/parser@^7.18.10", "@babel/parser@^7.18.11": +"@babel/parser@^7.18.10": version "7.18.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== -"@babel/parser@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4" - integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg== +"@babel/parser@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.1.tgz#6f6d6c2e621aad19a92544cc217ed13f1aac5b4c" + integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.15.4": version "7.15.4" @@ -1195,10 +1186,10 @@ resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.15.8.tgz#3cb40b81892a702968a3e0bba2bdd1115f034876" integrity sha512-EF2uQLeuwflnPRGetWH2Z400ITOSK7YbkXIKxY91EWSiOJ8xsbupT3sx3sFRwVyQgjsHSILFDzLcSo/rGspLhQ== -"@babel/standalone@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.18.13.tgz#380fd841d95bfd55435282f323136c1ad2469b86" - integrity sha512-5hjvvFkaXyfQri+s4CAZtx6FTKclfTNd2QN2RwgzCVJhnYYgKh4YFBCnNJSxurzvpSKD2NmpCkoWAkMc+j9y+g== +"@babel/standalone@^7.19.0": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.19.1.tgz#7662e7653e019fae8f7c07544946a440e63a3914" + integrity sha512-L64ozsIg/oUuHMiKsZLpnxg1cgvOY1bb62PoTzgm/x/vfvBS+besd41Cg6tc4KvLyubbQVik1o/0HN2BdUDVUQ== "@babel/template@^7.15.4": version "7.15.4" @@ -1209,7 +1200,7 @@ "@babel/parser" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/template@^7.18.10", "@babel/template@^7.18.6": +"@babel/template@^7.18.10": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== @@ -1233,35 +1224,19 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.13.tgz#5ab59ef51a997b3f10c4587d648b9696b6cb1a68" - integrity sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.13" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.13" - "@babel/types" "^7.18.13" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.18.9": - version "7.18.11" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f" - integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ== +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.1.tgz#0fafe100a8c2a603b4718b1d9bf2568d1d193347" + integrity sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.10" + "@babel/generator" "^7.19.0" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.11" - "@babel/types" "^7.18.10" + "@babel/parser" "^7.19.1" + "@babel/types" "^7.19.0" debug "^4.1.0" globals "^11.1.0" @@ -1273,7 +1248,7 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" -"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9": +"@babel/types@^7.18.10", "@babel/types@^7.18.6": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== @@ -1282,10 +1257,10 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" -"@babel/types@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.13.tgz#30aeb9e514f4100f7c1cb6e5ba472b30e48f519a" - integrity sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ== +"@babel/types@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" + integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== dependencies: "@babel/helper-string-parser" "^7.18.10" "@babel/helper-validator-identifier" "^7.18.6" @@ -3544,7 +3519,7 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.16.6, browserslist@^4 node-releases "^2.0.0" picocolors "^1.0.0" -browserslist@^4.20.2: +browserslist@^4.21.3: version "4.21.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== @@ -6786,10 +6761,10 @@ jiti@^1.10.1, jiti@^1.11.0, jiti@^1.12.5, jiti@^1.12.9, jiti@^1.9.1, jiti@^1.9.2 resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.12.9.tgz#2ce45b265cfc8dc91ebd70a5204807cf915291bc" integrity sha512-TdcJywkQtcwLxogc4rSMAi479G2eDPzfW0fLySks7TPhgZZ4s/tM6stnzayIh3gS/db3zExWJyUx4cNWrwAmoQ== -jiti@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.15.0.tgz#cfa7ebfe4a60d77cf3bd4f8630cd99225b638417" - integrity sha512-cClBkETOCVIpPMjX3ULlivuBvmt8l2Xtz+SHrULO06OqdtV0QFR2cuhc4FJnXByjUUX4CY0pl1nph0aFh9D3yA== +jiti@^1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.16.0.tgz#f72065954446ad1866fa8d6bcc3bed3cc1cebdaa" + integrity sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg== joycon@^3.0.1: version "3.0.1" @@ -8391,10 +8366,10 @@ pathe@^0.2.0: resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.2.0.tgz#30fd7bbe0a0d91f0e60bae621f5d19e9e225c339" integrity sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw== -pathe@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.7.tgz#83860c096cb11d9614c17e0d70d91622931676ce" - integrity sha512-yz7GK+kSsS27x727jtXpd5VT4dDfP/JDIQmaowfxyWCnFjOWtE1VIh7i6TzcSfzW0n4+bRQztj1VdKnITNq/MA== +pathe@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.8.tgz#3584f03fda1981a6efe8bc24623d82cbb4219acb" + integrity sha512-c71n61F1skhj/jzZe+fWE9XDoTYjWbUwIKVwFftZ5IOgiX44BVkTkD+/803YDgR50tqeO4eXWxLyVHBLWQAD1g== pbkdf2@^3.0.3: version "3.1.2" @@ -11460,14 +11435,14 @@ untyped@^0.2.5, untyped@^0.2.8, untyped@^0.2.9: resolved "https://registry.yarnpkg.com/untyped/-/untyped-0.2.9.tgz#3e3df96a303dec3e2eda55fcbdc02e2ab468683d" integrity sha512-8d8V+q/y5CGzV+IYnoOCMjrK+NSNp1HKO8iPQ+bV4rBP8knPIme3+j/bpej8IuMnEMxOJZNptXNOXCx7w+VJxQ== -untyped@^0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/untyped/-/untyped-0.4.7.tgz#1c6386eb941935199f2ab57981a0308546243141" - integrity sha512-hBgCv7fnqIRzAagn2cUZxxVmhTE7NcMAgI8CfQelFVacG4O55VrurigpK0G504ph4sQSqVsGEo52O5EKFCnJ9g== +untyped@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/untyped/-/untyped-0.5.0.tgz#0c8be1296d128a3f35e0df229b542f288741a50f" + integrity sha512-2Sre5A1a7G61bjaAKZnSFaVgbJMwwbbYQpJFH69hAYcDfN7kIaktlSphS02XJilz4+/jR1tsJ5MHo1oMoCezxg== dependencies: - "@babel/core" "^7.18.13" - "@babel/standalone" "^7.18.13" - "@babel/types" "^7.18.13" + "@babel/core" "^7.19.0" + "@babel/standalone" "^7.19.0" + "@babel/types" "^7.19.0" scule "^0.3.2" upath@^1.1.1: diff --git a/examples/advanced/config-extends/base/nuxt.config.ts b/examples/advanced/config-extends/base/nuxt.config.ts index b52d458e0ece..4b0e283af265 100644 --- a/examples/advanced/config-extends/base/nuxt.config.ts +++ b/examples/advanced/config-extends/base/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ imports: { dirs: ['utils'] diff --git a/examples/advanced/config-extends/nuxt.config.ts b/examples/advanced/config-extends/nuxt.config.ts index 1e99ce00bcca..b515b8e6d018 100644 --- a/examples/advanced/config-extends/nuxt.config.ts +++ b/examples/advanced/config-extends/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ extends: [ './ui', diff --git a/examples/advanced/config-extends/package.json b/examples/advanced/config-extends/package.json index 65a37af55d4f..cdec1b4b5644 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.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" }, "scripts": { "dev": "nuxi dev", diff --git a/examples/advanced/config-extends/ui/nuxt.config.ts b/examples/advanced/config-extends/ui/nuxt.config.ts index 5fb57ea54c58..fc7b9424c6bd 100644 --- a/examples/advanced/config-extends/ui/nuxt.config.ts +++ b/examples/advanced/config-extends/ui/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ components: [ { path: './components', prefix: 'UI' } diff --git a/examples/advanced/jsx/nuxt.config.ts b/examples/advanced/jsx/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/advanced/jsx/nuxt.config.ts +++ b/examples/advanced/jsx/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/advanced/jsx/package.json b/examples/advanced/jsx/package.json index 8a11beb34f9a..4475cab49442 100644 --- a/examples/advanced/jsx/package.json +++ b/examples/advanced/jsx/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/advanced/module-extend-pages/nuxt.config.ts b/examples/advanced/module-extend-pages/nuxt.config.ts index 0b86f8d08fee..b13e1285b19d 100644 --- a/examples/advanced/module-extend-pages/nuxt.config.ts +++ b/examples/advanced/module-extend-pages/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '~/modules/pages', diff --git a/examples/advanced/module-extend-pages/package.json b/examples/advanced/module-extend-pages/package.json index f66da7ab72e4..e9e69e15696c 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.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/advanced/testing/nuxt.config.ts b/examples/advanced/testing/nuxt.config.ts index 8b0aa104adf2..fc5628ebc36e 100644 --- a/examples/advanced/testing/nuxt.config.ts +++ b/examples/advanced/testing/nuxt.config.ts @@ -1,4 +1,2 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ }) diff --git a/examples/advanced/testing/package.json b/examples/advanced/testing/package.json index d872e9d70e5f..2d48aa5019da 100644 --- a/examples/advanced/testing/package.json +++ b/examples/advanced/testing/package.json @@ -7,6 +7,6 @@ "start": "nuxi preview" }, "devDependencies": { - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/app-config/nuxt.config.ts b/examples/app-config/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/app-config/nuxt.config.ts +++ b/examples/app-config/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/app-config/package.json b/examples/app-config/package.json index 0b8c1b0591a6..482e0638258d 100644 --- a/examples/app-config/package.json +++ b/examples/app-config/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/app/error-handling/nuxt.config.ts b/examples/app/error-handling/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/app/error-handling/nuxt.config.ts +++ b/examples/app/error-handling/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/app/error-handling/package.json b/examples/app/error-handling/package.json index ba72bbed5fac..55420fcb1905 100644 --- a/examples/app/error-handling/package.json +++ b/examples/app/error-handling/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/app/plugins/nuxt.config.ts b/examples/app/plugins/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/app/plugins/nuxt.config.ts +++ b/examples/app/plugins/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/app/plugins/package.json b/examples/app/plugins/package.json index 0098f2f7e4bd..30567084fb34 100644 --- a/examples/app/plugins/package.json +++ b/examples/app/plugins/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/app/teleport/nuxt.config.ts b/examples/app/teleport/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/app/teleport/nuxt.config.ts +++ b/examples/app/teleport/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/app/teleport/package.json b/examples/app/teleport/package.json index 74b40f6eafaf..202745f6e0b9 100644 --- a/examples/app/teleport/package.json +++ b/examples/app/teleport/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/auto-imports/components/nuxt.config.ts b/examples/auto-imports/components/nuxt.config.ts index 0bc8ef827487..340315d42879 100644 --- a/examples/auto-imports/components/nuxt.config.ts +++ b/examples/auto-imports/components/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/auto-imports/components/package.json b/examples/auto-imports/components/package.json index edb526ca0bcb..1088e8181a68 100644 --- a/examples/auto-imports/components/package.json +++ b/examples/auto-imports/components/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/auto-imports/composables/nuxt.config.ts b/examples/auto-imports/composables/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/auto-imports/composables/nuxt.config.ts +++ b/examples/auto-imports/composables/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/auto-imports/composables/package.json b/examples/auto-imports/composables/package.json index 50e7ecb39ec9..bd1513de64ae 100644 --- a/examples/auto-imports/composables/package.json +++ b/examples/auto-imports/composables/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/composables/use-async-data/nuxt.config.ts b/examples/composables/use-async-data/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/composables/use-async-data/nuxt.config.ts +++ b/examples/composables/use-async-data/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/composables/use-async-data/package.json b/examples/composables/use-async-data/package.json index 3bc29103c829..bcd9de43f9ee 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.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/composables/use-cookie/nuxt.config.ts b/examples/composables/use-cookie/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/composables/use-cookie/nuxt.config.ts +++ b/examples/composables/use-cookie/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/composables/use-cookie/package.json b/examples/composables/use-cookie/package.json index f1647579d7f7..8434d2ca4849 100644 --- a/examples/composables/use-cookie/package.json +++ b/examples/composables/use-cookie/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/composables/use-fetch/nuxt.config.ts b/examples/composables/use-fetch/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/composables/use-fetch/nuxt.config.ts +++ b/examples/composables/use-fetch/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/composables/use-fetch/package.json b/examples/composables/use-fetch/package.json index 3e1cf30f89fc..7d1c0f070ea7 100644 --- a/examples/composables/use-fetch/package.json +++ b/examples/composables/use-fetch/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/composables/use-head/app.vue b/examples/composables/use-head/app.vue index 335ffbd8f903..3c19f0731acc 100644 --- a/examples/composables/use-head/app.vue +++ b/examples/composables/use-head/app.vue @@ -12,6 +12,7 @@ Luck number: {{ dynamic }} + diff --git a/examples/composables/use-head/nuxt.config.ts b/examples/composables/use-head/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/composables/use-head/nuxt.config.ts +++ b/examples/composables/use-head/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/composables/use-head/package.json b/examples/composables/use-head/package.json index 1e3802a94c0f..79a0337b09db 100644 --- a/examples/composables/use-head/package.json +++ b/examples/composables/use-head/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/composables/use-state/nuxt.config.ts b/examples/composables/use-state/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/composables/use-state/nuxt.config.ts +++ b/examples/composables/use-state/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/composables/use-state/package.json b/examples/composables/use-state/package.json index fbf37f80498f..31086bb70150 100644 --- a/examples/composables/use-state/package.json +++ b/examples/composables/use-state/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/essentials/hello-world/nuxt.config.ts b/examples/essentials/hello-world/nuxt.config.ts index 8b0aa104adf2..fc5628ebc36e 100644 --- a/examples/essentials/hello-world/nuxt.config.ts +++ b/examples/essentials/hello-world/nuxt.config.ts @@ -1,4 +1,2 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ }) diff --git a/examples/essentials/hello-world/package.json b/examples/essentials/hello-world/package.json index 735d5898828e..6eed2d5392a5 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.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/experimental/reactivity-transform/nuxt.config.ts b/examples/experimental/reactivity-transform/nuxt.config.ts index 4959137de47f..a17b6a70ce70 100644 --- a/examples/experimental/reactivity-transform/nuxt.config.ts +++ b/examples/experimental/reactivity-transform/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/experimental/reactivity-transform/package.json b/examples/experimental/reactivity-transform/package.json index 006243da6f4a..f240ccd6a291 100644 --- a/examples/experimental/reactivity-transform/package.json +++ b/examples/experimental/reactivity-transform/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/experimental/vite-node/nuxt.config.ts b/examples/experimental/vite-node/nuxt.config.ts index d2551556ecc8..5244ad314d31 100644 --- a/examples/experimental/vite-node/nuxt.config.ts +++ b/examples/experimental/vite-node/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/experimental/vite-node/package.json b/examples/experimental/vite-node/package.json index 90b987087554..dd1461afc3be 100644 --- a/examples/experimental/vite-node/package.json +++ b/examples/experimental/vite-node/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/experimental/wasm/nuxt.config.ts b/examples/experimental/wasm/nuxt.config.ts index 0d7edfc69453..fc744fd0dd74 100644 --- a/examples/experimental/wasm/nuxt.config.ts +++ b/examples/experimental/wasm/nuxt.config.ts @@ -1,8 +1,6 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ nitro: { - experiments: { + experimental: { wasm: true } }, diff --git a/examples/experimental/wasm/package.json b/examples/experimental/wasm/package.json index 5e10dd86c37a..ea84e92d4e43 100644 --- a/examples/experimental/wasm/package.json +++ b/examples/experimental/wasm/package.json @@ -3,7 +3,7 @@ "private": true, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" }, "scripts": { "dev": "nuxi dev", diff --git a/examples/other/locale/nuxt.config.ts b/examples/other/locale/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/other/locale/nuxt.config.ts +++ b/examples/other/locale/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/other/locale/package.json b/examples/other/locale/package.json index 9762522dc47c..d071359ad6f8 100644 --- a/examples/other/locale/package.json +++ b/examples/other/locale/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/routing/layouts/nuxt.config.ts b/examples/routing/layouts/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/routing/layouts/nuxt.config.ts +++ b/examples/routing/layouts/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/routing/layouts/package.json b/examples/routing/layouts/package.json index 0835c83cffde..b562c056bf44 100644 --- a/examples/routing/layouts/package.json +++ b/examples/routing/layouts/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/routing/layouts/pages/dynamic.vue b/examples/routing/layouts/pages/dynamic.vue index ba16145855b5..f07ea238b373 100644 --- a/examples/routing/layouts/pages/dynamic.vue +++ b/examples/routing/layouts/pages/dynamic.vue @@ -5,7 +5,7 @@ Default slot
- diff --git a/examples/routing/middleware/nuxt.config.ts b/examples/routing/middleware/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/routing/middleware/nuxt.config.ts +++ b/examples/routing/middleware/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/routing/middleware/package.json b/examples/routing/middleware/package.json index ad3e9ac10649..4656b94fe4c1 100644 --- a/examples/routing/middleware/package.json +++ b/examples/routing/middleware/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/routing/nuxt-link/nuxt.config.ts b/examples/routing/nuxt-link/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/routing/nuxt-link/nuxt.config.ts +++ b/examples/routing/nuxt-link/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/routing/nuxt-link/package.json b/examples/routing/nuxt-link/package.json index 90d5f0cdbaf5..c87d83b0d28c 100644 --- a/examples/routing/nuxt-link/package.json +++ b/examples/routing/nuxt-link/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/routing/pages/nuxt.config.ts b/examples/routing/pages/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/routing/pages/nuxt.config.ts +++ b/examples/routing/pages/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/routing/pages/package.json b/examples/routing/pages/package.json index 97ea8abd3068..133529f8325d 100644 --- a/examples/routing/pages/package.json +++ b/examples/routing/pages/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/routing/universal-router/nuxt.config.ts b/examples/routing/universal-router/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/routing/universal-router/nuxt.config.ts +++ b/examples/routing/universal-router/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/routing/universal-router/package.json b/examples/routing/universal-router/package.json index 1d54e72abd2b..6c4db8ca421f 100644 --- a/examples/routing/universal-router/package.json +++ b/examples/routing/universal-router/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/examples/server/routes/nuxt.config.ts b/examples/server/routes/nuxt.config.ts index 36c7f84d69bb..9f9029e2b196 100644 --- a/examples/server/routes/nuxt.config.ts +++ b/examples/server/routes/nuxt.config.ts @@ -1,5 +1,3 @@ -import { defineNuxtConfig } from 'nuxt' - export default defineNuxtConfig({ modules: [ '@nuxt/ui' diff --git a/examples/server/routes/package.json b/examples/server/routes/package.json index 99493611ded9..bc014194d36f 100644 --- a/examples/server/routes/package.json +++ b/examples/server/routes/package.json @@ -8,6 +8,6 @@ }, "devDependencies": { "@nuxt/ui": "^0.3.2", - "nuxt": "^3.0.0-rc.9" + "nuxt": "^3.0.0-rc.10" } } diff --git a/lerna.json b/lerna.json index f6d14c764f7f..607c9991ed45 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.0.0-rc.9", + "version": "3.0.0-rc.11", "npmClient": "yarn", "useWorkspaces": true, "conventionalCommits": true, diff --git a/package.json b/package.json index 2eb5d34b2374..534a2ab046c6 100644 --- a/package.json +++ b/package.json @@ -38,38 +38,48 @@ "@nuxt/kit": "link:./packages/kit", "@nuxt/schema": "link:./packages/schema", "@nuxt/test-utils": "link:./packages/test-utils", - "@nuxt/vite": "link:./packages/vite", - "@nuxt/webpack": "link:./packages/webpack", + "@nuxt/vite-builder": "link:./packages/vite", + "@nuxt/webpack-builder": "link:./packages/webpack", "nuxi": "link:./packages/nuxi", "nuxt": "link:./packages/nuxt", "nuxt3": "link:./packages/nuxt", - "vite": "~3.1.0", - "unbuild": "^0.8.10" + "vite": "~3.1.3", + "unbuild": "^0.8.11" }, "devDependencies": { + "@actions/core": "^1.9.1", + "@nuxt/test-utils": "link:./packages/test-utils", "@nuxtjs/eslint-config-typescript": "^11.0.0", - "@types/node": "^16.11.58", + "@types/crawler": "^1.2.2", + "@types/node": "^16.11.60", "@types/rimraf": "^3", - "@unocss/reset": "^0.45.21", + "@types/semver": "^7", + "@unocss/reset": "^0.45.23", "case-police": "^0.5.10", - "changelogen": "^0.3.0", - "eslint": "^8.23.1", + "changelogen": "^0.3.2", + "crawler": "^1.3.0", + "eslint": "^8.24.0", "eslint-plugin-jsdoc": "^39.3.6", "execa": "^6.1.0", "expect-type": "^0.14.2", "globby": "^13.1.2", - "jiti": "^1.15.0", - "lerna": "^5.5.1", + "jiti": "^1.16.0", + "lerna": "^5.5.2", "markdownlint-cli": "^0.32.2", - "pathe": "^0.3.7", + "ohmyfetch": "^0.4.19", + "pathe": "^0.3.8", "rimraf": "^3.0.2", + "semver": "^7.3.7", + "std-env": "^3.2.1", "typescript": "^4.8.3", - "unbuild": "^0.8.10", + "ufo": "^0.8.5", + "unbuild": "^0.8.11", + "vite": "^3.1.4", "vitest": "~0.19.1", "vue-tsc": "^0.39.5" }, "packageManager": "yarn@3.2.3", "engines": { - "node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0" + "node": "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0" } } diff --git a/packages/kit/package.json b/packages/kit/package.json index c17b2e65dac9..cb1ded036676 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -1,6 +1,6 @@ { "name": "@nuxt/kit", - "version": "3.0.0-rc.9", + "version": "3.0.0-rc.11", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -13,24 +13,24 @@ "prepack": "unbuild" }, "dependencies": { - "@nuxt/schema": "3.0.0-rc.9", - "c12": "^0.2.11", + "@nuxt/schema": "3.0.0-rc.11", + "c12": "^0.2.13", "consola": "^2.15.3", "defu": "^6.1.0", "globby": "^13.1.2", "hash-sum": "^2.0.0", "ignore": "^5.2.0", - "jiti": "^1.15.0", + "jiti": "^1.16.0", "knitwork": "^0.1.2", "lodash.template": "^4.5.0", - "mlly": "^0.5.14", - "pathe": "^0.3.7", + "mlly": "^0.5.16", + "pathe": "^0.3.8", "pkg-types": "^0.3.5", "scule": "^0.3.2", "semver": "^7.3.7", "unctx": "^2.0.2", "unimport": "^0.6.7", - "untyped": "^0.4.7" + "untyped": "^0.5.0" }, "devDependencies": { "@types/lodash.template": "^4", @@ -38,6 +38,6 @@ "unbuild": "latest" }, "engines": { - "node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0" + "node": "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0" } } diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts index 7fb609a84241..e5f991dee8f6 100644 --- a/packages/kit/src/index.ts +++ b/packages/kit/src/index.ts @@ -18,7 +18,7 @@ export * from './layout' export * from './pages' export * from './plugin' export * from './resolve' -export * from './server' +export * from './nitro' export * from './template' export * from './logger' diff --git a/packages/kit/src/loader/config.ts b/packages/kit/src/loader/config.ts index ff7250a712ae..0f893f1bfd3f 100644 --- a/packages/kit/src/loader/config.ts +++ b/packages/kit/src/loader/config.ts @@ -7,6 +7,7 @@ import { NuxtConfigSchema } from '@nuxt/schema' export interface LoadNuxtConfigOptions extends LoadConfigOptions {} export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise { + (globalThis as any).defineNuxtConfig = (c: any) => c const result = await loadConfig({ name: 'nuxt', configFile: 'nuxt.config', @@ -16,6 +17,7 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise (definition: Mo } // Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema - function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) { + async function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) { const configKey = definition.meta!.configKey || definition.meta!.name! const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults let _options = defu(inlineOptions, nuxt.options[configKey as keyof NuxtOptions], _defaults) as OptionsT if (definition.schema) { - _options = applyDefaults(definition.schema, _options) as OptionsT + _options = await applyDefaults(definition.schema, _options) as OptionsT } return Promise.resolve(_options) } diff --git a/packages/kit/src/server.ts b/packages/kit/src/nitro.ts similarity index 66% rename from packages/kit/src/server.ts rename to packages/kit/src/nitro.ts index ba2a031f1187..a4fe041d0160 100644 --- a/packages/kit/src/server.ts +++ b/packages/kit/src/nitro.ts @@ -1,5 +1,5 @@ import type { Middleware } from 'h3' -import type { NitroEventHandler, NitroDevEventHandler } from 'nitropack' +import type { NitroEventHandler, NitroDevEventHandler, Nitro } from 'nitropack' import { useNuxt } from './context' export interface LegacyServerMiddleware { @@ -46,3 +46,26 @@ export function addServerHandler (handler: NitroEventHandler) { export function addDevServerHandler (handler: NitroDevEventHandler) { useNuxt().options.devServerHandlers.push(handler) } + +/** + * Access to the Nitro instance + * + * **Note:** You can call `useNitro()` only after `ready` hook. + * + * **Note:** Changes to the Nitro instance configuration are not applied. + * + * @example + * + * ```ts + * nuxt.hook('ready', () => { + * console.log(useNitro()) + * }) + * ``` + */ +export function useNitro (): Nitro { + const nuxt = useNuxt() + if (!(nuxt as any)._nitro) { + throw new Error('Nitro is not initialized yet. You can call `useNitro()` only after `ready` hook.') + } + return (nuxt as any)._nitro +} diff --git a/packages/nuxi/package.json b/packages/nuxi/package.json index d47852f9a44f..f6ce3d9b134a 100644 --- a/packages/nuxi/package.json +++ b/packages/nuxi/package.json @@ -1,6 +1,6 @@ { "name": "nuxi", - "version": "3.0.0-rc.9", + "version": "3.0.0-rc.11", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -18,13 +18,13 @@ "prepack": "unbuild" }, "devDependencies": { - "@nuxt/kit": "3.0.0-rc.9", - "@nuxt/schema": "3.0.0-rc.9", + "@nuxt/kit": "3.0.0-rc.11", + "@nuxt/schema": "3.0.0-rc.11", "@types/clear": "^0", "@types/flat": "^5.0.2", "@types/mri": "^1.1.1", "@types/semver": "^7", - "c12": "^0.2.11", + "c12": "^0.2.13", "chokidar": "^3.5.3", "clear": "^0.1.0", "clipboardy": "^3.0.0", @@ -34,12 +34,12 @@ "destr": "^1.1.1", "execa": "^6.1.0", "flat": "^5.0.2", - "giget": "^0.1.5", - "jiti": "^1.15.0", - "listhen": "^0.2.15", - "mlly": "^0.5.14", + "giget": "^0.1.7", + "jiti": "^1.16.0", + "listhen": "^0.3.4", + "mlly": "^0.5.16", "mri": "^1.2.0", - "pathe": "^0.3.7", + "pathe": "^0.3.8", "perfect-debounce": "^0.1.3", "pkg-types": "^0.3.5", "scule": "^0.3.2", @@ -50,6 +50,6 @@ "fsevents": "~2.3.2" }, "engines": { - "node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0" + "node": "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0" } } diff --git a/packages/nuxi/src/commands/build.ts b/packages/nuxi/src/commands/build.ts index 3a410ded4b34..da19795a5fc5 100644 --- a/packages/nuxi/src/commands/build.ts +++ b/packages/nuxi/src/commands/build.ts @@ -1,4 +1,4 @@ -import { resolve } from 'pathe' +import { relative, resolve } from 'pathe' import consola from 'consola' import { writeTypes } from '../utils/prepare' import { loadKit } from '../utils/kit' @@ -10,7 +10,7 @@ import { defineNuxtCommand } from './index' export default defineNuxtCommand({ meta: { name: 'build', - usage: 'npx nuxi build [--prerender] [rootDir]', + usage: 'npx nuxi build [--prerender] [--dotenv] [rootDir]', description: 'Build nuxt for production deployment' }, async invoke (args) { @@ -19,15 +19,22 @@ export default defineNuxtCommand({ const rootDir = resolve(args._[0] || '.') showVersions(rootDir) - const { loadNuxt, buildNuxt } = await loadKit(rootDir) + const { loadNuxt, buildNuxt, useNitro } = await loadKit(rootDir) const nuxt = await loadNuxt({ rootDir, + dotenv: { + cwd: rootDir, + fileName: args.dotenv + }, overrides: { _generate: args.prerender } }) + // Use ? for backward compatibility for Nuxt <= RC.10 + const nitro = useNitro?.() + await clearDir(nuxt.options.buildDir) await writeTypes(nuxt) @@ -38,5 +45,12 @@ export default defineNuxtCommand({ }) await buildNuxt(nuxt) + + if (args.prerender) { + // TODO: revisit later if/when nuxt build --prerender will output hybrid + const dir = nitro?.options.output.publicDir + const publicDir = dir ? relative(process.cwd(), dir) : '.output/public' + consola.success(`You can now deploy \`${publicDir}\` to any static hosting!`) + } } }) diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index bd01df9b77dd..54ed2a3f21e0 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -18,7 +18,7 @@ import { defineNuxtCommand } from './index' export default defineNuxtCommand({ meta: { name: 'dev', - usage: 'npx nuxi dev [rootDir] [--clipboard] [--open, -o] [--port, -p] [--host, -h] [--https] [--ssl-cert] [--ssl-key]', + usage: 'npx nuxi dev [rootDir] [--dotenv] [--clipboard] [--open, -o] [--port, -p] [--host, -h] [--https] [--ssl-cert] [--ssl-key]', description: 'Run nuxt development server' }, async invoke (args) { @@ -40,7 +40,7 @@ export default defineNuxtCommand({ const rootDir = resolve(args._[0] || '.') showVersions(rootDir) - await setupDotenv({ cwd: rootDir }) + await setupDotenv({ cwd: rootDir, fileName: args.dotenv }) const listener = await listen(serverHandler, { showURL: false, @@ -48,8 +48,7 @@ export default defineNuxtCommand({ open: args.open || args.o, port: args.port || args.p || process.env.NUXT_PORT, hostname: args.host || args.h || process.env.NUXT_HOST, - https: Boolean(args.https), - certificate: (args['ssl-cert'] && args['ssl-key']) && { + https: args.https && { cert: args['ssl-cert'], key: args['ssl-key'] } @@ -92,9 +91,10 @@ export default defineNuxtCommand({ await currentNuxt.hooks.callHook('listen', listener.server, listener) const address = listener.server.address() as AddressInfo + currentNuxt.options.server.url = listener.url currentNuxt.options.server.port = address.port currentNuxt.options.server.host = address.address - currentNuxt.options.server.https = Boolean(args.https) + currentNuxt.options.server.https = listener.https await Promise.all([ writeTypes(currentNuxt).catch(console.error), diff --git a/packages/nuxi/src/commands/generate.ts b/packages/nuxi/src/commands/generate.ts index 7e402665c0f8..231103cd3cb1 100644 --- a/packages/nuxi/src/commands/generate.ts +++ b/packages/nuxi/src/commands/generate.ts @@ -1,4 +1,3 @@ -import consola from 'consola' import buildCommand from './build' import { defineNuxtCommand } from './index' @@ -11,6 +10,5 @@ export default defineNuxtCommand({ async invoke (args) { args.prerender = true await buildCommand.invoke(args) - consola.success('You can now deploy `.output/public` to any static hosting!') } }) diff --git a/packages/nuxi/src/commands/info.ts b/packages/nuxi/src/commands/info.ts index 8dac49d71b00..e613135355f0 100644 --- a/packages/nuxi/src/commands/info.ts +++ b/packages/nuxi/src/commands/info.ts @@ -119,7 +119,10 @@ function normalizeConfigModule (module: NuxtModule | string | null | undefined, function getNuxtConfig (rootDir: string) { try { - return jiti(rootDir, { interopDefault: true, esmResolve: true })('./nuxt.config') + (globalThis as any).defineNuxtConfig = (c: any) => c + const result = jiti(rootDir, { interopDefault: true, esmResolve: true })('./nuxt.config') + delete (globalThis as any).defineNuxtConfig + return result } catch (err) { // TODO: Show error as warning if it is not 404 return {} diff --git a/packages/nuxi/src/commands/preview.ts b/packages/nuxi/src/commands/preview.ts index 0fb07832a019..028367c46547 100644 --- a/packages/nuxi/src/commands/preview.ts +++ b/packages/nuxi/src/commands/preview.ts @@ -10,7 +10,7 @@ import { defineNuxtCommand } from './index' export default defineNuxtCommand({ meta: { name: 'preview', - usage: 'npx nuxi preview|start [rootDir]', + usage: 'npx nuxi preview|start [--dotenv] [rootDir]', description: 'Launches nitro server for local testing after `nuxi build`.' }, async invoke (args) { @@ -35,9 +35,10 @@ export default defineNuxtCommand({ process.exit(1) } - if (existsSync(resolve(rootDir, '.env'))) { + const envExists = args.dotenv ? existsSync(resolve(rootDir, args.dotenv)) : existsSync(rootDir) + if (envExists) { consola.info('Loading `.env`. This will not be loaded when running the server in production.') - await setupDotenv({ cwd: rootDir }) + await setupDotenv({ cwd: rootDir, fileName: args.dotenv }) } consola.info('Starting preview command:', nitroJSON.commands.preview) diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts index 533e33eefe0f..93a542838f18 100644 --- a/packages/nuxi/src/utils/prepare.ts +++ b/packages/nuxi/src/utils/prepare.ts @@ -27,7 +27,8 @@ export const writeTypes = async (nuxt: Nuxt) => { include: [ './nuxt.d.ts', join(relative(nuxt.options.buildDir, nuxt.options.rootDir), '**/*'), - ...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [] + ...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [], + ...nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : [] ] }) diff --git a/packages/nuxt/config.cjs b/packages/nuxt/config.cjs new file mode 100644 index 000000000000..cfdf3f8aa98a --- /dev/null +++ b/packages/nuxt/config.cjs @@ -0,0 +1,7 @@ +function defineNuxtConfig (config) { + return config +} + +module.exports = { + defineNuxtConfig +} diff --git a/packages/nuxt/config.d.ts b/packages/nuxt/config.d.ts new file mode 100644 index 000000000000..a1dd455ddf43 --- /dev/null +++ b/packages/nuxt/config.d.ts @@ -0,0 +1,4 @@ +import { NuxtConfig } from '@nuxt/schema' +export { NuxtConfig } from '@nuxt/schema' + +export declare function defineNuxtConfig(config: NuxtConfig): NuxtConfig diff --git a/packages/nuxt/config.mjs b/packages/nuxt/config.mjs new file mode 100644 index 000000000000..a063cde6ed7b --- /dev/null +++ b/packages/nuxt/config.mjs @@ -0,0 +1,5 @@ +function defineNuxtConfig (config) { + return config +} + +export { defineNuxtConfig } diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 2f8eecc6f4e4..2fb8eb6579fe 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "nuxt", - "version": "3.0.0-rc.9", + "version": "3.0.0-rc.11", "repository": "nuxt/framework", "license": "MIT", "type": "module", @@ -12,6 +12,11 @@ }, "exports": { ".": "./dist/index.mjs", + "./config": { + "import": "./config.mjs", + "require": "./config.cjs", + "types": "./config.d.ts" + }, "./app": "./dist/app/index.mjs", "./package.json": "./package.json" }, @@ -24,21 +29,22 @@ "app.d.ts", "bin", "types.d.ts", - "dist" + "dist", + "config.*" ], "scripts": { "prepack": "unbuild" }, "dependencies": { "@nuxt/devalue": "^2.0.0", - "@nuxt/kit": "3.0.0-rc.9", - "@nuxt/schema": "3.0.0-rc.9", + "@nuxt/kit": "3.0.0-rc.11", + "@nuxt/schema": "3.0.0-rc.11", "@nuxt/telemetry": "^2.1.5", - "@nuxt/ui-templates": "^0.3.3", - "@nuxt/vite-builder": "3.0.0-rc.9", + "@nuxt/ui-templates": "^0.4.0", + "@nuxt/vite-builder": "3.0.0-rc.11", "@vue/reactivity": "^3.2.39", "@vue/shared": "^3.2.39", - "@vueuse/head": "^0.7.10", + "@vueuse/head": "^0.7.12", "chokidar": "^3.5.3", "cookie-es": "^0.5.0", "defu": "^6.1.0", @@ -50,24 +56,24 @@ "hash-sum": "^2.0.0", "hookable": "^5.3.0", "knitwork": "^0.1.2", - "magic-string": "^0.26.3", - "mlly": "^0.5.14", - "nitropack": "^0.5.1", - "nuxi": "3.0.0-rc.9", + "magic-string": "^0.26.4", + "mlly": "^0.5.16", + "nitropack": "^0.5.4", + "nuxi": "3.0.0-rc.11", "ohash": "^0.1.5", - "ohmyfetch": "^0.4.18", - "pathe": "^0.3.7", + "ohmyfetch": "^0.4.19", + "pathe": "^0.3.8", "perfect-debounce": "^0.1.3", "scule": "^0.3.2", - "strip-literal": "^0.4.0", + "strip-literal": "^0.4.2", "ufo": "^0.8.5", "unctx": "^2.0.2", "unenv": "^0.6.2", "unimport": "^0.6.7", "unplugin": "^0.9.2", - "untyped": "^0.4.7", + "untyped": "^0.5.0", "vue": "^3.2.39", - "vue-bundle-renderer": "^0.4.2", + "vue-bundle-renderer": "^0.4.3", "vue-devtools-stub": "^0.1.0", "vue-router": "^4.1.5" }, @@ -78,6 +84,6 @@ "vue-meta": "next" }, "engines": { - "node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0" + "node": "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0" } } diff --git a/packages/nuxt/src/app/components/client-only.mjs b/packages/nuxt/src/app/components/client-only.mjs index 3e0cf41bdd63..e6530f742988 100644 --- a/packages/nuxt/src/app/components/client-only.mjs +++ b/packages/nuxt/src/app/components/client-only.mjs @@ -1,4 +1,4 @@ -import { ref, onMounted, defineComponent, createElementBlock, h, Fragment } from 'vue' +import { ref, onMounted, defineComponent, createElementBlock, h, createElementVNode } from 'vue' export default defineComponent({ name: 'ClientOnly', @@ -30,9 +30,14 @@ export function createClientOnly (component) { if (clone.render) { // override the component render (non script setup component) clone.render = (ctx, ...args) => { - return ctx.mounted$ - ? h(Fragment, ctx.$attrs ?? ctx._.attrs, component.render(ctx, ...args)) - : h('div', ctx.$attrs ?? ctx._.attrs) + if (ctx.mounted$) { + const res = component.render(ctx, ...args) + return (res.children === null || typeof res.children === 'string') + ? createElementVNode(res.type, res.props, res.children, res.patchFlag, res.dynamicProps, res.shapeFlag) + : h(res) + } else { + return h('div', ctx.$attrs ?? ctx._.attrs) + } } } else if (clone.template) { // handle runtime-compiler template @@ -51,10 +56,14 @@ export function createClientOnly (component) { return typeof setupState !== 'function' ? { ...setupState, mounted$ } : (...args) => { - return mounted$.value - // use Fragment to avoid oldChildren is null issue - ? h(Fragment, ctx.attrs, setupState(...args)) - : h('div', ctx.attrs) + if (mounted$.value) { + const res = setupState(...args) + return (res.children === null || typeof res.children === 'string') + ? createElementVNode(res.type, res.props, res.children, res.patchFlag, res.dynamicProps, res.shapeFlag) + : h(res) + } else { + return h('div', ctx.attrs) + } } }) } diff --git a/packages/nuxt/src/app/components/layout.ts b/packages/nuxt/src/app/components/layout.ts index c1ccc6a60720..bf6333d3d024 100644 --- a/packages/nuxt/src/app/components/layout.ts +++ b/packages/nuxt/src/app/components/layout.ts @@ -1,4 +1,4 @@ -import { defineComponent, isRef, nextTick, onMounted, Ref, Transition, VNode } from 'vue' +import { defineComponent, unref, nextTick, onMounted, Ref, Transition, VNode } from 'vue' import { _wrapIf } from './utils' import { useRoute } from '#app' // @ts-ignore @@ -21,7 +21,7 @@ export default defineComponent({ if (process.dev && process.client) { onMounted(() => { nextTick(() => { - if (_layout && ['#comment', '#text'].includes(vnode?.el?.nodeName)) { + if (_layout && _layout in layouts && ['#comment', '#text'].includes(vnode?.el?.nodeName)) { console.warn(`[nuxt] \`${_layout}\` layout does not have a single root node and will cause errors when navigating between routes.`) } }) @@ -29,7 +29,7 @@ export default defineComponent({ } return () => { - const layout = (isRef(props.name) ? props.name.value : props.name) ?? route.meta.layout as string ?? 'default' + const layout = unref(props.name) ?? route.meta.layout as string ?? 'default' const hasLayout = layout && layout in layouts if (process.dev && layout && !hasLayout && layout !== 'default') { diff --git a/packages/nuxt/src/app/components/nuxt-link.ts b/packages/nuxt/src/app/components/nuxt-link.ts index b6b8c2ed5778..baab6d0b9cb0 100644 --- a/packages/nuxt/src/app/components/nuxt-link.ts +++ b/packages/nuxt/src/app/components/nuxt-link.ts @@ -1,8 +1,9 @@ -import { defineComponent, h, resolveComponent, PropType, computed, DefineComponent, ComputedRef } from 'vue' -import { RouteLocationRaw } from 'vue-router' +import { defineComponent, h, ref, resolveComponent, PropType, computed, DefineComponent, ComputedRef, onMounted, onBeforeUnmount } from 'vue' +import { RouteLocationRaw, Router } from 'vue-router' import { hasProtocol } from 'ufo' -import { navigateTo, useRouter } from '#app' +import { navigateTo, useRouter } from '../composables/router' +import { useNuxtApp } from '../nuxt' const firstNonUndefined = (...args: (T | undefined)[]) => args.find(arg => arg !== undefined) @@ -13,6 +14,7 @@ export type NuxtLinkOptions = { externalRelAttribute?: string | null activeClass?: string exactActiveClass?: string + prefetchedClass?: string } export type NuxtLinkProps = { @@ -28,13 +30,33 @@ export type NuxtLinkProps = { rel?: string | null noRel?: boolean + prefetch?: boolean + noPrefetch?: boolean + // Styling activeClass?: string exactActiveClass?: string // Vue Router's `` additional props ariaCurrentValue?: string -}; +} + +// Polyfills for Safari support +// https://caniuse.com/requestidlecallback +const requestIdleCallback: Window['requestIdleCallback'] = process.server + ? undefined as any + : (globalThis.requestIdleCallback || ((cb) => { + const start = Date.now() + const idleDeadline = { + didTimeout: false, + timeRemaining: () => Math.max(0, 50 - (Date.now() - start)) + } + return setTimeout(() => { cb(idleDeadline) }, 1) + })) + +const cancelIdleCallback: Window['cancelIdleCallback'] = process.server + ? null as any + : (globalThis.cancelIdleCallback || ((id) => { clearTimeout(id) })) export function defineNuxtLink (options: NuxtLinkOptions) { const componentName = options.componentName || 'NuxtLink' @@ -77,6 +99,18 @@ export function defineNuxtLink (options: NuxtLinkOptions) { required: false }, + // Prefetching + prefetch: { + type: Boolean as PropType, + default: undefined, + required: false + }, + noPrefetch: { + type: Boolean as PropType, + default: undefined, + required: false + }, + // Styling activeClass: { type: String as PropType, @@ -88,6 +122,11 @@ export function defineNuxtLink (options: NuxtLinkOptions) { default: undefined, required: false }, + prefetchedClass: { + type: String as PropType, + default: undefined, + required: false + }, // Vue Router's `` additional props replace: { @@ -145,13 +184,49 @@ export function defineNuxtLink (options: NuxtLinkOptions) { return to.value === '' || hasProtocol(to.value, true) }) + // Prefetching + const prefetched = ref(false) + const el = process.server ? undefined : ref(null) + if (process.client) { + checkPropConflicts(props, 'prefetch', 'noPrefetch') + const shouldPrefetch = props.prefetch !== false && props.noPrefetch !== true && typeof to.value === 'string' && !isSlowConnection() + if (shouldPrefetch) { + const nuxtApp = useNuxtApp() + const observer = useObserver() + let idleId: number + let unobserve: Function | null = null + onMounted(() => { + idleId = requestIdleCallback(() => { + if (el?.value?.tagName) { + unobserve = observer!.observe(el.value, async () => { + unobserve?.() + unobserve = null + await Promise.all([ + nuxtApp.hooks.callHook('link:prefetch', to.value as string).catch(() => {}), + preloadRouteComponents(to.value as string, router).catch(() => {}) + ]) + prefetched.value = true + }) + } + }) + }) + onBeforeUnmount(() => { + if (idleId) { cancelIdleCallback(idleId) } + unobserve?.() + unobserve = null + }) + } + } + return () => { if (!isExternal.value) { // Internal link return h( resolveComponent('RouterLink'), { + ref: process.server ? undefined : (ref: any) => { el!.value = ref?.$el }, to: to.value, + ...((prefetched.value && !props.custom) ? { class: props.prefetchedClass || options.prefetchedClass } : {}), activeClass: props.activeClass || options.activeClass, exactActiveClass: props.exactActiveClass || options.exactActiveClass, replace: props.replace, @@ -201,3 +276,74 @@ export function defineNuxtLink (options: NuxtLinkOptions) { } export default defineNuxtLink({ componentName: 'NuxtLink' }) + +// --- Prefetching utils --- + +function useObserver () { + if (process.server) { return } + + const nuxtApp = useNuxtApp() + if (nuxtApp._observer) { + return nuxtApp._observer + } + + let observer: IntersectionObserver | null = null + type CallbackFn = () => void + const callbacks = new Map() + + const observe = (element: Element, callback: CallbackFn) => { + if (!observer) { + observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + const callback = callbacks.get(entry.target) + const isVisible = entry.isIntersecting || entry.intersectionRatio > 0 + if (isVisible && callback) { callback() } + } + }) + } + callbacks.set(element, callback) + observer.observe(element) + return () => { + callbacks.delete(element) + observer!.unobserve(element) + if (callbacks.size === 0) { + observer!.disconnect() + observer = null + } + } + } + + const _observer = nuxtApp._observer = { + observe + } + + return _observer +} + +function isSlowConnection () { + if (process.server) { return } + + // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection + const cn = (navigator as any).connection as { saveData: boolean, effectiveType: string } | null + if (cn && (cn.saveData || /2g/.test(cn.effectiveType))) { return true } + return false +} + +async function preloadRouteComponents (to: string, router: Router & { _nuxtLinkPreloaded?: Set } = useRouter()) { + if (process.server) { return } + + if (!router._nuxtLinkPreloaded) { router._nuxtLinkPreloaded = new Set() } + if (router._nuxtLinkPreloaded.has(to)) { return } + router._nuxtLinkPreloaded.add(to) + + const components = router.resolve(to).matched + .map(component => component.components?.default) + .filter(component => typeof component === 'function') + + const promises: Promise[] = [] + for (const component of components) { + const promise = Promise.resolve((component as Function)()).catch(() => {}) + promises.push(promise) + } + await Promise.all(promises) +} diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 1765e35753a3..51a338619e39 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -1,6 +1,6 @@ import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref } from 'vue' import type { Ref, WatchSource } from 'vue' -import { NuxtApp, useNuxtApp } from '#app' +import { NuxtApp, useNuxtApp } from '../nuxt' export type _Transform = (input: Input) => Output diff --git a/packages/nuxt/src/app/composables/cookie.ts b/packages/nuxt/src/app/composables/cookie.ts index bbedc9e63641..59e221693080 100644 --- a/packages/nuxt/src/app/composables/cookie.ts +++ b/packages/nuxt/src/app/composables/cookie.ts @@ -4,8 +4,8 @@ import { appendHeader } from 'h3' import type { CompatibilityEvent } from 'h3' import destr from 'destr' import { isEqual } from 'ohash' +import { useNuxtApp } from '../nuxt' import { useRequestEvent } from './ssr' -import { useNuxtApp } from '#app' type _CookieOptions = Omit diff --git a/packages/nuxt/src/app/composables/error.ts b/packages/nuxt/src/app/composables/error.ts index ead4df01e62f..8da328792448 100644 --- a/packages/nuxt/src/app/composables/error.ts +++ b/packages/nuxt/src/app/composables/error.ts @@ -1,6 +1,6 @@ import { createError as _createError, H3Error } from 'h3' import { toRef } from 'vue' -import { useNuxtApp } from '#app' +import { useNuxtApp } from '../nuxt' export const useError = () => toRef(useNuxtApp().payload, 'error') diff --git a/packages/nuxt/src/app/composables/fetch.ts b/packages/nuxt/src/app/composables/fetch.ts index f1edcdaeef79..9b2b0294d109 100644 --- a/packages/nuxt/src/app/composables/fetch.ts +++ b/packages/nuxt/src/app/composables/fetch.ts @@ -1,6 +1,6 @@ import type { FetchError, FetchOptions } from 'ohmyfetch' import type { TypedInternalResponse, NitroFetchRequest } from 'nitropack' -import { computed, isRef, Ref } from 'vue' +import { computed, unref, Ref } from 'vue' import type { AsyncDataOptions, _Transform, KeyOfRes, AsyncData, PickFrom } from './asyncData' import { useAsyncData } from './asyncData' @@ -52,7 +52,7 @@ export function useFetch< if (typeof r === 'function') { r = r() } - return (isRef(r) ? r.value : r) + return unref(r) }) const { @@ -63,6 +63,7 @@ export function useFetch< pick, watch, initialCache, + immediate, ...fetchOptions } = opts @@ -78,6 +79,7 @@ export function useFetch< transform, pick, initialCache, + immediate, watch: [ _request, ...(watch || []) diff --git a/packages/nuxt/src/app/composables/hydrate.ts b/packages/nuxt/src/app/composables/hydrate.ts index e3b2d894a5ad..873c472d255d 100644 --- a/packages/nuxt/src/app/composables/hydrate.ts +++ b/packages/nuxt/src/app/composables/hydrate.ts @@ -1,4 +1,4 @@ -import { useNuxtApp } from '#app' +import { useNuxtApp } from '../nuxt' /** * Allows full control of the hydration cycle to set and receive data from the server. diff --git a/packages/nuxt/src/app/composables/index.ts b/packages/nuxt/src/app/composables/index.ts index d3af73707338..98fc038d67b0 100644 --- a/packages/nuxt/src/app/composables/index.ts +++ b/packages/nuxt/src/app/composables/index.ts @@ -1,5 +1,5 @@ export { defineNuxtComponent } from './component' -export { useAsyncData, useLazyAsyncData, refreshNuxtData } from './asyncData' +export { useAsyncData, useLazyAsyncData, refreshNuxtData, clearNuxtData } from './asyncData' export type { AsyncDataOptions, AsyncData } from './asyncData' export { useHydration } from './hydrate' export { useState } from './state' diff --git a/packages/nuxt/src/app/composables/payload.ts b/packages/nuxt/src/app/composables/payload.ts index 03c37bb97139..f53d06d7ab8c 100644 --- a/packages/nuxt/src/app/composables/payload.ts +++ b/packages/nuxt/src/app/composables/payload.ts @@ -1,6 +1,6 @@ import { parseURL, joinURL } from 'ufo' import { useNuxtApp } from '../nuxt' -import { useHead } from '#app' +import { useHead } from '..' interface LoadPayloadOptions { fresh?: boolean diff --git a/packages/nuxt/src/app/composables/preload.ts b/packages/nuxt/src/app/composables/preload.ts index cb888cbce69c..7b9f01acf457 100644 --- a/packages/nuxt/src/app/composables/preload.ts +++ b/packages/nuxt/src/app/composables/preload.ts @@ -1,5 +1,5 @@ import type { Component } from 'vue' -import { useNuxtApp } from '#app' +import { useNuxtApp } from '../nuxt' /** * Preload a component or components that have been globally registered. diff --git a/packages/nuxt/src/app/composables/router.ts b/packages/nuxt/src/app/composables/router.ts index 4d07272f0fa9..a16dbf7f04be 100644 --- a/packages/nuxt/src/app/composables/router.ts +++ b/packages/nuxt/src/app/composables/router.ts @@ -2,7 +2,9 @@ import { getCurrentInstance, inject } from 'vue' import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure, RouteLocationPathRaw } from 'vue-router' import { sendRedirect } from 'h3' import { hasProtocol, joinURL, parseURL } from 'ufo' -import { useNuxtApp, useRuntimeConfig, useState, createError, NuxtError } from '#app' +import { useNuxtApp, useRuntimeConfig } from '../nuxt' +import { createError, NuxtError } from './error' +import { useState } from './state' export const useRouter = () => { return useNuxtApp()?.$router as Router @@ -77,7 +79,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na } // Early redirect on client-side - if (!isExternal && isProcessingMiddleware()) { + if (process.client && !isExternal && isProcessingMiddleware()) { return to } diff --git a/packages/nuxt/src/app/composables/ssr.ts b/packages/nuxt/src/app/composables/ssr.ts index 6172aa9a239f..f2e127e3f14d 100644 --- a/packages/nuxt/src/app/composables/ssr.ts +++ b/packages/nuxt/src/app/composables/ssr.ts @@ -1,7 +1,6 @@ /* eslint-disable no-redeclare */ import type { CompatibilityEvent } from 'h3' -import { useNuxtApp } from '#app' -import { NuxtApp } from '#app/nuxt' +import { useNuxtApp, NuxtApp } from '../nuxt' export function useRequestHeaders (include: K[]): Record export function useRequestHeaders (): Readonly> diff --git a/packages/nuxt/src/app/composables/state.ts b/packages/nuxt/src/app/composables/state.ts index 95f53ca2d273..3a710ee6d368 100644 --- a/packages/nuxt/src/app/composables/state.ts +++ b/packages/nuxt/src/app/composables/state.ts @@ -1,6 +1,6 @@ import { isRef, toRef } from 'vue' import type { Ref } from 'vue' -import { useNuxtApp } from '#app' +import { useNuxtApp } from '../nuxt' /** * Create a global reactive ref that will be hydrated but not shared across ssr requests diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index d80a5f1d248b..881d9a248a07 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -31,6 +31,7 @@ export interface RuntimeNuxtHooks { 'app:error': (err: any) => HookResult 'app:error:cleared': (options: { redirect?: string }) => HookResult 'app:data:refresh': (keys?: string[]) => HookResult + 'link:prefetch': (link: string) => HookResult 'page:start': (Component?: VNode) => HookResult 'page:finish': (Component?: VNode) => HookResult 'vue:setup': () => void diff --git a/packages/nuxt/src/app/plugins/payload.client.ts b/packages/nuxt/src/app/plugins/payload.client.ts index fce8a62c618a..c13acdb001b8 100644 --- a/packages/nuxt/src/app/plugins/payload.client.ts +++ b/packages/nuxt/src/app/plugins/payload.client.ts @@ -1,19 +1,20 @@ -import { defineNuxtPlugin, loadPayload, addRouteMiddleware, isPrerendered } from '#app' +import { defineNuxtPlugin, loadPayload, isPrerendered, useRouter } from '#app' export default defineNuxtPlugin((nuxtApp) => { // Only enable behavior if initial page is prerendered - // TOOD: Support hybrid + // TOOD: Support hybrid and dev if (!isPrerendered()) { return } - addRouteMiddleware(async (to, from) => { + + // Load payload into cache + nuxtApp.hooks.hook('link:prefetch', to => loadPayload(to)) + + // Load payload after middleware & once final route is resolved + useRouter().beforeResolve(async (to, from) => { if (to.path === from.path) { return } - const url = to.path - const payload = await loadPayload(url) - if (!payload) { - return - } + const payload = await loadPayload(to.path) + if (!payload) { return } Object.assign(nuxtApp.payload.data, payload.data) - Object.assign(nuxtApp.payload.state, payload.state) }) }) diff --git a/packages/nuxt/src/components/loader.ts b/packages/nuxt/src/components/loader.ts index ee0a86b5bf0f..452fc7025c0c 100644 --- a/packages/nuxt/src/components/loader.ts +++ b/packages/nuxt/src/components/loader.ts @@ -65,26 +65,31 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => { const s = new MagicString(code) // replace `_resolveComponent("...")` to direct import - s.replace(/(?<=[ (])_?resolveComponent\(\s*["'](lazy-|Lazy)?([^'"]*?)["'][\s,]*\)/g, (full, lazy, name) => { + s.replace(/(?<=[ (])_?resolveComponent\(\s*["'](lazy-|Lazy)?([^'"]*?)["'][\s,]*[^)]*\)/g, (full, lazy, name) => { const component = findComponent(components, name, options.mode) if (component) { let identifier = map.get(component) || `__nuxt_component_${num++}` map.set(component, identifier) + const isClientOnly = component.mode === 'client' + if (isClientOnly) { + imports.add(genImport('#app/components/client-only', [{ name: 'createClientOnly' }])) + identifier += '_client' + } + if (lazy) { imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }])) identifier += '_lazy' - imports.add(`const ${identifier} = /*#__PURE__*/ __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: true })})`) + imports.add(`const ${identifier} = /*#__PURE__*/ __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: true })}${isClientOnly ? '.then(c => createClientOnly(c))' : ''})`) } else { imports.add(genImport(component.filePath, [{ name: component.export, as: identifier }])) - } - const isClientOnly = component.mode === 'client' - if (isClientOnly) { - imports.add(genImport('#app/components/client-only', [{ name: 'createClientOnly' }])) - imports.add(`const ${identifier}_client = /*#__PURE__*/ createClientOnly(${identifier})`) - identifier += '_client' + if (isClientOnly) { + imports.add(`const ${identifier}_wrapped = /*#__PURE__*/ createClientOnly(${identifier})`) + identifier += '_wrapped' + } } + return identifier } // no matched diff --git a/packages/nuxt/src/components/templates.ts b/packages/nuxt/src/components/templates.ts index c79b3ad57271..00b3356dbfc9 100644 --- a/packages/nuxt/src/components/templates.ts +++ b/packages/nuxt/src/components/templates.ts @@ -89,11 +89,13 @@ export const componentsTypeTemplate: NuxtTemplate = { const buildDir = nuxt.options.buildDir const componentTypes = options.getComponents().map(c => [ c.pascalName, - `typeof ${genDynamicImport(isAbsolute(c.filePath) ? relative(buildDir, c.filePath) : c.filePath, { wrapper: false })}['${c.export}']` + `typeof ${genDynamicImport(isAbsolute(c.filePath) + ? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!vue)\w+$/g, '') + : c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']` ]) return `// Generated by components discovery -declare module 'vue' { +declare module '@vue/runtime-core' { export interface GlobalComponents { ${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join('\n')} ${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join('\n')} diff --git a/packages/nuxt/src/components/tree-shake.ts b/packages/nuxt/src/components/tree-shake.ts index 1cb14dde5c4e..23d869ddde9e 100644 --- a/packages/nuxt/src/components/tree-shake.ts +++ b/packages/nuxt/src/components/tree-shake.ts @@ -6,7 +6,7 @@ import type { Component } from '@nuxt/schema' interface TreeShakeTemplatePluginOptions { sourcemap?: boolean - getComponents(): Component[] + getComponents (): Component[] } export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplatePluginOptions) => { @@ -26,7 +26,7 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat .filter(c => c.mode === 'client' && !components.some(other => other.mode !== 'client' && other.pascalName === c.pascalName)) .map(c => `${c.pascalName}|${c.kebabName}`) .concat('ClientOnly|client-only') - .map(component => `<(${component})[^>]*>[\\s\\S]*?<\\/(${component})>`) + .map(component => `<(${component})(| [^>]*)>[\\s\\S]*?<\\/(${component})>`) regexpMap.set(components, new RegExp(`(${clientOnlyComponents.join('|')})`, 'g')) } @@ -34,8 +34,12 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat const COMPONENTS_RE = regexpMap.get(components)! const s = new MagicString(code) - // Do not render client-only slots on SSR, but preserve attributes - s.replace(COMPONENTS_RE, r => r.replace(/<([^>]*[^/])\/?>[\s\S]*$/, '<$1 />')) + // Do not render client-only slots on SSR, but preserve attributes and fallback/placeholder slots + s.replace(COMPONENTS_RE, r => r.replace(/<([^>]*[^/])\/?>[\s\S]*$/, (chunk: string, el: string) => { + const fallback = chunk.match(/]*(#|v-slot:)(fallback|placeholder)[^>]*>[\s\S]*?<\/template>/)?.[0] || '' + const tag = el.split(' ').shift() + return `<${el}>${fallback}` + })) if (s.hasChanged()) { return { diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index be20faa92537..d473a3a9ae21 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -1,6 +1,6 @@ import { existsSync, promises as fsp } from 'node:fs' import { resolve, join } from 'pathe' -import { createNitro, createDevServer, build, prepare, copyPublicAssets, writeTypes, scanHandlers, prerender } from 'nitropack' +import { createNitro, createDevServer, build, prepare, copyPublicAssets, writeTypes, scanHandlers, prerender, Nitro } from 'nitropack' import type { NitroEventHandler, NitroDevEventHandler, NitroConfig } from 'nitropack' import type { Nuxt } from '@nuxt/schema' import { resolvePath } from '@nuxt/kit' @@ -10,7 +10,7 @@ import { toEventHandler, dynamicEventHandler } from 'h3' import { distDir } from '../dirs' import { ImportProtectionPlugin } from './plugins/import-protection' -export async function initNitro (nuxt: Nuxt) { +export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { // Resolve handlers const { handlers, devHandlers } = await resolveHandlers(nuxt) @@ -18,6 +18,7 @@ export async function initNitro (nuxt: Nuxt) { const _nitroConfig = ((nuxt.options as any).nitro || {}) as NitroConfig const nitroConfig: NitroConfig = defu(_nitroConfig, { rootDir: nuxt.options.rootDir, + workspaceDir: nuxt.options.workspaceDir, srcDir: join(nuxt.options.srcDir, 'server'), dev: nuxt.options.dev, preset: nuxt.options.dev ? 'nitro-dev' : undefined, @@ -55,8 +56,8 @@ export async function initNitro (nuxt: Nuxt) { prerender: { crawlLinks: nuxt.options._generate ? nuxt.options.generate.crawler : false, routes: ([] as string[]) - .concat(nuxt.options._generate ? ['/', ...nuxt.options.generate.routes] : []) - .concat(nuxt.options.ssr === false ? ['/', '/200.html', '/404.html'] : []) + .concat(nuxt.options.generate.routes) + .concat(nuxt.options._generate ? [nuxt.options.ssr ? '/' : '/index.html', '/200.html', '/404.html'] : []) }, sourceMap: nuxt.options.sourcemap.server, externals: { @@ -69,7 +70,8 @@ export async function initNitro (nuxt: Nuxt) { nuxt.options.buildDir ]), 'nuxt/dist', - 'nuxt3/dist' + 'nuxt3/dist', + distDir ] }, alias: { @@ -97,8 +99,9 @@ export async function initNitro (nuxt: Nuxt) { }, replace: { 'process.env.NUXT_NO_SSR': nuxt.options.ssr === false, - 'process.env.NUXT_NO_SCRIPTS': !!nuxt.options.experimental.noScripts, + 'process.env.NUXT_NO_SCRIPTS': !!nuxt.options.experimental.noScripts && !nuxt.options.dev, 'process.env.NUXT_INLINE_STYLES': !!nuxt.options.experimental.inlineSSRStyles, + 'process.env.NUXT_PAYLOAD_EXTRACTION': !!nuxt.options.experimental.payloadExtraction, 'process.dev': nuxt.options.dev, __VUE_PROD_DEVTOOLS__: false }, @@ -132,7 +135,8 @@ export async function initNitro (nuxt: Nuxt) { // Init nitro const nitro = await createNitro(nitroConfig) - // Expose nitro to modules + // Expose nitro to modules and kit + nuxt._nitro = nitro await nuxt.callHook('nitro:init', nitro) // Connect vfs storages diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 99e840de3052..81305b826913 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -57,6 +57,13 @@ async function initNuxt (nuxt: Nuxt) { // Add module augmentations directly to NuxtConfig opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/schema.d.ts') }) opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/app.config.d.ts') }) + + for (const layer of nuxt.options._layers) { + const declaration = join(layer.cwd, 'index.d.ts') + if (fse.existsSync(declaration)) { + opts.references.push({ path: declaration }) + } + } }) // Add import protection @@ -85,7 +92,7 @@ async function initNuxt (nuxt: Nuxt) { } // TODO: [Experimental] Avoid emitting assets when flag is enabled - if (nuxt.options.experimental.noScripts) { + if (nuxt.options.experimental.noScripts && !nuxt.options.dev) { nuxt.hook('build:manifest', async (manifest) => { for (const file in manifest) { if (manifest[file].resourceType === 'script') { @@ -167,7 +174,14 @@ async function initNuxt (nuxt: Nuxt) { }) // Add prerender payload support - addPlugin(resolve(nuxt.options.appDir, 'plugins/payload.client')) + if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) { + addPlugin(resolve(nuxt.options.appDir, 'plugins/payload.client')) + } + + // Track components used to render for webpack + if (nuxt.options.builder === '@nuxt/webpack-builder') { + addPlugin(resolve(nuxt.options.appDir, 'plugins/preload.server')) + } for (const m of modulesToInstall) { if (Array.isArray(m)) { @@ -204,6 +218,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise { .map(i => new RegExp(`(^|\\/)${escapeRE(i.cwd!.split('node_modules/').pop()!)}(\\/|$)(?!node_modules\\/)`)) } }]) + options.modulesDir.push(resolve(options.workspaceDir, 'node_modules')) options.modulesDir.push(resolve(pkgDir, 'node_modules')) options.build.transpile.push('@nuxt/ui-templates') options.alias['vue-demi'] = resolve(options.appDir, 'compat/vue-demi') @@ -221,9 +236,11 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise { return nuxt } +/** @deprecated `defineNuxtConfig` is auto imported. Remove import or alternatively use `import { defineNuxtConfig } from 'nuxt/config'`. */ export function defineNuxtConfig (config: NuxtConfig): NuxtConfig { return config } -// For a convenience import together with `defineNuxtConfig` -export type { NuxtConfig } +/** @deprecated Use `import type { NuxtConfig } from 'nuxt/config'`. */ +type _NuxtConfig = NuxtConfig +export type { _NuxtConfig as NuxtConfig } diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 66883ecba119..fcb56a73f754 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -103,9 +103,11 @@ const getSPARenderer = lazyCachedFunction(async () => { return { renderToString } }) -const PAYLOAD_CACHE = process.env.prerender ? new Map() : null // TODO: Use LRU cache +const PAYLOAD_CACHE = (process.env.NUXT_PAYLOAD_EXTRACTION && process.env.prerender) ? new Map() : null // TODO: Use LRU cache const PAYLOAD_URL_RE = /\/_payload(\.[a-zA-Z0-9]+)?.js(\?.*)?$/ +const PRERENDER_NO_SSR_ROUTES = new Set(['/index.html', '/200.html', '/404.html']) + export default defineRenderHandler(async (event) => { // Whether we're rendering an error page const ssrError = event.req.url?.startsWith('/__nuxt_error') @@ -130,14 +132,18 @@ export default defineRenderHandler(async (event) => { req: event.req, res: event.res, runtimeConfig: useRuntimeConfig() as NuxtSSRContext['runtimeConfig'], - noSSR: !!event.req.headers['x-nuxt-no-ssr'], + noSSR: + !!(process.env.NUXT_NO_SSR) || + !!(event.req.headers['x-nuxt-no-ssr']) || + (process.env.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false), error: !!ssrError, nuxt: undefined!, /* NuxtApp */ payload: (ssrError ? { error: ssrError } : {}) as NuxtSSRContext['payload'] } // Whether we are prerendering route - const payloadURL = process.env.prerender ? joinURL(url, '_payload.js') : undefined + const _PAYLOAD_EXTRACTION = process.env.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR + const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(useRuntimeConfig().app.baseURL, url, '_payload.js') : undefined if (process.env.prerender) { ssrContext.payload.prerenderedAt = Date.now() } @@ -169,9 +175,9 @@ export default defineRenderHandler(async (event) => { return response } - if (process.env.prerender) { + if (_PAYLOAD_EXTRACTION) { // Hint nitro to prerender payload for this route - appendHeader(event, 'x-nitro-prerender', payloadURL!) + appendHeader(event, 'x-nitro-prerender', joinURL(url, '_payload.js')) // Use same ssr context to generate payload for this route PAYLOAD_CACHE!.set(url, renderPayloadResponse(ssrContext)) } @@ -189,7 +195,7 @@ export default defineRenderHandler(async (event) => { htmlAttrs: normalizeChunks([renderedMeta.htmlAttrs]), head: normalizeChunks([ renderedMeta.headTags, - !process.env.NUXT_NO_SCRIPTS && process.env.prerender ? `` : null, + _PAYLOAD_EXTRACTION ? `` : null, _rendered.renderResourceHints(), _rendered.renderStyles(), inlinedStyles, @@ -207,7 +213,7 @@ export default defineRenderHandler(async (event) => { bodyAppend: normalizeChunks([ process.env.NUXT_NO_SCRIPTS ? undefined - : (process.env.prerender + : (_PAYLOAD_EXTRACTION ? `` : `` ), @@ -291,9 +297,9 @@ function renderPayloadResponse (ssrContext: NuxtSSRContext) { } function splitPayload (ssrContext: NuxtSSRContext) { - const { data, state, prerenderedAt, ...initial } = ssrContext.payload + const { data, prerenderedAt, ...initial } = ssrContext.payload return { initial: { ...initial, prerenderedAt }, - payload: { data, state, prerenderedAt } + payload: { data, prerenderedAt } } } diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index 3b2b4a7d28fa..d8cd4c326453 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -1,7 +1,7 @@ import type { Nuxt, NuxtApp, NuxtTemplate } from '@nuxt/schema' import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genString, genSafeVariableName } from 'knitwork' -import { isAbsolute, join, relative } from 'pathe' +import { isAbsolute, join, relative, resolve } from 'pathe' import { resolveSchema, generateTypes } from 'untyped' import escapeRE from 'escape-string-regexp' import { hash } from 'ohash' @@ -68,8 +68,8 @@ export const serverPluginTemplate: NuxtTemplate = { filename: 'plugins/server.mjs', getContents (ctx) { const serverPlugins = ctx.app.plugins.filter(p => !p.mode || p.mode !== 'client') - const exports: string[] = ['preload'] - const imports: string[] = ["import preload from '#app/plugins/preload.server'"] + const exports: string[] = [] + const imports: string[] = [] for (const plugin of serverPlugins) { const path = relative(ctx.nuxt.options.rootDir, plugin.src) const variable = genSafeVariableName(path).replace(/_(45|46|47)/g, '_') + '_' + hash(path) @@ -114,21 +114,23 @@ export { } const adHocModules = ['router', 'pages', 'imports', 'meta', 'components'] export const schemaTemplate: NuxtTemplate = { filename: 'types/schema.d.ts', - getContents: ({ nuxt }) => { + getContents: async ({ nuxt }) => { const moduleInfo = nuxt.options._installedModules.map(m => ({ ...m.meta || {}, importName: m.entryPath || m.meta?.name })).filter(m => m.configKey && m.name && !adHocModules.includes(m.name)) + const relativeRoot = relative(resolve(nuxt.options.buildDir, 'types'), nuxt.options.rootDir) + return [ "import { NuxtModule } from '@nuxt/schema'", "declare module '@nuxt/schema' {", ' interface NuxtConfig {', ...moduleInfo.filter(Boolean).map(meta => - ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName, { wrapper: false })}.default extends NuxtModule ? Partial : Record` + ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName.startsWith('.') ? './' + join(relativeRoot, meta.importName) : meta.importName, { wrapper: false })}.default extends NuxtModule ? Partial : Record` ), ' }', - generateTypes(resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== 'public'))), + generateTypes(await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== 'public'))), { interfaceName: 'RuntimeConfig', addExport: false, @@ -136,7 +138,7 @@ export const schemaTemplate: NuxtTemplate = { allowExtraKeys: false, indentation: 2 }), - generateTypes(resolveSchema(nuxt.options.runtimeConfig.public), + generateTypes(await resolveSchema(nuxt.options.runtimeConfig.public), { interfaceName: 'PublicRuntimeConfig', addExport: false, diff --git a/packages/nuxt/src/head/runtime/components.ts b/packages/nuxt/src/head/runtime/components.ts index df8ff0aed9a4..db72e444ce8b 100644 --- a/packages/nuxt/src/head/runtime/components.ts +++ b/packages/nuxt/src/head/runtime/components.ts @@ -90,9 +90,19 @@ export const Script = defineComponent({ /** @deprecated **/ language: String }, - setup: setupForUseMeta(script => ({ - script: [script] - })) + setup: setupForUseMeta((props, { slots }) => { + const script = { ...props } + const textContent = (slots.default?.() || []) + .filter(({ children }) => children) + .map(({ children }) => children) + .join('') + if (textContent) { + script.children = textContent + } + return { + script: [script] + } + }) }) //