├── docs ├── _dir.yml ├── 2.guide │ ├── _dir.yml │ ├── index.md │ ├── 1.concepts │ │ ├── index.md │ │ └── _dir.yml │ ├── 3.going-further │ │ ├── index.md │ │ └── _dir.yml │ └── 2.directory-structure │ │ ├── index.md │ │ ├── _dir.yml │ │ ├── 3.package.md │ │ ├── 1.node_modules.md │ │ ├── 1.public.md │ │ ├── 0.output.md │ │ ├── 2.gitignore.md │ │ └── 1.assets.md ├── 5.community │ ├── _dir.yml │ ├── _contributors.yml │ ├── index.md │ └── 7.changelog.md ├── 3.api │ ├── _dir.yml │ ├── 4.advanced │ │ └── _dir.yml │ ├── 5.commands │ │ ├── _dir.yml │ │ ├── upgrade.md │ │ ├── info.md │ │ ├── cleanup.md │ │ ├── analyze.md │ │ ├── prepare.md │ │ ├── devtools.md │ │ ├── build.md │ │ └── build-module.md │ ├── index.md │ ├── 6.configuration │ │ ├── _dir.yml │ │ └── nuxt-config.md │ ├── 3.utils │ │ ├── index.md │ │ ├── _dir.yml │ │ ├── on-before-route-leave.md │ │ ├── on-before-route-update.md │ │ ├── update-app-config.md │ │ ├── clear-nuxt-state.md │ │ ├── clear-nuxt-data.md │ │ ├── prerender-routes.md │ │ ├── set-page-layout.md │ │ ├── show-error.md │ │ ├── set-response-status.md │ │ ├── on-nuxt-ready.md │ │ └── clear-error.md │ ├── 2.components │ │ ├── index.md │ │ ├── _dir.yml │ │ └── 7.nuxt-welcome.md │ └── 1.composables │ │ ├── _dir.yml │ │ ├── use-app-config.md │ │ ├── use-request-event.md │ │ ├── use-request-url.md │ │ └── use-server-seo-meta.md ├── 6.bridge │ ├── _dir.yml │ └── 9.vite.md ├── 7.migration │ └── _dir.yml ├── 1.getting-started │ └── _dir.yml └── README.md ├── .nuxtrc ├── packages ├── kit │ ├── .gitignore │ ├── index.d.ts │ ├── src │ │ ├── logger.ts │ │ ├── loader │ │ │ └── schema.ts │ │ └── ignore.test.ts │ └── build.config.ts ├── schema │ ├── .gitignore │ ├── builder-env.d.ts │ └── src │ │ ├── builder-env.ts │ │ ├── index.ts │ │ ├── types │ │ ├── builder-env │ │ │ └── index.ts │ │ ├── router.ts │ │ ├── compatibility.ts │ │ └── imports.ts │ │ └── config │ │ ├── router.ts │ │ ├── internal.ts │ │ ├── generate.ts │ │ └── index.ts ├── nuxt │ ├── kit.d.ts │ ├── kit.js │ ├── schema.d.ts │ ├── schema.js │ ├── app.d.ts │ ├── src │ │ ├── app │ │ │ ├── entry-spa.ts │ │ │ ├── components │ │ │ │ ├── layout.ts │ │ │ │ ├── index.ts │ │ │ │ ├── server-placeholder.ts │ │ │ │ ├── dev-only.ts │ │ │ │ ├── injections.ts │ │ │ │ └── nuxt-error-boundary.ts │ │ │ ├── compat │ │ │ │ ├── vue-demi.ts │ │ │ │ ├── capi.ts │ │ │ │ └── idle-callback.ts │ │ │ ├── plugins │ │ │ │ ├── debug.ts │ │ │ │ ├── preload.server.ts │ │ │ │ └── restore-state.client.ts │ │ │ ├── entry.async.ts │ │ │ ├── middleware │ │ │ │ └── manifest-route-rule.ts │ │ │ ├── composables │ │ │ │ ├── asyncContext.ts │ │ │ │ ├── url.ts │ │ │ │ └── ready.ts │ │ │ └── index.ts │ │ ├── pages │ │ │ └── runtime │ │ │ │ ├── index.ts │ │ │ │ ├── app.vue │ │ │ │ └── page-placeholder.ts │ │ ├── index.ts │ │ ├── core │ │ │ ├── runtime │ │ │ │ └── nitro │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── no-ssr.ts │ │ │ │ │ └── paths.ts │ │ │ └── utils │ │ │ │ ├── index.ts │ │ │ │ └── names.ts │ │ ├── dirs.ts │ │ ├── head │ │ │ └── runtime │ │ │ │ └── plugins │ │ │ │ └── vueuse-head-polyfill.ts │ │ └── components │ │ │ └── runtime │ │ │ └── server-component.ts │ ├── bin │ │ └── nuxt.mjs │ ├── config.js │ ├── test │ │ ├── fixture │ │ │ └── components │ │ │ │ ├── islands │ │ │ │ └── Isle.vue │ │ │ │ ├── HelloWorld.vue │ │ │ │ ├── global │ │ │ │ └── Glob.vue │ │ │ │ ├── some.island.vue │ │ │ │ ├── Nuxt3.client.vue │ │ │ │ ├── Nuxt3.server.vue │ │ │ │ ├── parent-folder │ │ │ │ └── index.server.vue │ │ │ │ ├── some-glob.global.vue │ │ │ │ ├── same-name │ │ │ │ └── same │ │ │ │ │ └── Same.vue │ │ │ │ └── client │ │ │ │ └── ComponentWithProps.vue │ │ └── utils.ts │ ├── config.cjs │ ├── config.d.ts │ └── index.d.ts ├── vite │ ├── src │ │ ├── index.ts │ │ ├── runtime │ │ │ ├── client.manifest.mjs │ │ │ └── vite-node-shared.mjs │ │ ├── utils │ │ │ ├── wpfs.ts │ │ │ ├── index.ts │ │ │ └── transpile.ts │ │ ├── dirs.ts │ │ └── plugins │ │ │ └── type-check.ts │ └── build.config.ts ├── webpack │ ├── src │ │ ├── index.ts │ │ ├── configs │ │ │ └── index.ts │ │ ├── plugins │ │ │ └── warning-ignore.ts │ │ ├── presets │ │ │ ├── nuxt.ts │ │ │ └── pug.ts │ │ └── utils │ │ │ └── mfs.ts │ └── build.config.ts ├── test-utils │ ├── experimental.d.ts │ ├── src │ │ ├── dirs.ts │ │ ├── index.ts │ │ ├── mock.ts │ │ ├── setup │ │ │ ├── vitest.ts │ │ │ └── jest.ts │ │ ├── runtime │ │ │ └── global-setup.ts │ │ └── experimental.ts │ └── build.config.ts └── nuxi │ └── README.md ├── test ├── fixtures │ ├── basic │ │ ├── pages │ │ │ ├── empty.ts │ │ │ ├── invalid-root │ │ │ │ ├── 2.vue │ │ │ │ ├── 1.vue │ │ │ │ ├── 3.vue │ │ │ │ ├── 4.vue │ │ │ │ └── fine.vue │ │ │ ├── layout-switch │ │ │ │ ├── end.vue │ │ │ │ └── start.vue │ │ │ ├── jsx.vue │ │ │ ├── parent │ │ │ │ └── index.vue │ │ │ ├── parent.vue │ │ │ ├── another-parent │ │ │ │ └── index.vue │ │ │ ├── extends.vue │ │ │ ├── route-rules │ │ │ │ ├── spa.vue │ │ │ │ └── inline.vue │ │ │ ├── another-parent.vue │ │ │ ├── keyed-child-parent.vue │ │ │ ├── non-ascii │ │ │ │ └── ç.vue │ │ │ ├── fixed-keyed-child-parent.vue │ │ │ ├── plugins.vue │ │ │ ├── navigate-to-api.vue │ │ │ ├── navigate-to.vue │ │ │ ├── prefetch │ │ │ │ ├── server-components.vue │ │ │ │ ├── index.vue │ │ │ │ └── components.vue │ │ │ ├── url.vue │ │ │ ├── redirect.vue │ │ │ ├── with-dynamic-layout.vue │ │ │ ├── no-scripts.vue │ │ │ ├── with-computed-layout.vue │ │ │ ├── auth.vue │ │ │ ├── ignore │ │ │ │ └── composables.vue │ │ │ ├── instance │ │ │ │ ├── error.vue │ │ │ │ └── next-request.vue │ │ │ ├── async-context.vue │ │ │ ├── legacy │ │ │ │ ├── async-data │ │ │ │ │ ├── index │ │ │ │ │ │ └── index.vue │ │ │ │ │ └── index.vue │ │ │ │ └── async-data.vue │ │ │ ├── no-auth.vue │ │ │ ├── legacy-async-data-fail.vue │ │ │ ├── app-config.vue │ │ │ ├── hydration │ │ │ │ ├── spa-redirection │ │ │ │ │ ├── end.vue │ │ │ │ │ └── start.vue │ │ │ │ └── layout.vue │ │ │ ├── with-layout.vue │ │ │ ├── with-layout2.vue │ │ │ ├── internal-layout.vue │ │ │ ├── async-parent.vue │ │ │ ├── async-parent │ │ │ │ └── child.vue │ │ │ ├── layouts │ │ │ │ └── with-props.vue │ │ │ ├── tree-shake.vue │ │ │ ├── middleware-abort-non-fatal.vue │ │ │ ├── server-components │ │ │ │ └── lazy │ │ │ │ │ ├── start.vue │ │ │ │ │ └── end.vue │ │ │ ├── wrapper-expose │ │ │ │ ├── page │ │ │ │ │ ├── index.vue │ │ │ │ │ └── another.vue │ │ │ │ └── page.vue │ │ │ ├── client-only-explicit-import.vue │ │ │ ├── suspense │ │ │ │ ├── sync-[parent].vue │ │ │ │ ├── sync-[parent] │ │ │ │ │ ├── sync-[child].vue │ │ │ │ │ └── async-[child].vue │ │ │ │ ├── async-[parent] │ │ │ │ │ ├── sync-[child].vue │ │ │ │ │ └── async-[child].vue │ │ │ │ └── async-[parent].vue │ │ │ ├── useAsyncData │ │ │ │ ├── single.vue │ │ │ │ ├── immediate-remove-unmounted.vue │ │ │ │ └── double.vue │ │ │ ├── styles.vue │ │ │ ├── navigate-to-external.vue │ │ │ ├── nested │ │ │ │ ├── [foo].vue │ │ │ │ └── [foo] │ │ │ │ │ ├── [bar].vue │ │ │ │ │ └── user-[group].vue │ │ │ ├── middleware-abort.vue │ │ │ ├── navigate-to-forbidden.vue │ │ │ ├── fixed-keyed-child-parent │ │ │ │ └── [foo].vue │ │ │ ├── navigate-to-error.vue │ │ │ ├── keyed-child-parent │ │ │ │ └── [foo].vue │ │ │ ├── navigate-to-redirect.vue │ │ │ ├── error.vue │ │ │ ├── [...slug].vue │ │ │ ├── vueuse-head.vue │ │ │ ├── chunk-error.vue │ │ │ ├── cookies.vue │ │ │ └── assets.vue │ │ ├── layouts │ │ │ ├── PascalCase.ts │ │ │ ├── invalid-root.vue │ │ │ ├── with-props.vue │ │ │ ├── custom-async.vue │ │ │ ├── custom2.vue │ │ │ └── custom.vue │ │ ├── .gitignore │ │ ├── public │ │ │ └── ignore │ │ │ │ └── public-asset │ │ ├── assets │ │ │ ├── assets.css │ │ │ ├── plugin.css │ │ │ ├── functional.css │ │ │ ├── global.css │ │ │ └── css-only-asset.svg │ │ ├── composables │ │ │ ├── export-star.ts │ │ │ ├── ignored.ts │ │ │ ├── override-base.ts │ │ │ ├── template.ts │ │ │ ├── foo.ts │ │ │ ├── nested │ │ │ │ └── bar.ts │ │ │ ├── badSideEffect.ts │ │ │ ├── random.ts │ │ │ ├── asyncDataTests.ts │ │ │ ├── async-context.ts │ │ │ └── tree-shake.ts │ │ ├── plugins │ │ │ ├── invalid-plugin-1.ts │ │ │ ├── test.d.ts │ │ │ ├── invalid-plugin-2.ts │ │ │ ├── this-should-not-load.spec.js │ │ │ ├── cookie.ts │ │ │ ├── prerender.server.ts │ │ │ ├── chunk-error.ts │ │ │ ├── context-error.ts │ │ │ ├── my-plugin.ts │ │ │ ├── server-only.server.ts │ │ │ ├── style.ts │ │ │ ├── custom-type-registration.ts │ │ │ ├── register.ts │ │ │ ├── custom-type-assertion.client.ts │ │ │ ├── 10.layer-ordering.ts │ │ │ ├── add-route.ts │ │ │ └── async-plugin.ts │ │ ├── tsconfig.json │ │ ├── extends │ │ │ ├── bar │ │ │ │ ├── app.config.ts │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── composables │ │ │ │ │ └── base.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── middleware │ │ │ │ │ ├── a.global.ts │ │ │ │ │ └── override.ts │ │ │ │ ├── components │ │ │ │ │ └── ExtendsOverride.vue │ │ │ │ ├── layouts │ │ │ │ │ └── override.vue │ │ │ │ ├── plugins │ │ │ │ │ ├── 09.layer-plugin-pre.ts │ │ │ │ │ └── 11.layer-plugin-post.ts │ │ │ │ ├── app │ │ │ │ │ └── router.options.ts │ │ │ │ └── pages │ │ │ │ │ └── override.vue │ │ │ └── node_modules │ │ │ │ └── foo │ │ │ │ ├── alias │ │ │ │ └── test.ts │ │ │ │ ├── composables │ │ │ │ └── foo.ts │ │ │ │ ├── components │ │ │ │ ├── ExtendsFoo.vue │ │ │ │ └── ExtendsOverride.vue │ │ │ │ ├── layouts │ │ │ │ ├── override.vue │ │ │ │ └── default.vue │ │ │ │ ├── server │ │ │ │ ├── api │ │ │ │ │ └── foo.ts │ │ │ │ └── middleware │ │ │ │ │ └── foo.ts │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── pages │ │ │ │ ├── override │ │ │ │ │ └── index.vue │ │ │ │ ├── override.vue │ │ │ │ └── foo.vue │ │ │ │ ├── middleware │ │ │ │ ├── foo.ts │ │ │ │ └── override.ts │ │ │ │ ├── plugins │ │ │ │ └── foo.ts │ │ │ │ └── app │ │ │ │ └── router.options.ts │ │ ├── server │ │ │ ├── api │ │ │ │ ├── hello.ts │ │ │ │ ├── hey │ │ │ │ │ ├── index.post.ts │ │ │ │ │ └── index.get.ts │ │ │ │ ├── counter.ts │ │ │ │ ├── random.ts │ │ │ │ ├── app-config.ts │ │ │ │ ├── union.ts │ │ │ │ ├── auto-imports.ts │ │ │ │ ├── very-long-request.ts │ │ │ │ └── useAsyncData │ │ │ │ │ └── count.ts │ │ │ ├── tsconfig.json │ │ │ ├── routes │ │ │ │ ├── ignore │ │ │ │ │ └── scanned.ts │ │ │ │ └── proxy.ts │ │ │ └── plugins │ │ │ │ └── headers.ts │ │ ├── components │ │ │ ├── client │ │ │ │ ├── NoState.client.vue │ │ │ │ ├── Binding.client.ts │ │ │ │ ├── StringChildStateful.client.vue │ │ │ │ ├── MultiRootNode.client.vue │ │ │ │ ├── StringChildStatefulScript.client.vue │ │ │ │ ├── MultiRootNodeScript.client.vue │ │ │ │ ├── SetupScript.client.vue │ │ │ │ └── Script.client.vue │ │ │ ├── WithSuffix.global.vue │ │ │ ├── islands │ │ │ │ ├── RouteComponent.vue │ │ │ │ └── PureComponent.vue │ │ │ ├── global │ │ │ │ ├── TestGlobal.vue │ │ │ │ ├── ServerComponentGlobal.server.vue │ │ │ │ └── ClientGlobal.client.vue │ │ │ ├── GlobalSync.vue │ │ │ ├── FunctionalComponent.ts │ │ │ ├── BreaksServer.client.ts │ │ │ ├── BreakInSetup.vue │ │ │ ├── Tsx.tsx │ │ │ ├── clientFallback │ │ │ │ ├── NonStatefulSetup.vue │ │ │ │ ├── StatefulSetup.vue │ │ │ │ ├── NonStateful.vue │ │ │ │ └── Stateful.vue │ │ │ ├── Nested │ │ │ │ └── SugarCounter.vue │ │ │ ├── ClientOnlySetupScript.client.vue │ │ │ ├── ServerOnlyComponent.server.vue │ │ │ ├── ComponentWithRef.vue │ │ │ ├── ClientWrapped.client.vue │ │ │ ├── AsyncServerComponent.server.vue │ │ │ ├── SugarCounter.vue │ │ │ └── ClientOnlyScript.client.vue │ │ ├── .nuxtignore │ │ ├── modules │ │ │ ├── auto-registered │ │ │ │ ├── runtime │ │ │ │ │ ├── server │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ └── some-utils.ts │ │ │ │ │ ├── handler.ts │ │ │ │ │ └── some-server-import.ts │ │ │ │ └── index.ts │ │ │ ├── runtime │ │ │ │ ├── plugin.ts │ │ │ │ ├── middleware.ts │ │ │ │ └── page.vue │ │ │ ├── test │ │ │ │ └── index.ts │ │ │ ├── functional.ts │ │ │ ├── example.ts │ │ │ └── page-extend │ │ │ │ └── index.ts │ │ ├── utils │ │ │ └── useBar.ts │ │ ├── some-exports.ts │ │ ├── app.config.ts │ │ ├── other-composables-folder │ │ │ ├── custom-keyed-composable.ts │ │ │ └── local.ts │ │ ├── middleware │ │ │ ├── injectAuth.ts │ │ │ ├── sets-layout.ts │ │ │ ├── abort.global.ts │ │ │ └── b.global.ts │ │ ├── other-components-folder │ │ │ └── named-export.ts │ │ ├── error.vue │ │ └── package.json │ ├── basic-types │ │ ├── layouts │ │ │ ├── PascalCase.ts │ │ │ └── custom.vue │ │ ├── .gitignore │ │ ├── extends │ │ │ ├── bar │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── app.config.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── layouts │ │ │ │ │ └── override.vue │ │ │ │ ├── middleware │ │ │ │ │ └── override.ts │ │ │ │ └── pages │ │ │ │ │ └── override.vue │ │ │ └── node_modules │ │ │ │ └── foo │ │ │ │ ├── layouts │ │ │ │ ├── override.vue │ │ │ │ └── default.vue │ │ │ │ ├── pages │ │ │ │ ├── override.vue │ │ │ │ └── foo.vue │ │ │ │ ├── server │ │ │ │ └── api │ │ │ │ │ └── foo.ts │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── middleware │ │ │ │ ├── foo.ts │ │ │ │ └── override.ts │ │ │ │ └── plugins │ │ │ │ └── foo.ts │ │ ├── tsconfig.json │ │ ├── server │ │ │ ├── api │ │ │ │ ├── hello.ts │ │ │ │ ├── hey │ │ │ │ │ ├── index.get.ts │ │ │ │ │ └── index.post.ts │ │ │ │ └── union.ts │ │ │ └── tsconfig.json │ │ ├── pages │ │ │ ├── page.vue │ │ │ ├── param │ │ │ │ └── [id].vue │ │ │ └── custom-name.vue │ │ ├── app.config.ts │ │ ├── modules │ │ │ ├── auto-registered │ │ │ │ ├── runtime │ │ │ │ │ └── handler.ts │ │ │ │ └── index.ts │ │ │ ├── runtime │ │ │ │ ├── plugin.ts │ │ │ │ ├── middleware.ts │ │ │ │ └── page.vue │ │ │ ├── test │ │ │ │ └── index.ts │ │ │ ├── page-extend.ts │ │ │ └── example.ts │ │ ├── middleware │ │ │ ├── named.ts │ │ │ └── global.global.ts │ │ ├── plugins │ │ │ └── injection.ts │ │ ├── nuxt.schema.ts │ │ ├── package.json │ │ └── components │ │ │ └── WithTypes.vue │ ├── minimal │ │ ├── tsconfig.json │ │ ├── error.vue │ │ ├── package.json │ │ └── nuxt.config.ts │ ├── minimal-types │ │ ├── app.vue │ │ ├── tsconfig.json │ │ ├── nuxt.config.ts │ │ └── package.json │ └── runtime-compiler │ │ ├── .gitignore │ │ ├── public │ │ └── favicon.ico │ │ ├── tsconfig.json │ │ ├── components │ │ ├── Helloworld.vue │ │ ├── Name.ts │ │ └── ShowTemplate.vue │ │ ├── package.json │ │ ├── server │ │ └── api │ │ │ ├── template.get.ts │ │ │ └── full-component.get.ts │ │ └── nuxt.config.ts ├── setup.ts └── setup-env.ts ├── scripts ├── example.sh ├── release.sh ├── bump.ts ├── bump-rc.ts ├── release-rc.sh └── release-edge.sh ├── .website ├── tsconfig.json ├── .gitignore ├── package.json ├── app.config.ts ├── nuxt.config.ts └── README.md ├── playground ├── nuxt.config.ts ├── tsconfig.json ├── server │ ├── tsconfig.json │ └── api │ │ └── test.ts ├── app.vue └── package.json ├── .stackblitz ├── config.json └── codeflow.json ├── .npmrc ├── .github ├── assets │ ├── banner.png │ ├── modules.png │ ├── examples.png │ ├── questions.png │ ├── suggestions.png │ ├── documentation.png │ ├── reporting-bugs.png │ ├── twitter.svg │ └── github.svg ├── issue-up.yml ├── FUNDING.yml ├── workflows │ ├── reproduire.yml │ ├── introspect.yml │ └── autofix-docs.yml └── ISSUE_TEMPLATE │ └── config.yml ├── pnpm-workspace.yaml ├── .markdownlintignore ├── changelog.config.json ├── examples └── README.md ├── .vscode └── extensions.json ├── .editorconfig ├── .markdownlint.yml ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .gitpod.yml ├── vitest.nuxt.config.ts ├── lychee.toml ├── SECURITY.md └── knip.json /docs/_dir.yml: -------------------------------------------------------------------------------- 1 | title: Docs 2 | -------------------------------------------------------------------------------- /.nuxtrc: -------------------------------------------------------------------------------- 1 | telemetry.enabled=false 2 | -------------------------------------------------------------------------------- /packages/kit/.gitignore: -------------------------------------------------------------------------------- 1 | /schema 2 | -------------------------------------------------------------------------------- /packages/schema/.gitignore: -------------------------------------------------------------------------------- 1 | /schema 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/empty.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/PascalCase.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/layouts/PascalCase.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/2.guide/_dir.yml: -------------------------------------------------------------------------------- 1 | image: '/socials/guide.jpg' 2 | -------------------------------------------------------------------------------- /packages/nuxt/kit.d.ts: -------------------------------------------------------------------------------- 1 | export * from '@nuxt/kit' 2 | -------------------------------------------------------------------------------- /packages/nuxt/kit.js: -------------------------------------------------------------------------------- 1 | export * from '@nuxt/kit' 2 | -------------------------------------------------------------------------------- /packages/vite/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './vite' 2 | -------------------------------------------------------------------------------- /packages/nuxt/schema.d.ts: -------------------------------------------------------------------------------- 1 | export * from '@nuxt/schema' 2 | -------------------------------------------------------------------------------- /packages/nuxt/schema.js: -------------------------------------------------------------------------------- 1 | export * from '@nuxt/schema' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/.gitignore: -------------------------------------------------------------------------------- 1 | !extends/node_modules 2 | -------------------------------------------------------------------------------- /docs/5.community/_dir.yml: -------------------------------------------------------------------------------- 1 | image: '/socials/community.jpg' 2 | -------------------------------------------------------------------------------- /packages/nuxt/app.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/app/index.js' 2 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/entry-spa.ts: -------------------------------------------------------------------------------- 1 | export default () => {} 2 | -------------------------------------------------------------------------------- /packages/schema/builder-env.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/env' 2 | -------------------------------------------------------------------------------- /packages/webpack/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './webpack' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/.gitignore: -------------------------------------------------------------------------------- 1 | !extends/node_modules 2 | -------------------------------------------------------------------------------- /docs/3.api/_dir.yml: -------------------------------------------------------------------------------- 1 | title: API 2 | image: '/socials/api.jpg' 3 | -------------------------------------------------------------------------------- /packages/nuxt/bin/nuxt.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import 'nuxi/cli' 3 | -------------------------------------------------------------------------------- /scripts/example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pnpm --filter example-$2 $1 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/public/ignore/public-asset: -------------------------------------------------------------------------------- 1 | this should be ignored 2 | -------------------------------------------------------------------------------- /.website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/nuxt/src/pages/runtime/index.ts: -------------------------------------------------------------------------------- 1 | export * from './composables' 2 | -------------------------------------------------------------------------------- /packages/test-utils/experimental.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/experimental' 2 | -------------------------------------------------------------------------------- /playground/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | 3 | }) 4 | -------------------------------------------------------------------------------- /playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/assets/assets.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --assets: 'assets'; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/assets/plugin.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --plugin: 'plugin'; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/export-star.ts: -------------------------------------------------------------------------------- 1 | export * from './nested/bar' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/invalid-plugin-1.ts: -------------------------------------------------------------------------------- 1 | import 'nonexistent-package' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/test.d.ts: -------------------------------------------------------------------------------- 1 | interface MyInterface {} 2 | export {} 3 | -------------------------------------------------------------------------------- /.stackblitz/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "startCommand": "pnpm build:stub && pnpm play" 3 | } 4 | -------------------------------------------------------------------------------- /docs/5.community/_contributors.yml: -------------------------------------------------------------------------------- 1 | contributors: 2 | name: '' 3 | link: '' 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/minimal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | shell-emulator=true 4 | -------------------------------------------------------------------------------- /packages/nuxt/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './core/nuxt' 2 | export * from './core/builder' 3 | -------------------------------------------------------------------------------- /playground/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({}) 2 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/assets/functional.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --functional: 'functional'; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/minimal/error.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/3.api/4.advanced/_dir.yml: -------------------------------------------------------------------------------- 1 | navigation.icon: uil:cell 2 | image: '/socials/advanced.jpg' 3 | -------------------------------------------------------------------------------- /docs/6.bridge/_dir.yml: -------------------------------------------------------------------------------- 1 | titleTemplate: 'Migrate to Bridge: %s' 2 | image: '/socials/guide.jpg' 3 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/ignored.ts: -------------------------------------------------------------------------------- 1 | export function useIgnoredImport () { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/app.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | fromLayer: true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/invalid-root/2.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/hello.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => 'Hello API') 2 | -------------------------------------------------------------------------------- /test/fixtures/minimal-types/app.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/minimal-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /docs/2.guide/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | redirect: /guide/concepts/auto-imports 4 | --- 5 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/_dir.yml: -------------------------------------------------------------------------------- 1 | navigation.icon: uil:caret-right 2 | image: '/socials/commands.jpg' 3 | -------------------------------------------------------------------------------- /docs/3.api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | redirect: /api/composables/use-app-config 4 | --- 5 | -------------------------------------------------------------------------------- /docs/7.migration/_dir.yml: -------------------------------------------------------------------------------- 1 | titleTemplate: 'Migrate to Nuxt 3: %s' 2 | image: '/socials/guide.jpg' 3 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/app.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | fromLayer: true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/server/api/hello.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => 'Hello API') 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/alias/test.ts: -------------------------------------------------------------------------------- 1 | export const test = 'from layer alias' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/layout-switch/end.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /.github/assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/banner.png -------------------------------------------------------------------------------- /.github/assets/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/modules.png -------------------------------------------------------------------------------- /docs/3.api/6.configuration/_dir.yml: -------------------------------------------------------------------------------- 1 | navigation.icon: uil:wrench 2 | image: '/socials/configuration.jpg' 3 | -------------------------------------------------------------------------------- /packages/nuxt/src/core/runtime/nitro/config.ts: -------------------------------------------------------------------------------- 1 | export const defineAppConfig = (config: any) => config 2 | -------------------------------------------------------------------------------- /playground/server/api/test.ts: -------------------------------------------------------------------------------- 1 | export default eventHandler((_event) => { 2 | return 'Hello!' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/composables/foo.ts: -------------------------------------------------------------------------------- 1 | export const useExtendsFoo = () => 'foo' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/invalid-root.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/jsx.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.github/assets/examples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/examples.png -------------------------------------------------------------------------------- /.github/assets/questions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/questions.png -------------------------------------------------------------------------------- /docs/2.guide/1.concepts/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | redirect: /guide/concepts/auto-imports 4 | --- 5 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Utils" 3 | navigation: false 4 | redirect: /api/utils/ 5 | --- 6 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/layout.ts: -------------------------------------------------------------------------------- 1 | // TODO: remove in 4.x 2 | export { default } from './nuxt-layout' 3 | -------------------------------------------------------------------------------- /packages/webpack/src/configs/index.ts: -------------------------------------------------------------------------------- 1 | export { client } from './client' 2 | export { server } from './server' 3 | -------------------------------------------------------------------------------- /.github/assets/suggestions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/suggestions.png -------------------------------------------------------------------------------- /docs/2.guide/3.going-further/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | redirect: /guide/going-further/tooling 4 | --- 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/pages/page.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/NoState.client.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | modules: [undefined] 3 | }) 4 | -------------------------------------------------------------------------------- /.github/assets/documentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/documentation.png -------------------------------------------------------------------------------- /.github/assets/reporting-bugs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/.github/assets/reporting-bugs.png -------------------------------------------------------------------------------- /packages/schema/src/builder-env.ts: -------------------------------------------------------------------------------- 1 | import './types/builder-env' 2 | 3 | export const builders = ['vite', 'webpack'] 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/**" 3 | - "playground" 4 | - "test/fixtures/*" 5 | - ".website" 6 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/pages/param/[id].vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/.nuxtignore: -------------------------------------------------------------------------------- 1 | composables/ignored.* 2 | **/ignore/public-asset 3 | server/routes/ignore/scanned.ts 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/override-base.ts: -------------------------------------------------------------------------------- 1 | export const useOverrideableComposable = () => 'test from project' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/composables/base.ts: -------------------------------------------------------------------------------- 1 | export const useOverrideableComposable = () => 'test from layer' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/auto-registered/runtime/server/utils/some-utils.ts: -------------------------------------------------------------------------------- 1 | export const testUtils = 'test-utils' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/invalid-root/1.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/parent/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | redirect: /guide/directory-structure/nuxt 4 | --- 5 | -------------------------------------------------------------------------------- /docs/5.community/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | title: "Community" 4 | redirect: /community/getting-help 5 | --- 6 | -------------------------------------------------------------------------------- /packages/nuxt/config.js: -------------------------------------------------------------------------------- 1 | function defineNuxtConfig (config) { 2 | return config 3 | } 4 | 5 | export { defineNuxtConfig } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/template.ts: -------------------------------------------------------------------------------- 1 | export const templateAutoImport = 'auto imported from ~/composables/template.ts' 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/invalid-root/3.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/parent.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/invalid-plugin-2.ts: -------------------------------------------------------------------------------- 1 | export default function previousPlugin (one, inject) { 2 | inject() 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/utils/useBar.ts: -------------------------------------------------------------------------------- 1 | export default function () { 2 | return 'auto imported from ~/utils/useBar.ts' 3 | } 4 | -------------------------------------------------------------------------------- /packages/nuxt/src/pages/runtime/app.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/assets/global.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --global: 'global'; 3 | --asset: url('~/assets/css-only-asset.svg'); 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/foo.ts: -------------------------------------------------------------------------------- 1 | export function useFoo () { 2 | return 'auto imported from ~/composables/foo.ts' 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/this-should-not-load.spec.js: -------------------------------------------------------------------------------- 1 | throw new Error('this-should-not-load.spec.js should not be loaded') 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/hey/index.post.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | method: 'post' as const 3 | })) 4 | -------------------------------------------------------------------------------- /test/fixtures/minimal-types/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | experimental: { appManifest: true } 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log* 3 | .nuxt 4 | .nitro 5 | .cache 6 | .output 7 | .env 8 | dist 9 | -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | 3 | docs/0.index.md 4 | docs/1.getting-started/1.introduction.md 5 | docs/**/*.nuxt.config.md 6 | -------------------------------------------------------------------------------- /changelog.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": "nuxt/nuxt", 3 | "scopeMap": { 4 | "nuxt3": "nuxt", 5 | "nuxi": "cli" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/3.api/2.components/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Components" 3 | navigation: false 4 | redirect: /api/components/nuxt-page 5 | --- 6 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/_dir.yml: -------------------------------------------------------------------------------- 1 | titleTemplate: '%s · Nuxt Utils' 2 | navigation.icon: uil:adjust-circle 3 | image: '/socials/utils.jpg' 4 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/islands/Isle.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'bing' { 2 | interface BingInterface { 3 | foo: 'bar' 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/another-parent/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/extends.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/cookie.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | useCookie('set-in-plugin').value = 'true' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/counter.ts: -------------------------------------------------------------------------------- 1 | let counter = 0 2 | 3 | export default defineEventHandler(() => ({ count: counter++ })) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/hey/index.get.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | foo: 'bar', 3 | baz: 'qux' 4 | })) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/some-exports.ts: -------------------------------------------------------------------------------- 1 | export const importedValue = 'an imported value' 2 | export const importedRE = /an imported regex/ 3 | -------------------------------------------------------------------------------- /docs/1.getting-started/_dir.yml: -------------------------------------------------------------------------------- 1 | title: Get Started 2 | titleTemplate: '%s · Get Started with Nuxt' 3 | image: '/socials/get-started.jpg' 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'bing' { 2 | interface BingInterface { 3 | foo: 'bar' 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/layouts/custom.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/server/api/hey/index.get.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | foo: 'bar', 3 | baz: 'qux' 4 | })) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/server/api/hey/index.post.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | method: 'post' as const 3 | })) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/app.config.ts: -------------------------------------------------------------------------------- 1 | export default defineAppConfig({ 2 | userConfig: 123, 3 | nested: { 4 | val: 2 5 | } 6 | }) 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/route-rules/spa.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/routes/ignore/scanned.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => { 2 | return 'this should be ignored' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/routes/proxy.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(async () => { 2 | return await $fetch('/') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/nuxt/config.cjs: -------------------------------------------------------------------------------- 1 | function defineNuxtConfig (config) { 2 | return config 3 | } 4 | 5 | module.exports = { 6 | defineNuxtConfig 7 | } 8 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/global/Glob.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/some.island.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/app.config.ts: -------------------------------------------------------------------------------- 1 | export default defineAppConfig({ 2 | userConfig: 123, 3 | nested: { 4 | val: 2 5 | } 6 | }) 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/WithSuffix.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/components/ExtendsFoo.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/another-parent.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/Nuxt3.client.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/Nuxt3.server.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/parent-folder/index.server.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/some-glob.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/islands/RouteComponent.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/layouts/override.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/server/api/foo.ts: -------------------------------------------------------------------------------- 1 | import { eventHandler } from 'h3' 2 | 3 | export default eventHandler(() => 'foo') 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/auto-registered/runtime/handler.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => 'handler added by auto-registered module') 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/keyed-child-parent.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /.github/issue-up.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/antfu/issue-up 2 | upstream: 3 | nitro: unjs/nitro 4 | unimport: unjs/unimport 5 | untyped: unjs/untyped 6 | -------------------------------------------------------------------------------- /docs/3.api/2.components/_dir.yml: -------------------------------------------------------------------------------- 1 | navigation.icon: heroicons-outline:cube 2 | titleTemplate: '%s · Nuxt Components' 3 | image: '/socials/components.jpg' 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts: -------------------------------------------------------------------------------- 1 | import { eventHandler } from 'h3' 2 | 3 | export default eventHandler(() => 'foo') 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => 'handler added by auto-registered module') 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/global/TestGlobal.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/middleware/a.global.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware(() => { 2 | useNuxtApp().extendsMiddleware = true 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtConfig } from 'nuxt/config' 2 | 3 | export default defineNuxtConfig({}) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/other-composables-folder/custom-keyed-composable.ts: -------------------------------------------------------------------------------- 1 | export function useCustomKeyedComposable (arg?: string) { 2 | return arg 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/nuxt/main/test/fixtures/runtime-compiler/public/favicon.ico -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtConfig } from 'nuxt/config' 2 | 3 | export default defineNuxtConfig({}) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/GlobalSync.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/middleware/injectAuth.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.auth = 'Injected by injectAuth middleware' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/non-ascii/ç.vue: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /.website/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_Store 8 | coverage 9 | dist 10 | sw.* 11 | .env 12 | .output 13 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/middleware/named.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.auth = 'Injected by injectAuth middleware' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/FunctionalComponent.ts: -------------------------------------------------------------------------------- 1 | import '~/assets/functional.css' 2 | 3 | export default defineComponent({ 4 | render: () => 'hi' 5 | }) 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/nested/bar.ts: -------------------------------------------------------------------------------- 1 | export function useNestedBar () { 2 | return 'auto imported from ~/composables/nested/bar.ts via star export' 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/components/ExtendsOverride.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/components/ExtendsOverride.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/fixed-keyed-child-parent.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/2.guide/1.concepts/_dir.yml: -------------------------------------------------------------------------------- 1 | title: Key Concepts 2 | titleTemplate: '%s · Nuxt Concepts' 3 | navigation.icon: uil:award-alt 4 | image: '/socials/key-concepts.jpg' 5 | -------------------------------------------------------------------------------- /docs/2.guide/3.going-further/_dir.yml: -------------------------------------------------------------------------------- 1 | title: Going further 2 | titleTemplate: '%s · Nuxt Advanced' 3 | navigation.icon: uil:star 4 | image: '/socials/going-further.jpg' 5 | -------------------------------------------------------------------------------- /docs/3.api/1.composables/_dir.yml: -------------------------------------------------------------------------------- 1 | navigation.icon: heroicons-outline:switch-horizontal 2 | titleTemplate: '%s · Nuxt Composables' 3 | image: '/socials/composables.jpg' 4 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/compat/vue-demi.ts: -------------------------------------------------------------------------------- 1 | export * from './capi' 2 | 3 | export const Vue2 = undefined 4 | export const isVue2 = false 5 | export const isVue3 = true 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/layouts/override.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/random.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => { 2 | return new Array(10).fill(0).map(() => Math.round(Math.random() * 10000)) 3 | }) 4 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Nuxt 3 Examples 2 | 3 | - 👉 See examples in your browser at https://nuxt.com/docs/examples 4 | - 👉 View on GitHub at https://github.com/nuxt/examples 5 | -------------------------------------------------------------------------------- /packages/vite/src/runtime/client.manifest.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { viteNodeFetch } from './vite-node-shared.mjs' 3 | 4 | export default () => viteNodeFetch('/manifest') 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/global/ServerComponentGlobal.server.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/plugins/09.layer-plugin-pre.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | nuxtApp.provide('layerPluginPre', 'layer-plugin') 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/plugins/11.layer-plugin-post.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | nuxtApp.provide('layerPluginPost', 'layer-plugin') 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/app-config.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => { 2 | const appConfig = useAppConfig() 3 | return { 4 | appConfig 5 | } 6 | }) 7 | -------------------------------------------------------------------------------- /packages/nuxi/README.md: -------------------------------------------------------------------------------- 1 | # Nuxt CLI (nuxi) 2 | 3 | ⚡️ Next Generation CLI Experience for [Nuxt](https://nuxt.com/). 4 | 5 | - 👉 View on GitHub at https://github.com/nuxt/cli 6 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/index.ts: -------------------------------------------------------------------------------- 1 | // defineNuxtLink 2 | export { defineNuxtLink } from './nuxt-link' 3 | export type { NuxtLinkOptions, NuxtLinkProps } from './nuxt-link' 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/layouts/override.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/global/ClientGlobal.client.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/pages/override/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/runtime/plugin.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(async () => { 2 | await new Promise(resolve => setTimeout(resolve, 1)) 3 | useNuxtApp() 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/test/index.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtModule } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'test' 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/invalid-root/4.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /packages/kit/index.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | var __NUXT_PREPATHS__: string[] | string | undefined 3 | var __NUXT_PATHS__: string[] | string | undefined 4 | } 5 | 6 | export {} 7 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/same-name/same/Same.vue: -------------------------------------------------------------------------------- 1 | 6 | 8 | -------------------------------------------------------------------------------- /packages/test-utils/src/dirs.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { dirname } from 'pathe' 3 | 4 | export const distDir = dirname(fileURLToPath(import.meta.url)) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/runtime/plugin.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(async () => { 2 | await new Promise(resolve => setTimeout(resolve, 1)) 3 | useNuxtApp() 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/test/index.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtModule } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'test' 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/plugins/injection.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | return { 3 | provide: { 4 | pluginInjection: () => '' 5 | } 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/badSideEffect.ts: -------------------------------------------------------------------------------- 1 | export function badSideEffect () { 2 | // ... 3 | } 4 | 5 | throw new Error('composables/badSideEffect.ts should be tree-shaken') 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/middleware/override.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.override = 'This middleware should be overridden by bar' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/middleware/foo.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.foo = 'Injected by extended middleware from foo' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/union.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | type: 'a', 3 | foo: 'bar' 4 | }) as { type: 'a', foo: string } | { type: 'b', baz: string }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/middleware/override.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.override = 'Injected by extended middleware from bar' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.foo = 'Injected by extended middleware from foo' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/server/api/union.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => ({ 2 | type: 'a', 3 | foo: 'bar' 4 | }) as { type: 'a', foo: string } | { type: 'b', baz: string }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/random.ts: -------------------------------------------------------------------------------- 1 | export function useRandomState (max = 100, name = 'default') { 2 | return useState('random:' + name, () => Math.round(Math.random() * max)) 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/runtime/middleware.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware(async () => { 2 | await new Promise(resolve => setTimeout(resolve, 1)) 3 | useNuxtApp() 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/other-composables-folder/local.ts: -------------------------------------------------------------------------------- 1 | function useAsyncData (s?: any) { return s } 2 | 3 | export const ShouldNotBeKeyed = (() => { 4 | return useAsyncData() 5 | })() 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/plugins.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/prerender.server.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | // Pretend to be prerendered 3 | nuxtApp.payload.prerenderedAt = Date.now() 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/components/Helloworld.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/vite/src/utils/wpfs.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'pathe' 2 | import fse from 'fs-extra' 3 | 4 | export const wpfs = { 5 | ...fse, 6 | join 7 | } as typeof fse & { join: typeof join } 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/middleware/override.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.override = 'Injected by extended middleware from bar' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/runtime/middleware.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware(async () => { 2 | await new Promise(resolve => setTimeout(resolve, 1)) 3 | useNuxtApp() 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/middleware/sets-layout.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware(async () => { 2 | await new Promise(resolve => setTimeout(resolve, 10)) 3 | setPageLayout('custom') 4 | }) 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/auto-registered/runtime/some-server-import.ts: -------------------------------------------------------------------------------- 1 | export function serverAutoImported () { 2 | return 'serverAutoImported' 3 | } 4 | 5 | export const someUtils = 'utils' 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/other-components-folder/named-export.ts: -------------------------------------------------------------------------------- 1 | export const namedExport = defineComponent({ 2 | setup: () => () => h('div', 'This is a custom component with a named export.') 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/chunk-error.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | nuxtApp.hook('app:chunkError', () => { 3 | console.log('caught chunk load error') 4 | }) 5 | }) 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "vue.volar" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/_dir.yml: -------------------------------------------------------------------------------- 1 | title: Directory Structure 2 | titleTemplate: '%s · Nuxt Directory Structure' 3 | navigation.icon: uil:folder-open 4 | image: '/socials/directory-structure.jpg' 5 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | to.meta.override = 'This middleware should be overriden by bar' 3 | }) 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/app/router.options.ts: -------------------------------------------------------------------------------- 1 | import type { RouterOptions } from 'nuxt/schema' 2 | 3 | export default { 4 | linkExactActiveClass: 'bar-exact-active-class' 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to-api.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | github: [nuxt] 5 | open_collective: nuxtjs 6 | -------------------------------------------------------------------------------- /packages/kit/src/logger.ts: -------------------------------------------------------------------------------- 1 | import { consola } from 'consola' 2 | 3 | export const logger = consola 4 | 5 | export function useLogger (tag?: string) { 6 | return tag ? logger.withTag(tag) : logger 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/prefetch/server-components.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/url.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/prefetch/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/BreaksServer.client.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error assigning property to window object to break SSR 2 | window.test = true 3 | 4 | export default defineComponent({ 5 | render: () => 'hi' 6 | }) 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/plugins/foo.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | return { 3 | provide: { 4 | foo: () => 'String generated from foo plugin!' 5 | } 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | return { 3 | provide: { 4 | foo: () => 'String generated from foo plugin!' 5 | } 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/middleware/global.global.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | if ('abort' in to.query) { 3 | return abortNavigation({ 4 | statusCode: 401 5 | }) 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/auto-imports.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => { 2 | return { 3 | thisIs: autoimportedFunction(), 4 | autoImported: someUtils, 5 | fromServerDir: testUtils 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/redirect.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/middleware/abort.global.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | if ('abort' in to.query) { 3 | return abortNavigation({ 4 | statusCode: 401 5 | }) 6 | } 7 | return true 8 | }) 9 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/invalid-root/fine.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/prefetch/components.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "fixture-runtime-compiler", 4 | "scripts": { 5 | "build": "nuxi build" 6 | }, 7 | "dependencies": { 8 | "nuxt": "workspace:*" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/test-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './browser' 2 | export * from './context' 3 | export * from './mock' 4 | export * from './nuxt' 5 | export * from './server' 6 | export * from './setup' 7 | export * from './run' 8 | export * from './types' 9 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/with-props.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/with-dynamic-layout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/app/router.options.ts: -------------------------------------------------------------------------------- 1 | import type { RouterOptions } from '@nuxt/schema' 2 | 3 | export default { 4 | linkActiveClass: 'foo-active-class', 5 | linkExactActiveClass: 'foo-exact-active-class' 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/middleware/b.global.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware((to) => { 2 | if (to.path === '/middleware/ordering' && !useNuxtApp().extendsMiddleware) { 3 | return createError('extendsMiddleware not set in layer') 4 | } 5 | }) 6 | -------------------------------------------------------------------------------- /test/fixtures/minimal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "fixture-minimal", 4 | "scripts": { 5 | "build": "nuxi build" 6 | }, 7 | "dependencies": { 8 | "nuxt": "workspace:*", 9 | "vue": "latest" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/5.community/7.changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: false 3 | navigation.icon: heroicons-outline:newspaper 4 | description: Discover the latest Nuxt 3 updates. 5 | --- 6 | 7 | # Releases 8 | 9 | Discover the latest Nuxt updates. 10 | 11 | ::releases 12 | :: 13 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/server-placeholder.ts: -------------------------------------------------------------------------------- 1 | import { createElementBlock, defineComponent } from 'vue' 2 | 3 | export default defineComponent({ 4 | name: 'ServerPlaceholder', 5 | render () { 6 | return createElementBlock('div') 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /packages/nuxt/test/utils.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | 3 | export const fixtureDir = resolve(__dirname, 'fixture') 4 | 5 | export function normalizeLineEndings (str: string, normalized = '\n') { 6 | return str.replace(/\r?\n/g, normalized) 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/nuxt.schema.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtSchema({ 2 | appConfig: { 3 | /** 4 | * This is an example app config defined in custom schema 5 | * @type {123 | 456} 6 | */ 7 | userConfig: 123 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/pages/override.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/no-scripts.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/with-computed-layout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/nuxt/test/fixture/components/client/ComponentWithProps.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/assets/css-only-asset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/BreakInSetup.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/Tsx.tsx: -------------------------------------------------------------------------------- 1 | export default defineComponent({ 2 | render () { 3 | return
4 | TSX component 5 | custom 6 | 7 |
8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/clientFallback/NonStatefulSetup.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/auth.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/very-long-request.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(async () => { 2 | await timeout(20) 3 | return 'that was very long ...' 4 | }) 5 | function timeout (ms: number) { 6 | return new Promise(resolve => setTimeout(resolve, ms)) 7 | } 8 | -------------------------------------------------------------------------------- /packages/vite/src/dirs.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { dirname } from 'pathe' 3 | 4 | let _distDir = dirname(fileURLToPath(import.meta.url)) 5 | if (_distDir.match(/(chunks|shared)$/)) { _distDir = dirname(_distDir) } 6 | export const distDir = _distDir 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/ignore/composables.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /playground/app.vue: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/instance/error.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/context-error.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | // this should be undefined 3 | const vueApp = getCurrentInstance() 4 | return { 5 | provide: { 6 | wasVueAppInstanceWronglyPreserved: !!vueApp 7 | } 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/asyncDataTests.ts: -------------------------------------------------------------------------------- 1 | export const useSleep = () => useAsyncData('sleep', async () => { 2 | await new Promise(resolve => setTimeout(resolve, 50)) 3 | 4 | return 'Slept!' 5 | }) 6 | 7 | export const useCounter = () => useFetch('/api/useAsyncData/count') 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/server/middleware/foo.ts: -------------------------------------------------------------------------------- 1 | // TODO: add back TypeScript and auto-importing once Nitro supports it 2 | import { eventHandler } from 'h3' 3 | 4 | export default eventHandler((event) => { 5 | event.res.setHeader('injected-header', 'foo') 6 | }) 7 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/Binding.client.ts: -------------------------------------------------------------------------------- 1 | export default defineComponent({ 2 | name: 'Foo', 3 | methods: { 4 | getMessage () { 5 | return 'Hello world' 6 | } 7 | }, 8 | render () { 9 | return h('div', {}, this.getMessage()) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/route-rules/inline.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/async-context.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/legacy/async-data/index/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/api/useAsyncData/count.ts: -------------------------------------------------------------------------------- 1 | let counter = 0 2 | 3 | const test = () => () => { 4 | // TODO: useNuxtApp should be undefined when type-testing a nitro route 5 | useNuxtApp() 6 | } 7 | test() 8 | 9 | export default defineEventHandler(() => ({ count: counter++ })) 10 | -------------------------------------------------------------------------------- /playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-playground", 3 | "private": true, 4 | "scripts": { 5 | "dev": "nuxi dev", 6 | "build": "nuxi build", 7 | "start": "nuxi preview" 8 | }, 9 | "dependencies": { 10 | "nuxt": "workspace:*", 11 | "vue": "latest" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/layout-switch/start.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/no-auth.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /.github/assets/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/legacy-async-data-fail.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/Nested/SugarCounter.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/app-config.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/hydration/spa-redirection/end.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/with-layout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/server/api/template.get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * mock the behavior of nuxt retrieving data from an api 3 | */ 4 | 5 | export default defineEventHandler(() => { 6 | return '
Hello my name is : {{name}}, i am defined by ShowTemplate.vue and my template is retrieved from the API
' 7 | }) 8 | -------------------------------------------------------------------------------- /packages/nuxt/src/core/runtime/nitro/no-ssr.ts: -------------------------------------------------------------------------------- 1 | import { defineEventHandler, getRequestHeader } from 'h3' 2 | 3 | export default defineEventHandler((event) => { 4 | if (getRequestHeader(event, 'x-nuxt-no-ssr')) { 5 | event.context.nuxt = event.context.nuxt || {} 6 | event.context.nuxt.noSSR = true 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/pages/custom-name.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/ClientOnlySetupScript.client.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/hydration/spa-redirection/start.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/plugins/debug.ts: -------------------------------------------------------------------------------- 1 | import { createDebugger } from 'hookable' 2 | import { defineNuxtPlugin } from '#app/nuxt' 3 | 4 | export default defineNuxtPlugin({ 5 | name: 'nuxt:debug', 6 | enforce: 'pre', 7 | setup (nuxtApp) { 8 | createDebugger(nuxtApp.hooks, { tag: 'nuxt-app' }) 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/my-plugin.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | useHead({ 3 | titleTemplate: '%s - Fixture' 4 | }) 5 | const path = useRoute()?.path 6 | return { 7 | provide: { 8 | myPlugin: () => 'Injected by my-plugin', 9 | path: () => path 10 | } 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/dev-only.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | 3 | export default defineComponent({ 4 | name: 'DevOnly', 5 | setup (_, props) { 6 | if (import.meta.dev) { 7 | return () => props.slots.default?.() 8 | } 9 | return () => props.slots.fallback?.() 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/StringChildStateful.client.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/server-only.server.ts: -------------------------------------------------------------------------------- 1 | import { setHeader } from 'h3' 2 | 3 | export default defineNuxtPlugin({ 4 | name: 'server-only-plugin', 5 | setup () { 6 | const evt = useRequestEvent() 7 | setHeader(evt, 'custom-head', 'hello') 8 | }, 9 | env: { 10 | islands: false 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /test/fixtures/minimal-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "fixture-minimal-types", 4 | "scripts": { 5 | "build": "nuxi build", 6 | "test:types": "nuxi prepare && npx vue-tsc --noEmit" 7 | }, 8 | "dependencies": { 9 | "nuxt": "workspace:*", 10 | "vue": "latest" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation: false 3 | --- 4 | 5 | # Nuxt Docs 6 | 7 | This repository contains the documentation of Nuxt hosted on nuxt.com. 8 | 9 | ## Contributing 10 | 11 | You can contribute directly on GitHub for now, we are planning to open source nuxt.com repo for everyone to contribute with ease very soon. 12 | -------------------------------------------------------------------------------- /packages/nuxt/src/dirs.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { dirname, resolve } from 'pathe' 3 | 4 | let _distDir = dirname(fileURLToPath(import.meta.url)) 5 | if (_distDir.match(/(chunks|shared)$/)) { _distDir = dirname(_distDir) } 6 | export const distDir = _distDir 7 | export const pkgDir = resolve(distDir, '..') 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/style.ts: -------------------------------------------------------------------------------- 1 | import '~/assets/plugin.css' 2 | 3 | export class OnMountedMethod { 4 | public onMounted () { 5 | console.log('public onMounted') 6 | } 7 | 8 | onBeforeMount () { 9 | console.log('onBeforeMount') 10 | } 11 | } 12 | export default defineNuxtPlugin(() => { 13 | // 14 | }) 15 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | experimental: { 4 | externalVue: false 5 | }, 6 | vue: { 7 | runtimeCompiler: true 8 | }, 9 | builder: process.env.TEST_BUILDER as 'webpack' | 'vite' ?? 'vite' 10 | }) 11 | -------------------------------------------------------------------------------- /packages/test-utils/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | declaration: true, 5 | entries: [ 6 | 'src/index', 7 | 'src/experimental', 8 | { input: 'src/runtime/', outDir: 'dist/runtime', format: 'esm' } 9 | ], 10 | externals: [ 11 | ] 12 | }) 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/ServerOnlyComponent.server.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/with-layout2.vue: -------------------------------------------------------------------------------- 1 | 10 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/legacy/async-data/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/ComponentWithRef.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/clientFallback/StatefulSetup.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/custom-async.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | -------------------------------------------------------------------------------- /.website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docus-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt dev", 7 | "build": "nuxt build", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview" 10 | }, 11 | "devDependencies": { 12 | "@nuxt-themes/docus": "1.15.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/kit/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | declaration: true, 5 | entries: [ 6 | 'src/index' 7 | ], 8 | externals: [ 9 | '@nuxt/schema', 10 | 'nitropack', 11 | 'webpack', 12 | 'vite', 13 | 'h3' 14 | ], 15 | failOnWarn: false 16 | }) 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/error.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/internal-layout.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /packages/nuxt/config.d.ts: -------------------------------------------------------------------------------- 1 | import type { NuxtConfig } from 'nuxt/schema' 2 | import type { DefineConfig, InputConfig, UserInputConfig, ConfigLayerMeta } from 'c12' 3 | export { NuxtConfig } from 'nuxt/schema' 4 | 5 | export interface DefineNuxtConfig extends DefineConfig {} 6 | export declare const defineNuxtConfig: DefineNuxtConfig 7 | -------------------------------------------------------------------------------- /.website/app.config.ts: -------------------------------------------------------------------------------- 1 | export default defineAppConfig({ 2 | docus: { 3 | title: 'Nuxt Docs [dev]', 4 | description: 'The best place to start your documentation.', 5 | socials: { 6 | twitter: 'nuxt_js', 7 | github: 'nuxt/nuxt' 8 | }, 9 | aside: { 10 | level: 1, 11 | collapsed: false, 12 | }, 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /docs/3.api/1.composables/use-app-config.md: -------------------------------------------------------------------------------- 1 | # `useAppConfig` 2 | 3 | Access the reactive [app config](/docs/guide/directory-structure/app-config) defined in the project. 4 | 5 | **Usage:** 6 | 7 | ```js 8 | const appConfig = useAppConfig() 9 | 10 | console.log(appConfig) 11 | ``` 12 | 13 | ::ReadMore{link="/docs/guide/directory-structure/app-config"} 14 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/entry.async.ts: -------------------------------------------------------------------------------- 1 | import type { CreateOptions } from '#app' 2 | 3 | const entry = import.meta.server 4 | ? (ctx?: CreateOptions['ssrContext']) => import('#app/entry').then(m => m.default(ctx)) 5 | : () => import('#app/entry').then(m => m.default) 6 | 7 | if (import.meta.client) { 8 | entry() 9 | } 10 | 11 | export default entry 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/async-parent.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/async-parent/child.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/layouts/with-props.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/custom-type-registration.ts: -------------------------------------------------------------------------------- 1 | export default definePayloadPlugin((nuxtApp) => { 2 | definePayloadReducer('BlinkingText', data => data === '' && '_') 3 | definePayloadReviver('BlinkingText', () => '') 4 | if (import.meta.server) { 5 | nuxtApp.payload.blinkable = '' 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/register.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent, h } from 'vue' 2 | 3 | const Spin = defineComponent({ 4 | setup (props, { slots }) { 5 | return () => { 6 | return h('div', slots.default?.()) 7 | } 8 | } 9 | }) 10 | 11 | export default defineNuxtPlugin((nuxtApp) => { 12 | nuxtApp.vueApp.component('Spin', Spin) 13 | }) 14 | -------------------------------------------------------------------------------- /.stackblitz/codeflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "pnpm": { 3 | "overrides": { 4 | "@nuxt/kit": "./packages/kit", 5 | "@nuxt/schema": "./packages/schema", 6 | "@nuxt/test-utils": "./packages/test-utils", 7 | "@nuxt/vite": "./packages/vite", 8 | "@nuxt/webpack": "./packages/webpack", 9 | "nuxt": "./packages/nuxt" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/tree-shake.vue: -------------------------------------------------------------------------------- 1 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/custom-type-assertion.client.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | if (nuxtApp.payload.serverRendered && nuxtApp.payload.blinkable !== '' && document.querySelector('#__NUXT_DATA__')) { 3 | throw createError({ 4 | message: 'Custom type in Nuxt payload was not revived correctly' 5 | }) 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /packages/vite/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | declaration: true, 5 | entries: [ 6 | 'src/index', 7 | { input: 'src/runtime/', outDir: 'dist/runtime', format: 'esm' } 8 | ], 9 | dependencies: [ 10 | 'vue' 11 | ], 12 | externals: [ 13 | '@nuxt/schema' 14 | ] 15 | }) 16 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/bar/pages/override.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /packages/kit/src/loader/schema.ts: -------------------------------------------------------------------------------- 1 | import type { SchemaDefinition } from '@nuxt/schema' 2 | import { useNuxt } from '../context' 3 | 4 | export function extendNuxtSchema (def: SchemaDefinition | (() => SchemaDefinition)) { 5 | const nuxt = useNuxt() 6 | nuxt.hook('schema:extend', (schemas) => { 7 | schemas.push(typeof def === 'function' ? def() : def) 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/clientFallback/NonStateful.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/middleware-abort-non-fatal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/server-components/lazy/start.vue: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "fixture-basic", 4 | "scripts": { 5 | "build": "nuxi build" 6 | }, 7 | "dependencies": { 8 | "@nuxt/webpack-builder": "workspace:*", 9 | "nuxt": "workspace:*" 10 | }, 11 | "devDependencies": { 12 | "ufo": "latest", 13 | "unplugin": "latest", 14 | "vue": "latest" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/MultiRootNode.client.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/bar/pages/override.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/wrapper-expose/page/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /packages/nuxt/src/core/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './names' 2 | export * from './plugins' 3 | 4 | export function uniqueBy (arr: T[], key: K) { 5 | const res: T[] = [] 6 | const seen = new Set() 7 | for (const item of arr) { 8 | if (seen.has(item[key])) { continue } 9 | seen.add(item[key]) 10 | res.push(item) 11 | } 12 | return res 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/client-only-explicit-import.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/sync-[parent].vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/functional.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtModule } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule( 4 | function (_, nuxt) { 5 | nuxt.options.optimization.treeShake.composables.server[nuxt.options.rootDir] = ['useClientOnlyComposable', 'setTitleToPink'] 6 | nuxt.options.optimization.treeShake.composables.client[nuxt.options.rootDir] = ['useServerOnlyComposable'] 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/wrapper-expose/page/another.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 22 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/components/Name.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtComponent({ 2 | props: ['template', 'name'], 3 | 4 | /** 5 | * most of the time, vue compiler need at least a VNode, use h() to render the component 6 | */ 7 | render () { 8 | return h({ 9 | props: ['name'], 10 | template: this.template 11 | }, { 12 | name: this.name 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /packages/nuxt/src/core/utils/names.ts: -------------------------------------------------------------------------------- 1 | import { basename, extname } from 'pathe' 2 | import { kebabCase } from 'scule' 3 | 4 | export function getNameFromPath (path: string) { 5 | return kebabCase(basename(path).replace(extname(path), '')).replace(/["']/g, '') 6 | } 7 | 8 | export function hasSuffix (path: string, suffix: string) { 9 | return basename(path).replace(extname(path), '').endsWith(suffix) 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/useAsyncData/single.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/ClientWrapped.client.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/runtime/page.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/sync-[parent]/sync-[child].vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/async-[parent]/sync-[child].vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /.markdownlint.yml: -------------------------------------------------------------------------------- 1 | # Default state for all rules 2 | default: true 3 | # Disable max line length 4 | MD013: false 5 | # Allow duplicated heading for different sections 6 | MD024: 7 | allow_different_nesting: true 8 | siblings_only: true 9 | # Allow multiple top-level headings 10 | MD025: false 11 | # Allow inline HTML 12 | MD033: false 13 | # Allow non blank lines around list 14 | MD032: false 15 | MD046: 16 | style: fenced 17 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/runtime/page.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/10.layer-ordering.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | if (useRoute().path === '/plugins/ordering') { 3 | if (!nuxtApp.$layerPluginPre) { 4 | throw createError('layer plugin failed to run before end project plugin') 5 | } 6 | if (!nuxtApp.$layerPluginPost) { 7 | throw createError('layer plugin failed to run before end project plugin') 8 | } 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/middleware/manifest-route-rule.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtRouteMiddleware } from '#app/composables/router' 2 | import { getRouteRules } from '#app/composables/manifest' 3 | 4 | export default defineNuxtRouteMiddleware(async (to) => { 5 | if (import.meta.server || import.meta.test) { return } 6 | const rules = await getRouteRules(to.path) 7 | if (rules.redirect) { 8 | return rules.redirect 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/3.package.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconFile 3 | title: package.json 4 | head.title: package.json 5 | description: The package.json file contains all the dependencies and scripts for your application. 6 | --- 7 | 8 | # Package.json File 9 | 10 | The `package.json` file contains all the dependencies and scripts for your application ([learn more](https://docs.npmjs.com/cli/configuring-npm/package-json)). 11 | -------------------------------------------------------------------------------- /packages/test-utils/src/mock.ts: -------------------------------------------------------------------------------- 1 | import { consola } from 'consola' 2 | import { useTestContext } from './context' 3 | 4 | export function mockFn () { 5 | const ctx = useTestContext() 6 | return ctx.mockFn 7 | } 8 | 9 | export function mockLogger (): Record { 10 | const mocks: any = {} 11 | consola.mockTypes((type) => { 12 | mocks[type] = mockFn() 13 | return mocks[type] 14 | }) 15 | return mocks 16 | } 17 | -------------------------------------------------------------------------------- /packages/test-utils/src/setup/vitest.ts: -------------------------------------------------------------------------------- 1 | import type { TestHooks } from '../types' 2 | 3 | export default async function setupVitest (hooks: TestHooks) { 4 | const vitest = await import('vitest') 5 | 6 | hooks.ctx.mockFn = vitest.vi.fn 7 | 8 | vitest.beforeAll(hooks.setup, hooks.ctx.options.setupTimeout) 9 | vitest.beforeEach(hooks.beforeEach) 10 | vitest.afterEach(hooks.afterEach) 11 | vitest.afterAll(hooks.afterAll) 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "fixture-basic-types", 4 | "scripts": { 5 | "build": "nuxi build", 6 | "test:types": "nuxi prepare && npx vue-tsc --noEmit" 7 | }, 8 | "dependencies": { 9 | "nuxt": "workspace:*" 10 | }, 11 | "devDependencies": { 12 | "ofetch": "latest", 13 | "vitest": "0.33.0", 14 | "vue-router": "latest", 15 | "vue": "latest" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/StringChildStatefulScript.client.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/composables/asyncContext.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error withAsyncContext is internal API 2 | import { getCurrentInstance, withAsyncContext as withVueAsyncContext } from 'vue' 3 | 4 | export function withAsyncContext (fn: () => PromiseLike) { 5 | return withVueAsyncContext(() => { 6 | const nuxtApp = getCurrentInstance()?.appContext.app.$nuxt 7 | return nuxtApp ? nuxtApp.runWithContext(fn) : fn() 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /packages/schema/src/index.ts: -------------------------------------------------------------------------------- 1 | // Types 2 | export * from './types/compatibility' 3 | export * from './types/components' 4 | export * from './types/config' 5 | export * from './types/hooks' 6 | export * from './types/imports' 7 | export * from './types/head' 8 | export * from './types/module' 9 | export * from './types/nuxt' 10 | export * from './types/router' 11 | 12 | // Schema 13 | export { default as NuxtConfigSchema } from './config/index' 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/styles.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | 13 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts 2 | 3 | RUN apt-get update && \ 4 | apt-get install -fy libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdbus-1-3 libdrm2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 && \ 5 | apt-get clean autoclean && \ 6 | apt-get autoremove --yes && \ 7 | rm -rf /var/lib/{apt,dpkg,cache,log} 8 | 9 | RUN corepack enable && npx playwright install 10 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/index.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export * from './nuxt' 4 | export * from './composables/index' 5 | export * from './components/index' 6 | export * from './config' 7 | export * from './compat/idle-callback' 8 | 9 | // eslint-disable-next-line import/no-restricted-paths 10 | export type { PageMeta } from '../pages/runtime/index' 11 | 12 | export const isVue2 = false 13 | export const isVue3 = true 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/async-context.ts: -------------------------------------------------------------------------------- 1 | const delay = () => new Promise(resolve => setTimeout(resolve, 10)) 2 | 3 | export async function nestedAsyncComposable () { 4 | await delay() 5 | return await fn1() 6 | } 7 | 8 | async function fn1 () { 9 | await delay() 10 | return await fn2() 11 | } 12 | 13 | async function fn2 () { 14 | await delay() 15 | const app = useNuxtApp() 16 | return { 17 | hasApp: !!app 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/instance/next-request.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /packages/nuxt/index.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | var __NUXT_VERSION__: string 3 | var __NUXT_PREPATHS__: string[] | string | undefined 4 | var __NUXT_PATHS__: string[] | string | undefined 5 | 6 | interface Navigator { 7 | connection?: { 8 | type: 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown' 9 | effectiveType: 'slow-2g' | '2g' | '3g' | '4g' 10 | } 11 | } 12 | } 13 | 14 | export {} 15 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/injections.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from 'vue' 2 | import type { RouteLocationNormalizedLoaded } from 'vue-router' 3 | 4 | export interface LayoutMeta { 5 | isCurrent: (route: RouteLocationNormalizedLoaded) => boolean 6 | } 7 | 8 | export const LayoutMetaSymbol: InjectionKey = Symbol('layout-meta') 9 | 10 | export const PageRouteSymbol: InjectionKey = Symbol('route') 11 | -------------------------------------------------------------------------------- /packages/test-utils/src/setup/jest.ts: -------------------------------------------------------------------------------- 1 | import type { TestHooks } from '../types' 2 | 3 | export default async function setupJest (hooks: TestHooks) { 4 | const { jest, test, beforeEach, afterAll, afterEach } = await import('@jest/globals') 5 | 6 | hooks.ctx.mockFn = jest.fn 7 | 8 | test('setup', hooks.setup, hooks.ctx.options.setupTimeout) 9 | beforeEach(hooks.beforeEach) 10 | afterEach(hooks.afterEach) 11 | afterAll(hooks.afterAll) 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/AsyncServerComponent.server.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to-external.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | -------------------------------------------------------------------------------- /.github/workflows/reproduire.yml: -------------------------------------------------------------------------------- 1 | name: Reproduire 2 | on: 3 | issues: 4 | types: [labeled] 5 | 6 | permissions: 7 | issues: write 8 | 9 | jobs: 10 | reproduire: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 14 | - uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp 15 | with: 16 | label: needs reproduction 17 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: | 3 | npx pnpm install 4 | npx pnpm build:stub 5 | command: npx pnpm play 6 | 7 | ports: 8 | - port: 3000 9 | onOpen: open-preview 10 | visibility: public 11 | 12 | github: 13 | prebuilds: 14 | master: true 15 | branches: true 16 | pullRequests: true 17 | pullRequestsFromForks: true 18 | addCheck: true 19 | addComment: false 20 | addBadge: true 21 | addLabel: true 22 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/SugarCounter.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/on-before-route-leave.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "onBeforeRouteLeave" 3 | description: The onBeforeRouteLeave composable allows registering a route guard within a component. 4 | --- 5 | 6 | # `onBeforeRouteLeave` 7 | 8 | The `onBeforeRouteLeave` composable adds a navigation guard that triggers whenever the component for the current location is about to be left. 9 | 10 | ::ReadMore{link="https://router.vuejs.org/api/#Functions-onBeforeRouteLeave"} 11 | :: 12 | -------------------------------------------------------------------------------- /docs/3.api/6.configuration/nuxt-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Nuxt Config 3 | head.title: Nuxt Configuration Reference 4 | --- 5 | 6 | # Nuxt Configuration Reference 7 | 8 | Discover all the options you can use in your [nuxt.config.ts](/docs/guide/directory-structure/nuxt.config) file. 9 | 10 | ::alert 11 | This file is auto-generated from the [source code](https://github.com/nuxt/nuxt/tree/main/packages/schema/src/config). 12 | :: 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/nested/[foo].vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/on-before-route-update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "onBeforeRouteUpdate" 3 | description: The onBeforeRouteUpdate composable allows registering a route guard within a component. 4 | --- 5 | 6 | # `onBeforeRouteUpdate` 7 | 8 | The `onBeforeRouteUpdate` composable adds a navigation guard that triggers whenever the component for the current location is about to be updated. 9 | 10 | ::ReadMore{link="https://router.vuejs.org/api/#Functions-onBeforeRouteUpdate"} 11 | :: 12 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/composables/url.ts: -------------------------------------------------------------------------------- 1 | import { getRequestURL } from 'h3' 2 | import { joinURL } from 'ufo' 3 | import { useRequestEvent } from './ssr' 4 | import { useRuntimeConfig } from '#app' 5 | 6 | export function useRequestURL () { 7 | if (import.meta.server) { 8 | const url = getRequestURL(useRequestEvent()) 9 | url.pathname = joinURL(useRuntimeConfig().app.baseURL, url.pathname) 10 | return url 11 | } 12 | return new URL(window.location.href) 13 | } 14 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/plugins/preload.server.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin } from '#app/nuxt' 2 | 3 | export default defineNuxtPlugin({ 4 | name: 'nuxt:webpack-preload', 5 | setup (nuxtApp) { 6 | nuxtApp.vueApp.mixin({ 7 | beforeCreate () { 8 | const { _registeredComponents } = this.$nuxt.ssrContext 9 | const { __moduleIdentifier } = this.$options 10 | _registeredComponents.add(__moduleIdentifier) 11 | } 12 | }) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/auto-registered/index.ts: -------------------------------------------------------------------------------- 1 | import { addServerHandler, createResolver, defineNuxtModule } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'auto-registered-module' 6 | }, 7 | setup () { 8 | const resolver = createResolver(import.meta.url) 9 | 10 | addServerHandler({ 11 | handler: resolver.resolve('./runtime/handler'), 12 | route: '/auto-registered-module' 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/middleware-abort.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/composables/ready.ts: -------------------------------------------------------------------------------- 1 | import { useNuxtApp } from '../nuxt' 2 | import { requestIdleCallback } from '../compat/idle-callback' 3 | 4 | export const onNuxtReady = (callback: () => any) => { 5 | if (import.meta.server) { return } 6 | 7 | const nuxtApp = useNuxtApp() 8 | if (nuxtApp.isHydrating) { 9 | nuxtApp.hooks.hookOnce('app:suspense:resolve', () => { requestIdleCallback(callback) }) 10 | } else { 11 | requestIdleCallback(callback) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/clientFallback/Stateful.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/custom2.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /packages/nuxt/src/pages/runtime/page-placeholder.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | // @ts-expect-error virtual file 3 | import { devPagesDir } from '#build/nuxt.config.mjs' 4 | 5 | export default defineComponent({ 6 | name: 'NuxtPage', 7 | setup (_, props) { 8 | if (import.meta.dev) { 9 | console.warn(`Create a Vue component in the \`${devPagesDir}/\` directory to enable \`\``) 10 | } 11 | return () => props.slots.default?.() 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/layouts/custom.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/legacy/async-data.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | -------------------------------------------------------------------------------- /packages/nuxt/src/head/runtime/plugins/vueuse-head-polyfill.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error ts failing with type 2 | import { polyfillAsVueUseHead } from '@unhead/vue/polyfill' 3 | import { defineNuxtPlugin } from '#app/nuxt' 4 | 5 | export default defineNuxtPlugin({ 6 | name: 'nuxt:vueuse-head-polyfill', 7 | setup (nuxtApp) { 8 | // avoid breaking ecosystem dependencies using low-level @vueuse/head APIs 9 | polyfillAsVueUseHead(nuxtApp.vueApp._context.provides.usehead) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/hydration/layout.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to-forbidden.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/fixed-keyed-child-parent/[foo].vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to-error.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /test/fixtures/minimal/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | 3 | const testWithInlineVue = process.env.EXTERNAL_VUE === 'false' 4 | 5 | export default defineNuxtConfig({ 6 | experimental: { 7 | externalVue: !testWithInlineVue 8 | }, 9 | buildDir: testWithInlineVue ? '.nuxt-inline' : '.nuxt', 10 | nitro: { 11 | output: { dir: fileURLToPath(new URL(testWithInlineVue ? './.output-inline' : './.output', import.meta.url)) } 12 | }, 13 | sourcemap: false 14 | }) 15 | -------------------------------------------------------------------------------- /.website/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { createResolver } from 'nuxt/kit' 2 | 3 | const { resolve } = createResolver(import.meta.url) 4 | 5 | export default defineNuxtConfig({ 6 | // https://github.com/nuxt-themes/docus 7 | extends: '@nuxt-themes/docus', 8 | content: { 9 | sources: { 10 | docs: { 11 | driver: 'fs', 12 | prefix: '/', 13 | base: resolve('../docs') 14 | } 15 | } 16 | }, 17 | experimental: { 18 | renderJsonPayloads: false 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /packages/schema/src/types/builder-env/index.ts: -------------------------------------------------------------------------------- 1 | import type { ViteImportMeta } from './vite' 2 | import type { WebpackImportMeta } from './webpack' 3 | 4 | export type BundlerImportMeta = ViteImportMeta & WebpackImportMeta 5 | 6 | declare global { 7 | interface ImportMeta extends BundlerImportMeta { 8 | /** the `file:` url of the current file (similar to `__filename` but as file url) */ 9 | url: string 10 | 11 | readonly env: Record 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/keyed-child-parent/[foo].vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/add-route.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((_nuxtApp) => { 2 | const router = useRouter() 3 | 4 | router.beforeEach((to) => { 5 | if (to.path !== '/add-route-test') { return } 6 | if (router.getRoutes().some(route => route.path === to.path)) { 7 | return 8 | } 9 | 10 | router.addRoute({ 11 | path: to.path, 12 | name: to.path, 13 | component: () => import('~/pages/index.vue') 14 | }) 15 | 16 | return to.path 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/server/plugins/headers.ts: -------------------------------------------------------------------------------- 1 | export default defineNitroPlugin((nitroApp) => { 2 | if (!import.meta.dev) { return } 3 | 4 | const onError = nitroApp.h3App.options.onError! 5 | nitroApp.h3App.options.onError = (error, event) => { 6 | // TODO: somehow add error logging assertion to @nuxt/test-utils 7 | if (error.message?.includes('Cannot set headers after they are sent to the client')) { 8 | process.exit(1) 9 | } 10 | return onError(error, event) 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/update-app-config.md: -------------------------------------------------------------------------------- 1 | # `updateAppConfig` 2 | 3 | Updates [app config](/docs/guide/directory-structure/app-config) using deep assignment. Existing (nested) properties will be preserved. 4 | 5 | **Usage:** 6 | 7 | ```js 8 | const appConfig = useAppConfig() // { foo: 'bar' } 9 | 10 | const newAppConfig = { foo: 'baz' } 11 | 12 | updateAppConfig(newAppConfig) 13 | 14 | console.log(appConfig) // { foo: 'baz' } 15 | ``` 16 | 17 | ::ReadMore{link="/docs/guide/directory-structure/app-config"} 18 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/upgrade.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "nuxi upgrade" 3 | description: The upgrade command upgrades Nuxt 3 to the latest version. 4 | --- 5 | 6 | # `nuxi upgrade` 7 | 8 | ```{bash} 9 | npx nuxi upgrade [--force|-f] 10 | ``` 11 | 12 | The `upgrade` command upgrades Nuxt 3 to the latest version. 13 | 14 | Option | Default | Description 15 | -------------------------|-----------------|------------------ 16 | `--force, -f` | `false` | Removes `node_modules` and lock files before upgrade. 17 | -------------------------------------------------------------------------------- /packages/webpack/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | declaration: true, 5 | entries: [ 6 | 'src/index' 7 | ], 8 | dependencies: [ 9 | '@nuxt/kit', 10 | 'unplugin', 11 | 'webpack-virtual-modules', 12 | 'postcss', 13 | 'postcss-loader', 14 | 'vue-loader', 15 | 'css-loader', 16 | 'file-loader', 17 | 'url-loader', 18 | 'vue' 19 | ], 20 | externals: [ 21 | '@nuxt/schema' 22 | ] 23 | }) 24 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/MultiRootNodeScript.client.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/info.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "nuxi info" 3 | description: The info command logs information about the current or specified Nuxt project. 4 | --- 5 | 6 | # `nuxi info` 7 | 8 | ```{bash} 9 | npx nuxi info [rootDir] 10 | ``` 11 | 12 | The `info` command logs information about the current or specified Nuxt project. 13 | 14 | Option | Default | Description 15 | -------------------------|-----------------|------------------ 16 | `rootDir` | `.` | The directory of the target application. 17 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/wrapper-expose/page.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/clear-nuxt-state.md: -------------------------------------------------------------------------------- 1 | # `clearNuxtState` 2 | 3 | Delete cached state of `useState`. 4 | 5 | This method is useful if you want to invalidate the state of `useState`. 6 | 7 | ## Type 8 | 9 | ```ts 10 | clearNuxtState (keys?: string | string[] | ((key: string) => boolean)): void 11 | ``` 12 | 13 | ## Parameters 14 | 15 | * `keys`: One or an array of keys that are used in [`useState`](/docs/api/composables/use-state) to delete their cached state. If no keys are provided, **all state** will be invalidated. 16 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/navigate-to-redirect.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: 📚 Nuxt 3 Documentation 4 | url: https://nuxt.com/docs/ 5 | about: Check the documentation for usage of Nuxt 3 6 | - name: 📚 Nuxt 2 Documentation 7 | url: https://v2.nuxt.com/ 8 | about: Check the documentation for usage of Nuxt 2 9 | - name: 💬 Discussions 10 | url: https://github.com/nuxt/nuxt/discussions 11 | about: Use discussions if you have another issue, an idea for improvement or for asking questions. 12 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/error.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 20 | -------------------------------------------------------------------------------- /vitest.nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineVitestConfig } from 'nuxt-vitest/config' 2 | 3 | export default defineVitestConfig({ 4 | // TODO: investigate 5 | define: { 6 | 'import.meta.test': true 7 | }, 8 | test: { 9 | dir: './test/nuxt', 10 | environment: 'nuxt', 11 | environmentOptions: { 12 | nuxt: { 13 | overrides: { 14 | appConfig: { 15 | nuxt: { 16 | buildId: 'override' 17 | } 18 | } 19 | } 20 | } 21 | } 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /test/fixtures/basic/extends/node_modules/foo/pages/foo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/async-[parent].vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/nested/[foo]/[bar].vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | -------------------------------------------------------------------------------- /packages/webpack/src/plugins/warning-ignore.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler, WebpackError } from 'webpack' 2 | 3 | export type WarningFilter = (warn: WebpackError) => boolean 4 | 5 | export default class WarningIgnorePlugin { 6 | filter: WarningFilter 7 | 8 | constructor (filter: WarningFilter) { 9 | this.filter = filter 10 | } 11 | 12 | apply (compiler: Compiler) { 13 | compiler.hooks.done.tap('warnfix-plugin', (stats) => { 14 | stats.compilation.warnings = stats.compilation.warnings.filter(this.filter) 15 | }) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/basic/composables/tree-shake.ts: -------------------------------------------------------------------------------- 1 | export function useServerOnlyComposable () { 2 | if (import.meta.client) { 3 | throw new Error('this should not be called in the browser') 4 | } 5 | } 6 | 7 | export function useClientOnlyComposable () { 8 | // need to do some code that fails in node but not in the browser 9 | if (import.meta.server) { 10 | throw new Error('this should not be called on the server') 11 | } 12 | } 13 | 14 | export function setTitleToPink () { 15 | document.querySelector('h1')!.style.color = 'pink' 16 | } 17 | -------------------------------------------------------------------------------- /docs/3.api/1.composables/use-request-event.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "useRequestEvent" 3 | description: "You can use useRequestEvent to access the incoming request." 4 | --- 5 | 6 | # `useRequestEvent` 7 | 8 | Within your pages, components, and plugins you can use `useRequestEvent` to access the incoming request. 9 | 10 | ```js 11 | // Get underlying request event 12 | const event = useRequestEvent() 13 | 14 | // Get the URL 15 | const url = event.path 16 | ``` 17 | 18 | ::alert{icon=👉} 19 | In the browser, `useRequestEvent` will return `undefined`. 20 | :: 21 | -------------------------------------------------------------------------------- /packages/webpack/src/presets/nuxt.ts: -------------------------------------------------------------------------------- 1 | import type { WebpackConfigContext } from '../utils/config' 2 | import { applyPresets } from '../utils/config' 3 | 4 | import { assets } from './assets' 5 | import { base } from './base' 6 | import { esbuild } from './esbuild' 7 | import { pug } from './pug' 8 | import { style } from './style' 9 | import { vue } from './vue' 10 | 11 | export function nuxt (ctx: WebpackConfigContext) { 12 | applyPresets(ctx, [ 13 | base, 14 | assets, 15 | esbuild, 16 | pug, 17 | style, 18 | vue 19 | ]) 20 | } 21 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/page-extend.ts: -------------------------------------------------------------------------------- 1 | import { createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'page-extend' 6 | }, 7 | setup () { 8 | const nuxt = useNuxt() 9 | const resolver = createResolver(import.meta.url) 10 | 11 | nuxt.hook('pages:extend', (pages) => { 12 | pages.push({ 13 | name: 'page-extend', 14 | path: '/page-extend', 15 | file: resolver.resolve('./runtime/page.vue') 16 | }) 17 | }) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /docs/3.api/2.components/7.nuxt-welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The `` component greets users in new projects made from the starter template. 3 | --- 4 | 5 | # `` 6 | 7 | The `` component greets users in new projects made from the starter template. It includes links to the Nuxt documentation, source code, and social media accounts. 8 | 9 | ::alert{type=info icon=🔎} 10 | This component is part of [@nuxt/ui](https://github.com/nuxt/ui) 11 | :: 12 | 13 | ::ReadMore{link="https://github.com/nuxt/ui" title="@nuxt/ui"} 14 | :: 15 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/cleanup.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: "Remove common generated Nuxt files and caches." 3 | --- 4 | # `nuxi cleanup` 5 | 6 | ```{bash} 7 | npx nuxi clean|cleanup [rootDir] 8 | ``` 9 | 10 | The `cleanup` command removes common generated Nuxt files and caches, including: 11 | 12 | - `.nuxt` 13 | - `.output` 14 | - `node_modules/.vite` 15 | - `node_modules/.cache` 16 | 17 | Option | Default | Description 18 | -------------------------|-----------------|------------------ 19 | `rootDir` | `.` | The root directory of the project. 20 | -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Restore all git changes 6 | git restore -s@ -SW -- packages examples 7 | 8 | # Build all once to ensure things are nice 9 | pnpm build 10 | 11 | # Release packages 12 | for PKG in packages/* ; do 13 | if [[ $PKG == "packages/nuxi" ]] ; then 14 | continue 15 | fi 16 | pushd $PKG 17 | TAG="latest" 18 | echo "⚡ Publishing $PKG with tag $TAG" 19 | cp ../../LICENSE . 20 | cp ../../README.md . 21 | pnpm publish --access public --no-git-checks --tag $TAG 22 | popd > /dev/null 23 | done 24 | -------------------------------------------------------------------------------- /packages/nuxt/src/components/runtime/server-component.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent, h } from 'vue' 2 | import NuxtIsland from '#app/components/nuxt-island' 3 | 4 | export const createServerComponent = (name: string) => { 5 | return defineComponent({ 6 | name, 7 | inheritAttrs: false, 8 | props: { lazy: Boolean }, 9 | setup (props, { attrs, slots }) { 10 | return () => { 11 | return h(NuxtIsland, { 12 | name, 13 | lazy: props.lazy, 14 | props: attrs 15 | }, slots) 16 | } 17 | } 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/nested/[foo]/user-[group].vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 19 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/analyze.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "nuxi analyze" 3 | description: "Analyze the production bundle or your Nuxt application." 4 | --- 5 | 6 | # `nuxi analyze` 7 | 8 | ```{bash} 9 | npx nuxi analyze [--log-level] [rootDir] 10 | ``` 11 | 12 | The `analyze` command builds Nuxt and analyzes the production bundle (experimental). 13 | 14 | Option | Default | Description 15 | -------------------------|-----------------|------------------ 16 | `rootDir` | `.` | The directory of the target application. 17 | 18 | This command sets `process.env.NODE_ENV` to `production`. 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/plugins/async-plugin.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(async (/* nuxtApp */) => { 2 | const config1 = useRuntimeConfig() 3 | await new Promise(resolve => setTimeout(resolve, 100)) 4 | const { data } = useFetch('/api/hey', { key: 'hey' }) 5 | const config2 = useRuntimeConfig() 6 | return { 7 | provide: { 8 | asyncPlugin: () => config1 && config1 === config2 9 | ? 'Async plugin works! ' + config1.public.testConfig + (data.value?.baz ? 'useFetch works!' : 'useFetch does not work') 10 | : 'Async plugin failed!' 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /scripts/bump.ts: -------------------------------------------------------------------------------- 1 | import { consola } from 'consola' 2 | import { loadWorkspace } from './_utils' 3 | 4 | async function main () { 5 | const workspace = await loadWorkspace(process.cwd()) 6 | 7 | const newVersion = process.argv[2] 8 | if (!newVersion) { 9 | throw new Error('Please provide version!') 10 | } 11 | 12 | for (const pkg of workspace.packages.filter(p => !p.data.private)) { 13 | workspace.setVersion(pkg.data.name, newVersion!) 14 | } 15 | 16 | await workspace.save() 17 | } 18 | 19 | main().catch((err) => { 20 | consola.error(err) 21 | process.exit(1) 22 | }) 23 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/SetupScript.client.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/[...slug].vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /packages/schema/src/config/router.ts: -------------------------------------------------------------------------------- 1 | import { defineUntypedSchema } from 'untyped' 2 | 3 | export default defineUntypedSchema({ 4 | router: { 5 | /** 6 | * Additional options passed to `vue-router`. 7 | * 8 | * Note: Only JSON serializable options should be passed by nuxt config. 9 | * 10 | * For more control, you can use `app/router.options.ts` file. 11 | * @see [documentation](https://router.vuejs.org/api/interfaces/routeroptions.html). 12 | * @type {typeof import('../src/types/router').RouterConfigSerializable} 13 | */ 14 | options: {} 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/compat/capi.ts: -------------------------------------------------------------------------------- 1 | export * from 'vue' 2 | 3 | export const install = () => {} 4 | 5 | export function set (target: any, key: string | number | symbol, val: any) { 6 | if (Array.isArray(target)) { 7 | target.length = Math.max(target.length, key as number) 8 | target.splice(key as number, 1, val) 9 | return val 10 | } 11 | target[key] = val 12 | return val 13 | } 14 | 15 | export function del (target: any, key: string | number | symbol) { 16 | if (Array.isArray(target)) { 17 | target.splice(key as number, 1) 18 | return 19 | } 20 | delete target[key] 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/islands/PureComponent.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /packages/vite/src/runtime/vite-node-shared.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { Agent as HTTPSAgent } from 'node:https' 3 | import { $fetch } from 'ofetch' 4 | 5 | /** @type {import('../vite-node').ViteNodeServerOptions} */ 6 | export const viteNodeOptions = JSON.parse(process.env.NUXT_VITE_NODE_OPTIONS || '{}') 7 | 8 | export const viteNodeFetch = $fetch.create({ 9 | baseURL: viteNodeOptions.baseURL, 10 | // @ts-expect-error https://github.com/node-fetch/node-fetch#custom-agent 11 | agent: viteNodeOptions.baseURL.startsWith('https://') 12 | ? new HTTPSAgent({ rejectUnauthorized: false }) 13 | : null 14 | }) 15 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/example.ts: -------------------------------------------------------------------------------- 1 | import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'my-module', 6 | configKey: 'sampleModule' 7 | }, 8 | setup () { 9 | const resolver = createResolver(import.meta.url) 10 | 11 | addPlugin(resolver.resolve('./runtime/plugin')) 12 | useNuxt().hook('app:resolve', (app) => { 13 | app.middleware.push({ 14 | name: 'unctx-test', 15 | path: resolver.resolve('./runtime/middleware'), 16 | global: true 17 | }) 18 | }) 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/1.node_modules.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconDirectory 3 | title: "node_modules" 4 | description: "The package manager stores the dependencies of your project in the node_modules/ directory." 5 | head.title: "node_modules/" 6 | --- 7 | 8 | # Node modules Directory 9 | 10 | The package manager ([`npm`](https://docs.npmjs.com/cli/commands/npm) or [`yarn`](https://yarnpkg.com/) or [`pnpm`](https://pnpm.io/cli/install) or [`bun`](https://bun.sh/package-manager)) creates the [`node_modules/` directory](/docs/guide/directory-structure/node_modules) to store the dependencies of your project. 11 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/prepare.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The prepare command creates a .nuxt directory in your application and generates types. 3 | --- 4 | # `nuxi prepare` 5 | 6 | ```{bash} 7 | npx nuxi prepare [--log-level] [rootDir] 8 | ``` 9 | 10 | The `prepare` command creates a `.nuxt` directory in your application and generates types. This can be useful in a CI environment or as a `postinstall` command in your `package.json`. 11 | 12 | Option | Default | Description 13 | -------------------------|-----------------|------------------ 14 | `rootDir` | `.` | The root directory of the application to prepare. 15 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/plugins/restore-state.client.ts: -------------------------------------------------------------------------------- 1 | import destr from 'destr' 2 | import { defineNuxtPlugin, useNuxtApp } from '#app/nuxt' 3 | 4 | export default defineNuxtPlugin({ 5 | name: 'nuxt:restore-state', 6 | hooks: { 7 | 'app:mounted' () { 8 | const nuxtApp = useNuxtApp() 9 | try { 10 | const state = sessionStorage.getItem('nuxt:reload:state') 11 | if (state) { 12 | sessionStorage.removeItem('nuxt:reload:state') 13 | Object.assign(nuxtApp.payload.state, destr>(state)?.state) 14 | } 15 | } catch {} 16 | } 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/vueuse-head.vue: -------------------------------------------------------------------------------- 1 | 20 | 25 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/1.public.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconDirectory 3 | title: "public" 4 | description: "The public/ directory is used to serve your website's static assets." 5 | head.title: "public/" 6 | --- 7 | 8 | # Public Directory 9 | 10 | The [`public/` directory](/docs/guide/directory-structure/public) is directly served at the server root and contains public files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. `favicon.ico`). 11 | 12 | ::alert{icon=💡} 13 | This is known as the [`static/` directory](https://nuxtjs.org/docs/directory-structure/static) in Nuxt 2. 14 | :: 15 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/clear-nuxt-data.md: -------------------------------------------------------------------------------- 1 | # `clearNuxtData` 2 | 3 | Delete cached data, error status and pending promises of [`useAsyncData`](/docs/api/composables/use-async-data) and `useFetch`. 4 | 5 | This method is useful if you want to invalidate the data fetching for another page. 6 | 7 | ## Type 8 | 9 | ```ts 10 | clearNuxtData (keys?: string | string[] | ((key: string) => boolean)): void 11 | ``` 12 | 13 | ## Parameters 14 | 15 | * `keys`: One or an array of keys that are used in [`useAsyncData`](/docs/api/composables/use-async-data) to delete their cached data. If no keys are provided, **all data** will be invalidated. 16 | -------------------------------------------------------------------------------- /lychee.toml: -------------------------------------------------------------------------------- 1 | # Cache the results of Lychee if ran locally in order to minimise the chance of rate limiting 2 | cache = true 3 | # Ignore all private link (such as localhost) to avoid errors 4 | exclude_all_private = true 5 | # HTTP status code: 429 (Too Many Requests) will also be treated as a valid link if Lychee gets rate limited 6 | accept = [200, 429] 7 | # retry 8 | max_retries = 6 9 | # Explicitly exclude some URLs 10 | exclude = [ 11 | "https://twitter.nuxt.dev/", 12 | "https://github.com/nuxt/nuxt.com", 13 | "https://github.com/nuxt/translations/discussions/4", 14 | '(https?:\/\/github\.com\/)(.*\/)(generate)' 15 | ] 16 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report a vulnerability, please send an email to **security@nuxtjs.org** or submit it for a bounty via [Huntr](https://huntr.dev/bounties/disclose/?target=https://github.com/nuxt/nuxt). 6 | 7 | All security vulnerabilities will be promptly verified and addressed. 8 | 9 | While the discovery of new vulnerabilities is rare, we also recommend always using the latest versions of Nuxt and other dependencies by maintaining lock files (`yarn.lock`, `package-lock.json` and `pnpm-lock.yaml`) in order to ensure your application remains as secure as possible. 10 | 11 | -------------------------------------------------------------------------------- /scripts/bump-rc.ts: -------------------------------------------------------------------------------- 1 | import { inc } from 'semver' 2 | import { consola } from 'consola' 3 | import { loadWorkspace } from './_utils' 4 | 5 | async function main () { 6 | const workspace = await loadWorkspace(process.cwd()) 7 | 8 | for (const pkg of workspace.packages.filter(p => !p.data.private)) { 9 | // TODO: Set release type based on changelog after 3.0.0 10 | const newVersion = inc(pkg.data.version, 'prerelease', 'rc') 11 | workspace.setVersion(pkg.data.name, newVersion!) 12 | } 13 | 14 | await workspace.save() 15 | } 16 | 17 | main().catch((err) => { 18 | consola.error(err) 19 | process.exit(1) 20 | }) 21 | -------------------------------------------------------------------------------- /scripts/release-rc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Restore all git changes 6 | git restore -s@ -SW -- packages examples 7 | 8 | # Build all once to ensure things are nice 9 | pnpm build 10 | 11 | # Release packages 12 | for PKG in packages/* ; do 13 | if [[ $PKG == "packages/nuxi" ]] ; then 14 | continue 15 | fi 16 | pushd $PKG 17 | TAG="latest" 18 | if [ "$PKG" == "packages/nuxt" ]; then 19 | TAG="rc" 20 | fi 21 | echo "⚡ Publishing $PKG with tag $TAG" 22 | cp ../../LICENSE . 23 | cp ../../README.md . 24 | pnpm publish --access public --no-git-checks --tag $TAG 25 | popd > /dev/null 26 | done 27 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/ClientOnlyScript.client.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 20 | 21 | 26 | 27 | 32 | -------------------------------------------------------------------------------- /test/setup.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { dirname, join } from 'node:path' 3 | import fs from 'fs-extra' 4 | 5 | const dir = dirname(fileURLToPath(import.meta.url)) 6 | const fixtureDir = join(dir, 'fixtures') 7 | const tempDir = join(dir, 'fixtures-temp') 8 | 9 | export async function setup () { 10 | if (fs.existsSync(tempDir)) { 11 | await fs.remove(tempDir) 12 | } 13 | await fs.copy(fixtureDir, tempDir, { 14 | filter: src => !src.includes('.cache') 15 | }) 16 | } 17 | 18 | export async function teardown () { 19 | if (fs.existsSync(tempDir)) { 20 | await fs.remove(tempDir) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/test-utils/src/runtime/global-setup.ts: -------------------------------------------------------------------------------- 1 | import * as _kit from '@nuxt/kit' 2 | import { createTest, exposeContextToEnv } from '@nuxt/test-utils' 3 | 4 | // @ts-expect-error type cast 5 | // eslint-disable-next-line 6 | const kit: typeof _kit = _kit.default || _kit 7 | 8 | const options = JSON.parse(process.env.NUXT_TEST_OPTIONS || '{}') 9 | const hooks = createTest(options) 10 | 11 | export const setup = async () => { 12 | kit.logger.info('Building Nuxt app...') 13 | await hooks.setup() 14 | exposeContextToEnv() 15 | kit.logger.info('Running tests...') 16 | } 17 | 18 | export const teardown = async () => { 19 | await hooks.afterAll() 20 | } 21 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/prerender-routes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: prerenderRoutes hints to Nitro to prerender an additional route. 3 | --- 4 | 5 | # `prerenderRoutes` 6 | 7 | When prerendering, you can hint to Nitro to prerender additional paths, even if their URLs do not show up in the HTML of the generated page. 8 | 9 | `prerenderRoutes` can only be called within component setup functions, plugins, and route middleware. 10 | 11 | ```js 12 | const route = useRoute() 13 | 14 | prerenderRoutes('/') 15 | prerenderRoutes(['/', '/about']) 16 | ``` 17 | 18 | ::alert{icon=👉} 19 | In the browser, or if called outside prerendering, `prerenderRoutes` will have no effect. 20 | :: 21 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // https://code.visualstudio.com/docs/devcontainers/containers 2 | // https://containers.dev/implementors/json_reference/ 3 | { 4 | "name": "nuxt-devcontainer", 5 | "dockerFile": "Dockerfile", 6 | "features": {}, 7 | "customizations": { 8 | "vscode": { 9 | "settings": {}, 10 | "extensions": [ 11 | "ms-azuretools.vscode-docker", 12 | "dbaeumer.vscode-eslint", 13 | "github.vscode-github-actions", 14 | "vue.volar" 15 | ] 16 | } 17 | }, 18 | "postStartCommand": "pnpm install && pnpm build:stub", 19 | "mounts": ["type=volume,target=${containerWorkspaceFolder}/node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/webpack/src/presets/pug.ts: -------------------------------------------------------------------------------- 1 | import type { WebpackConfigContext } from '../utils/config' 2 | 3 | export function pug (ctx: WebpackConfigContext) { 4 | ctx.config.module!.rules!.push({ 5 | test: /\.pug$/i, 6 | oneOf: [ 7 | { 8 | resourceQuery: /^\?vue/i, 9 | use: [{ 10 | loader: 'pug-plain-loader', 11 | options: ctx.userConfig.loaders.pugPlain 12 | }] 13 | }, 14 | { 15 | use: [ 16 | 'raw-loader', 17 | { 18 | loader: 'pug-plain-loader', 19 | options: ctx.userConfig.loaders.pugPlain 20 | } 21 | ] 22 | } 23 | ] 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/components/WithTypes.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /.github/assets/github.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/sync-[parent]/async-[child].vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/suspense/async-[parent]/async-[child].vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/chunk-error.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 22 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/0.output.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconDirectory 3 | title: ".output" 4 | description: "Nuxt creates the .output/ directory when building your application for production." 5 | head.title: ".output/" 6 | --- 7 | 8 | # Output Directory 9 | 10 | Nuxt creates the [`.output/` directory](/docs/guide/directory-structure/output) when building your application for production. 11 | 12 | ::alert{type=warning} 13 | You should not touch any files inside since the whole directory will be re-created when running `nuxt build`. 14 | :: 15 | 16 | Use this directory to deploy your Nuxt application to production. Learn more in our [deployment section](/docs/getting-started/deployment). 17 | -------------------------------------------------------------------------------- /docs/6.bridge/9.vite.md: -------------------------------------------------------------------------------- 1 | # Vite 2 | 3 | ::alert{type=warning} 4 | When using `vite`, [nitro](/docs/bridge/nitro) must have been configured. 5 | :: 6 | 7 | ## Remove Modules 8 | 9 | - Remove `nuxt-vite`: Bridge enables same functionality 10 | 11 | ## Update Config 12 | 13 | ```ts [nuxt.config.js|ts] 14 | import { defineNuxtConfig } from '@nuxt/bridge' 15 | 16 | export default defineNuxtConfig({ 17 | bridge: { 18 | vite: true, 19 | nitro: true 20 | } 21 | }) 22 | ``` 23 | 24 | ## Configuration 25 | 26 | ```ts [nuxt.config.js|ts] 27 | import { defineNuxtConfig } from '@nuxt/bridge' 28 | 29 | export default defineNuxtConfig({ 30 | vite: { 31 | // Config for Vite 32 | } 33 | }) 34 | ``` 35 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/useAsyncData/immediate-remove-unmounted.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /test/fixtures/basic-types/modules/example.ts: -------------------------------------------------------------------------------- 1 | import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | defaults: { 5 | enabled: true, 6 | typeTest: (value: boolean) => typeof value === 'boolean' 7 | }, 8 | meta: { 9 | name: 'my-module', 10 | configKey: 'sampleModule' 11 | }, 12 | setup () { 13 | const resolver = createResolver(import.meta.url) 14 | 15 | addPlugin(resolver.resolve('./runtime/plugin')) 16 | useNuxt().hook('app:resolve', (app) => { 17 | app.middleware.push({ 18 | name: 'unctx-test', 19 | path: resolver.resolve('./runtime/middleware') 20 | }) 21 | }) 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /packages/nuxt/src/core/runtime/nitro/paths.ts: -------------------------------------------------------------------------------- 1 | import { joinURL } from 'ufo' 2 | import { useRuntimeConfig } from '#internal/nitro' 3 | 4 | export function baseURL (): string { 5 | return useRuntimeConfig().app.baseURL 6 | } 7 | 8 | export function buildAssetsDir (): string { 9 | return useRuntimeConfig().app.buildAssetsDir as string 10 | } 11 | 12 | export function buildAssetsURL (...path: string[]): string { 13 | return joinURL(publicAssetsURL(), buildAssetsDir(), ...path) 14 | } 15 | 16 | export function publicAssetsURL (...path: string[]): string { 17 | const publicBase = useRuntimeConfig().app.cdnURL as string || useRuntimeConfig().app.baseURL 18 | return path.length ? joinURL(publicBase, ...path) : publicBase 19 | } 20 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/compat/idle-callback.ts: -------------------------------------------------------------------------------- 1 | // Polyfills for Safari support 2 | // https://caniuse.com/requestidlecallback 3 | export const requestIdleCallback: Window['requestIdleCallback'] = import.meta.server 4 | ? (() => {}) as any 5 | : (globalThis.requestIdleCallback || ((cb) => { 6 | const start = Date.now() 7 | const idleDeadline = { 8 | didTimeout: false, 9 | timeRemaining: () => Math.max(0, 50 - (Date.now() - start)) 10 | } 11 | return setTimeout(() => { cb(idleDeadline) }, 1) 12 | })) 13 | 14 | export const cancelIdleCallback: Window['cancelIdleCallback'] = import.meta.server 15 | ? (() => {}) as any 16 | : (globalThis.cancelIdleCallback || ((id) => { clearTimeout(id) })) 17 | -------------------------------------------------------------------------------- /packages/schema/src/types/router.ts: -------------------------------------------------------------------------------- 1 | import type { RouterHistory, RouterOptions as _RouterOptions } from 'vue-router' 2 | 3 | export type RouterOptions = Partial> & { 4 | history?: (baseURL?: string) => RouterHistory 5 | routes?: (_routes: _RouterOptions['routes']) => _RouterOptions['routes'] 6 | hashMode?: boolean 7 | scrollBehaviorType?: 'smooth' | 'auto' 8 | } 9 | 10 | export type RouterConfig = RouterOptions 11 | 12 | /** 13 | * Only JSON serializable router options are configurable from nuxt config 14 | */ 15 | export type RouterConfigSerializable = Pick 16 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/components/ShowTemplate.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 36 | -------------------------------------------------------------------------------- /packages/schema/src/config/internal.ts: -------------------------------------------------------------------------------- 1 | import { defineUntypedSchema } from 'untyped' 2 | 3 | export default defineUntypedSchema({ 4 | /** @private */ 5 | _majorVersion: 3, 6 | /** @private */ 7 | _legacyGenerate: false, 8 | /** @private */ 9 | _start: false, 10 | /** @private */ 11 | _build: false, 12 | /** @private */ 13 | _generate: false, 14 | /** @private */ 15 | _prepare: false, 16 | /** @private */ 17 | _cli: false, 18 | /** @private */ 19 | _requiredModules: {}, 20 | /** @private */ 21 | _nuxtConfigFile: undefined, 22 | /** @private */ 23 | _nuxtConfigFiles: [], 24 | /** @private */ 25 | appDir: '', 26 | /** @private */ 27 | _installedModules: [], 28 | /** @private */ 29 | _modules: [] 30 | }) 31 | -------------------------------------------------------------------------------- /packages/vite/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { hash } from 'ohash' 2 | 3 | export function uniq (arr: T[]): T[] { 4 | return Array.from(new Set(arr)) 5 | } 6 | 7 | // Copied from vue-bundle-renderer utils 8 | const IS_CSS_RE = /\.(?:css|scss|sass|postcss|less|stylus|styl)(\?[^.]+)?$/ 9 | 10 | export function isCSS (file: string) { 11 | return IS_CSS_RE.test(file) 12 | } 13 | 14 | export function hashId (id: string) { 15 | return '$id_' + hash(id) 16 | } 17 | 18 | export function matchWithStringOrRegex (value: string, matcher: string | RegExp) { 19 | if (typeof matcher === 'string') { 20 | return value === matcher 21 | } else if (matcher instanceof RegExp) { 22 | return matcher.test(value) 23 | } 24 | 25 | return false 26 | } 27 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/cookies.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/set-page-layout.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: setPageLayout allows you to dynamically change the layout of a page. 3 | --- 4 | # `setPageLayout` 5 | 6 | `setPageLayout` allows you to dynamically change the layout of a page. It relies on access to the Nuxt context and can only be called within components' setup functions, plugins, and route middleware. 7 | 8 | ```ts 9 | export default defineNuxtRouteMiddleware((to) => { 10 | // Set the layout on the route you are navigating _to_ 11 | setPageLayout('other') 12 | }) 13 | ``` 14 | 15 | ::alert{icon=👉} 16 | If you choose to set the layout dynamically on the server side, you _must_ do so before the layout is rendered by Vue (that is, within a plugin or route middleware) to avoid a hydration mismatch. 17 | :: 18 | -------------------------------------------------------------------------------- /packages/schema/src/types/compatibility.ts: -------------------------------------------------------------------------------- 1 | export interface NuxtCompatibility { 2 | /** 3 | * Required nuxt version in semver format. 4 | * @example `^2.14.0` or `>=3.0.0-27219851.6e49637`. 5 | */ 6 | nuxt?: string 7 | 8 | /** 9 | * Bridge constraint for Nuxt 2 support. 10 | * 11 | * - `true`: When using Nuxt 2, using bridge module is required. 12 | * - `false`: When using Nuxt 2, using bridge module is not supported. 13 | */ 14 | bridge?: boolean 15 | } 16 | 17 | export interface NuxtCompatibilityIssue { 18 | name: string 19 | message: string 20 | } 21 | 22 | export interface NuxtCompatibilityIssues extends Array { 23 | /** 24 | * Return formatted error message. 25 | */ 26 | toString(): string 27 | } 28 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/useAsyncData/double.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/page-extend/index.ts: -------------------------------------------------------------------------------- 1 | import { createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'page-extend' 6 | }, 7 | setup () { 8 | const nuxt = useNuxt() 9 | const resolver = createResolver(import.meta.url) 10 | 11 | nuxt.hook('pages:extend', (pages) => { 12 | pages.push({ 13 | name: 'page-extend', 14 | path: '/page-extend', 15 | file: resolver.resolve('../runtime/page.vue') 16 | }, { 17 | path: '/big-page-1', 18 | file: resolver.resolve('./pages/big-page.vue') 19 | }, { 20 | path: '/big-page-2', 21 | file: resolver.resolve('./pages/big-page.vue') 22 | }) 23 | }) 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /test/setup-env.ts: -------------------------------------------------------------------------------- 1 | import { consola } from 'consola' 2 | import { vi } from 'vitest' 3 | import { logger } from '../packages/kit' 4 | 5 | consola.mockTypes(() => vi.fn()) 6 | logger.mockTypes(() => vi.fn()) 7 | 8 | const _warn = console.warn.bind(console) 9 | 10 | const hiddenWarns = [ 11 | '[@vue/reactivity-transform]', 12 | '[Vue warn]: Component', 13 | '[Vue router warn]' 14 | ] 15 | 16 | console.warn = (arg0: any, ...args: any[]) => { 17 | if ((typeof arg0 === 'string') && hiddenWarns.some(w => arg0.includes(w))) { 18 | return 19 | } 20 | _warn(...args) 21 | } 22 | 23 | // for (const t of ['uncaughtException', 'unhandledRejection'] as const) { 24 | // process.on(t, (err) => { 25 | // console.error(`[nuxt test suite] [${t}]`, err) 26 | // }) 27 | // } 28 | -------------------------------------------------------------------------------- /docs/3.api/1.composables/use-request-url.md: -------------------------------------------------------------------------------- 1 | # useRequestURL 2 | 3 | `useRequestURL` is a helper function that returns an [URL object](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) working on both server-side and client-side. 4 | 5 | ::code-group 6 | 7 | ```vue [pages/about.vue] 8 | 11 | 12 | 16 | ``` 17 | 18 | ```html [Result in development] 19 |

URL is: http://localhost:3000/about

20 |

Path is: /about

21 | ``` 22 | 23 | :: 24 | 25 | You can find the list of the [URL instance properties](https://developer.mozilla.org/en-US/docs/Web/API/URL#instance_properties) on the MDN documentation. 26 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/assets.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /packages/schema/src/config/generate.ts: -------------------------------------------------------------------------------- 1 | import { defineUntypedSchema } from 'untyped' 2 | 3 | export default defineUntypedSchema({ 4 | generate: { 5 | /** 6 | * The routes to generate. 7 | * 8 | * If you are using the crawler, this will be only the starting point for route generation. 9 | * This is often necessary when using dynamic routes. 10 | * 11 | * It is preferred to use `nitro.prerender.routes`. 12 | * @example 13 | * ```js 14 | * routes: ['/users/1', '/users/2', '/users/3'] 15 | * ``` 16 | * @type {string | string[]} 17 | */ 18 | routes: [], 19 | 20 | /** 21 | * This option is no longer used. Instead, use `nitro.prerender.ignore`. 22 | * @deprecated 23 | */ 24 | exclude: [] 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/show-error.md: -------------------------------------------------------------------------------- 1 | # `showError` 2 | 3 | Nuxt provides a quick and simple way to show a full screen error page if needed. 4 | 5 | Within your pages, components and plugins you can use `showError` to show an error. 6 | 7 | **Parameters:** 8 | 9 | - `error`: `string | Error | Partial<{ cause, data, message, name, stack, statusCode, statusMessage }>` 10 | 11 | ```js 12 | showError("😱 Oh no, an error has been thrown.") 13 | showError({ statusCode: 404, statusMessage: "Page Not Found" }) 14 | ``` 15 | 16 | The error is set in the state using [`useError()`](/docs/api/composables/use-error) to create a reactive and SSR-friendly shared error state across components. 17 | 18 | `showError` calls the `app:error` hook. 19 | 20 | ::ReadMore{link="/docs/getting-started/error-handling"} 21 | :: 22 | -------------------------------------------------------------------------------- /packages/schema/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import adhoc from './adhoc' 2 | import app from './app' 3 | import build from './build' 4 | import common from './common' 5 | import dev from './dev' 6 | import experimental from './experimental' 7 | import generate from './generate' 8 | import internal from './internal' 9 | import nitro from './nitro' 10 | import postcss from './postcss' 11 | import router from './router' 12 | import typescript from './typescript' 13 | import vite from './vite' 14 | import webpack from './webpack' 15 | 16 | export default { 17 | ...adhoc, 18 | ...app, 19 | ...build, 20 | ...common, 21 | ...dev, 22 | ...experimental, 23 | ...generate, 24 | ...internal, 25 | ...nitro, 26 | ...postcss, 27 | ...router, 28 | ...typescript, 29 | ...vite, 30 | ...webpack 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/basic/pages/server-components/lazy/end.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | -------------------------------------------------------------------------------- /scripts/release-edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -xe 4 | 5 | # Restore all git changes 6 | git restore -s@ -SW -- packages examples 7 | 8 | TAG=${1:-latest} 9 | 10 | # Bump versions to edge 11 | pnpm jiti ./scripts/bump-edge 12 | 13 | # Update token 14 | if [[ ! -z ${NODE_AUTH_TOKEN} ]] ; then 15 | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc 16 | echo "registry=https://registry.npmjs.org/" >> ~/.npmrc 17 | echo "always-auth=true" >> ~/.npmrc 18 | npm whoami 19 | fi 20 | 21 | # Release packages 22 | for p in packages/* ; do 23 | if [[ $p == "packages/nuxi" ]] ; then 24 | continue 25 | fi 26 | pushd $p 27 | echo "Publishing $p" 28 | cp ../../LICENSE . 29 | cp ../../README.md . 30 | pnpm publish --access public --no-git-checks --tag $TAG 31 | popd 32 | done 33 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/2.gitignore.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconFile 3 | title: ".gitignore" 4 | description: "A .gitignore file specifies intentionally untracked files that git should ignore." 5 | head.title: ".gitignore" 6 | --- 7 | 8 | # Git Ignore File 9 | 10 | A `.gitignore` file specifies intentionally untracked files that git should ignore. Learn more about it in [the git documentation](https://git-scm.com/docs/gitignore). 11 | 12 | We recommend having a `.gitignore` file that has **at least** the following entries present: 13 | 14 | ```bash [.gitignore] 15 | # Nuxt dev/build outputs 16 | .output 17 | .nuxt 18 | 19 | # Node dependencies 20 | node_modules 21 | 22 | # Logs 23 | logs 24 | *.log 25 | 26 | # Misc 27 | .DS_Store 28 | 29 | # Local env files 30 | .env.* 31 | !.env.example 32 | ``` 33 | -------------------------------------------------------------------------------- /packages/kit/src/ignore.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { resolveGroupSyntax } from './ignore.js' 3 | 4 | describe('resolveGroupSyntax', () => { 5 | it('should resolve single group syntax', () => { 6 | expect(resolveGroupSyntax('**/*.{spec}.{js,ts}')).toStrictEqual([ 7 | '**/*.spec.js', 8 | '**/*.spec.ts' 9 | ]) 10 | }) 11 | 12 | it('should resolve multi-group syntax', () => { 13 | expect(resolveGroupSyntax('**/*.{spec,test}.{js,ts}')).toStrictEqual([ 14 | '**/*.spec.js', 15 | '**/*.spec.ts', 16 | '**/*.test.js', 17 | '**/*.test.ts' 18 | ]) 19 | }) 20 | 21 | it('should do nothing with normal globs', () => { 22 | expect(resolveGroupSyntax('**/*.spec.js')).toStrictEqual([ 23 | '**/*.spec.js' 24 | ]) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /knip.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/knip@2/schema.json", 3 | "workspaces": { 4 | ".": { 5 | "entry": [ 6 | "scripts/*" 7 | ] 8 | }, 9 | "packages/*": { 10 | "entry": [ 11 | "src/index.ts", 12 | "src/runtime/**/*.ts" 13 | ] 14 | }, 15 | "packages/test-utils": { 16 | "entry": [ 17 | "src/experimental.ts", 18 | "src/index.ts" 19 | ] 20 | }, 21 | "packages/nuxi": { 22 | "entry": [ 23 | "src/index.ts", 24 | "src/commands/*.ts" 25 | ] 26 | }, 27 | "packages/nuxt": { 28 | "entry": [ 29 | "src/app/**/*.ts", 30 | "src/app/*.ts", 31 | "src/*/runtime/**/*.ts", 32 | "src/core/templates.ts", 33 | "src/index.ts" 34 | ] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/set-response-status.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: setResponseStatus sets the statusCode (and optionally the statusMessage) of the response. 3 | --- 4 | # `setResponseStatus` 5 | 6 | Nuxt provides composables and utilities for first-class server-side-rendering support. 7 | 8 | `setResponseStatus` sets the statusCode (and optionally the statusMessage) of the response. 9 | 10 | `setResponseStatus` can only be called within component setup functions, plugins, and route middleware. 11 | 12 | ```js 13 | const event = useRequestEvent() 14 | 15 | // Set the status code to 404 for a custom 404 page 16 | setResponseStatus(event, 404) 17 | 18 | // Set the status message as well 19 | setResponseStatus(event, 404, 'Page Not Found') 20 | ``` 21 | 22 | ::alert{icon=👉} 23 | In the browser, `setResponseStatus` will have no effect. 24 | :: 25 | -------------------------------------------------------------------------------- /packages/vite/src/utils/transpile.ts: -------------------------------------------------------------------------------- 1 | import { useNuxt } from '@nuxt/kit' 2 | import escapeRegExp from 'escape-string-regexp' 3 | import { normalize } from 'pathe' 4 | 5 | interface Envs { 6 | isDev: boolean 7 | isClient?: boolean 8 | isServer?: boolean 9 | } 10 | 11 | export function transpile (envs: Envs): Array { 12 | const nuxt = useNuxt() 13 | const transpile = [] 14 | 15 | for (let pattern of nuxt.options.build.transpile) { 16 | if (typeof pattern === 'function') { 17 | const result = pattern(envs) 18 | if (result) { pattern = result } 19 | } 20 | if (typeof pattern === 'string') { 21 | transpile.push(new RegExp(escapeRegExp(normalize(pattern)))) 22 | } else if (pattern instanceof RegExp) { 23 | transpile.push(pattern) 24 | } 25 | } 26 | 27 | return transpile 28 | } 29 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/on-nuxt-ready.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "onNuxtReady" 3 | description: The onNuxtReady composable allows running a callback after your app has finished initializing. 4 | --- 5 | 6 | # `onNuxtReady` 7 | 8 | The `onNuxtReady` composable allows running a callback after your app has finished initializing. It is ideal for running code that should not block the initial rendering of your app. 9 | 10 | ```ts 11 | export default defineNuxtPlugin(() => { 12 | onNuxtReady(async () => { 13 | const myAnalyticsLibrary = await import('my-big-analytics-library') 14 | // do something with myAnalyticsLibrary 15 | }) 16 | }) 17 | ``` 18 | 19 | It is 'safe' to run even after your app has initialized. In this case, then the code will be registered to run in the next idle callback. 20 | 21 | ::alert 22 | `onNuxtReady` only runs on the client-side. 23 | :: 24 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/devtools.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "nuxi devtools" 3 | description: The devtools command allows you to enable or disable Nuxt DevTools on a per-project basis. 4 | --- 5 | 6 | # `nuxi devtools` 7 | 8 | ```{bash} 9 | npx nuxi devtools enable|disable [rootDir] 10 | ``` 11 | 12 | Running `nuxi devtools enable` will install the Nuxt DevTools globally, and also enable it within the particular project you are using. It is saved as a preference in your user-level `.nuxtrc`. If you want to remove devtools support for a particular project, you can run `nuxi devtools disable`. 13 | 14 | Option | Default | Description 15 | -------------------------|-----------------|------------------ 16 | `rootDir` | `.` | The root directory of the app you want to enable devtools for. 17 | 18 | ::ReadMore{link="https://github.com/nuxt/devtools"} 19 | :: 20 | -------------------------------------------------------------------------------- /packages/schema/src/types/imports.ts: -------------------------------------------------------------------------------- 1 | import type { UnimportOptions } from 'unimport' 2 | 3 | export interface ImportsOptions extends UnimportOptions { 4 | /** 5 | * Enable implicit auto import from Vue, Nuxt and module contributed utilities. 6 | * Generate global TypeScript definitions. 7 | * @default true 8 | */ 9 | autoImport?: boolean 10 | 11 | /** 12 | * Directories to scan for auto imports. 13 | * @see https://nuxt.com/docs/guide/directory-structure/composables#how-files-are-scanned 14 | * @default ['./composables', './utils'] 15 | */ 16 | dirs?: string[] 17 | 18 | /** 19 | * Assign auto imported utilities to `globalThis` instead of using built time transformation. 20 | * @default false 21 | */ 22 | global?: boolean 23 | 24 | transform?: { 25 | exclude?: RegExp[] 26 | include?: RegExp[] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.website/README.md: -------------------------------------------------------------------------------- 1 | # Nuxt Docs Website 2 | 3 | This is a temporary directory until we open source the repository for nuxt.com. 4 | 5 | The goal is to simplify the contribution in the meantime to the documentation by having the possibility to preview the changes locally. 6 | 7 | ## Setup 8 | 9 | Install dependencies in the root of the `nuxt` folder: 10 | 11 | ```bash 12 | pnpm i 13 | ``` 14 | 15 | Then stub the dependencies: 16 | 17 | ```bash 18 | pnpm build:stub 19 | ``` 20 | 21 | ## Development 22 | 23 | In the root of the `nuxt` folder, run: 24 | 25 | ```bash 26 | pnpm docs:dev 27 | ``` 28 | 29 | Then open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 30 | 31 | Update the documentation within the `docs` folder. 32 | 33 | --- 34 | 35 | For a detailed explanation of how things work, check out [Docus](https://docus.dev). 36 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/build.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "nuxi build" 3 | description: "Build your Nuxt application." 4 | --- 5 | 6 | # `nuxi build` 7 | 8 | ```{bash} 9 | npx nuxi build [--prerender] [--dotenv] [--log-level] [rootDir] 10 | ``` 11 | 12 | The `build` command creates a `.output` directory with all your application, server and dependencies ready for production. 13 | 14 | Option | Default | Description 15 | -------------------------|-----------------|------------------ 16 | `rootDir` | `.` | The root directory of the application to bundle. 17 | `--prerender` | `false` | Pre-render every route of your application. (**note:** This is an experimental flag. The behavior might be changed.) 18 | `--dotenv` | `.` | Point to another `.env` file to load, **relative** to the root directory. 19 | 20 | This command sets `process.env.NODE_ENV` to `production`. 21 | -------------------------------------------------------------------------------- /packages/vite/src/plugins/type-check.ts: -------------------------------------------------------------------------------- 1 | import MagicString from 'magic-string' 2 | import type { Plugin } from 'vite' 3 | 4 | export function typeCheckPlugin (options: { sourcemap?: boolean } = {}): Plugin { 5 | let entry: string 6 | return { 7 | name: 'nuxt:type-check', 8 | configResolved (config) { 9 | const input = config.build.rollupOptions.input 10 | if (input && typeof input !== 'string' && !Array.isArray(input)) { 11 | entry = input.entry 12 | } 13 | }, 14 | transform (code, id) { 15 | if (id !== entry) { return } 16 | 17 | const s = new MagicString(code) 18 | 19 | s.prepend('import "/@vite-plugin-checker-runtime-entry";\n') 20 | 21 | return { 22 | code: s.toString(), 23 | map: options.sourcemap ? s.generateMap({ hires: true }) : undefined 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/fixtures/basic/modules/auto-registered/index.ts: -------------------------------------------------------------------------------- 1 | import { addServerHandler, addServerImports, addServerImportsDir, createResolver, defineNuxtModule } from 'nuxt/kit' 2 | 3 | export default defineNuxtModule({ 4 | meta: { 5 | name: 'auto-registered-module' 6 | }, 7 | setup () { 8 | const resolver = createResolver(import.meta.url) 9 | 10 | addServerHandler({ 11 | handler: resolver.resolve('./runtime/handler'), 12 | route: '/auto-registered-module' 13 | }) 14 | 15 | addServerImports([{ 16 | from: resolver.resolve('./runtime/some-server-import'), 17 | name: 'serverAutoImported', 18 | as: 'autoimportedFunction' 19 | }, { 20 | from: resolver.resolve('./runtime/some-server-import'), 21 | name: 'someUtils' 22 | }]) 23 | 24 | addServerImportsDir(resolver.resolve('./runtime/server')) 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /test/fixtures/runtime-compiler/server/api/full-component.get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * sometimes, CMS wants to give full control on components. This might not be a good practice. 3 | * SO MAKE SURE TO SANITIZE ALL YOUR STRINGS 4 | */ 5 | export default defineEventHandler(() => { 6 | return { 7 | props: ['lastname', 'firstname'], 8 | // don't forget to sanitize 9 | setup: ` 10 | const fullName = computed(() => props.lastname + ' ' + props.firstname); 11 | 12 | const count = ref(0); 13 | 14 | return {fullName, count} 15 | `, 16 | template: '
my name is {{ fullName }}, count: {{count}}. I am defined by Interactive in the setup of App.vue. My full component definition is retrieved from the api
' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /.github/workflows/introspect.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/workflows/**" 7 | branches: 8 | - main 9 | pull_request: 10 | paths: 11 | - ".github/workflows/**" 12 | branches: 13 | - main 14 | - "!v[0-9]*" 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | lint-workflows: 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 25 | # From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions 26 | - name: Check workflow files 27 | run: | 28 | bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/590d3bd9dde0c91f7a66071d40eb84716526e5a6/scripts/download-actionlint.bash) 1.6.25 29 | ./actionlint -color -shellcheck="" 30 | -------------------------------------------------------------------------------- /docs/3.api/5.commands/build-module.md: -------------------------------------------------------------------------------- 1 | # `nuxi build-module` 2 | 3 | ```{bash} 4 | npx nuxi build-module [--stub] [rootDir] 5 | ``` 6 | 7 | The `build-module` command runs `@nuxt/module-builder` to generate `dist` directory within your `rootDir` that contains the full build for your **nuxt-module**. 8 | 9 | Option | Default | Description 10 | -------------------------|-----------------|------------------ 11 | `rootDir` | `.` | The root directory of the module to bundle. 12 | `--stub` | `false` | Stub out your module for development using [jiti](https://github.com/unjs/jiti#jiti). (**note:** This is mainly for development purposes.) 13 | 14 | ::alert 15 | This command is only available when you are using `@nuxt/module-builder` to build your module. Please see [this readme](https://github.com/nuxt/module-builder#-nuxt-module-builder) for more information. 16 | :: 17 | -------------------------------------------------------------------------------- /packages/webpack/src/utils/mfs.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'pathe' 2 | import pify from 'pify' 3 | import { Volume, createFsFromVolume } from 'memfs' 4 | 5 | import type { IFs } from 'memfs' 6 | 7 | export function createMFS () { 8 | // Create a new volume 9 | const fs = createFsFromVolume(new Volume()) 10 | 11 | // Clone to extend 12 | const _fs: IFs & { join?(...paths: string[]): string } = { ...fs } as any 13 | 14 | // fs.join method is (still) expected by webpack-dev-middleware 15 | // There might be differences with https://github.com/webpack/memory-fs/blob/master/lib/join.js 16 | _fs.join = join 17 | 18 | // Used by vue-renderer 19 | _fs.exists = p => Promise.resolve(_fs.existsSync(p)) 20 | // @ts-expect-error need better types for `pify` 21 | _fs.readFile = pify(_fs.readFile) 22 | 23 | return _fs as IFs & { join?(...paths: string[]): string } 24 | } 25 | -------------------------------------------------------------------------------- /docs/2.guide/2.directory-structure/1.assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | navigation.icon: IconDirectory 3 | title: "assets" 4 | description: "The assets/ directory is used to add all the website's assets that the build tool will process." 5 | head.title: "assets/" 6 | --- 7 | 8 | # Assets Directory 9 | 10 | The [`assets/` directory](/docs/guide/directory-structure/assets) is used to add all the website's assets that the build tool (webpack or Vite) will process. 11 | 12 | The directory usually contains the following types of files: 13 | 14 | - Stylesheets (CSS, SASS, etc.) 15 | - Fonts 16 | - Images that won't be served from the [`public/`](/docs/guide/directory-structure/public) directory. 17 | 18 | If you want to serve assets from the server, we recommend taking a look at the [`public/`](/docs/guide/directory-structure/public) directory. 19 | 20 | ::ReadMore{link="/docs/getting-started/assets"} 21 | -------------------------------------------------------------------------------- /docs/3.api/3.utils/clear-error.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "clearError" 3 | description: "The clearError composable clears all handled errors." 4 | --- 5 | 6 | # `clearError` 7 | 8 | Within your pages, components, and plugins, you can use `clearError` to clear all errors and redirect the user. 9 | 10 | **Parameters:** 11 | 12 | - `options?: { redirect?: string }` 13 | 14 | You can provide an optional path to redirect to (for example, if you want to navigate to a 'safe' page). 15 | 16 | ```js 17 | // Without redirect 18 | clearError() 19 | 20 | // With redirect 21 | clearError({ redirect: '/homepage' }) 22 | ``` 23 | 24 | Errors are set in state using [`useError()`](/docs/api/composables/use-error). The `clearError` composable will reset this state and calls the `app:error:cleared` hook with the provided options. 25 | 26 | ::ReadMore{link="/docs/getting-started/error-handling"} 27 | :: 28 | -------------------------------------------------------------------------------- /packages/test-utils/src/experimental.ts: -------------------------------------------------------------------------------- 1 | import { $fetch as _$fetch, fetch as _fetch } from 'ofetch' 2 | import * as _kit from '@nuxt/kit' 3 | import { resolve } from 'pathe' 4 | import { stringifyQuery } from 'ufo' 5 | import { useTestContext } from './context' 6 | import { $fetch } from './server' 7 | 8 | /** 9 | * This is a function to render a component directly with the Nuxt server. 10 | */ 11 | export function $fetchComponent (filepath: string, props?: Record) { 12 | return $fetch(componentTestUrl(filepath, props)) 13 | } 14 | 15 | export function componentTestUrl (filepath: string, props?: Record) { 16 | const ctx = useTestContext() 17 | filepath = resolve(ctx.options.rootDir, filepath) 18 | const path = stringifyQuery({ 19 | path: filepath, 20 | props: JSON.stringify(props) 21 | }) 22 | return `/__nuxt_component_test__/?${path}` 23 | } 24 | -------------------------------------------------------------------------------- /docs/3.api/1.composables/use-server-seo-meta.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The useServerSeoMeta composable lets you define your site's SEO meta tags as a flat object with full TypeScript support. 3 | --- 4 | 5 | # `useServerSeoMeta` 6 | 7 | Just like [`useSeoMeta`](/docs/api/composables/use-seo-meta), [`useServerSeoMeta`](/docs/api/composables/use-server-seo-meta) composable lets you define your site's SEO meta tags as a flat object with full TypeScript support. 8 | :ReadMore{link="/docs/api/composables/use-seo-meta"} 9 | 10 | In most instances, the meta doesn't need to be reactive as robots will only scan the initial load. So we recommend using [`useServerSeoMeta`](/docs/api/composables/use-server-seo-meta) as a performance-focused utility that will not do anything (or return a `head` object) on the client. 11 | Parameters are exactly the same as with [`useSeoMeta`](/docs/api/composables/use-seo-meta) 12 | -------------------------------------------------------------------------------- /packages/nuxt/src/app/components/nuxt-error-boundary.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent, onErrorCaptured, ref } from 'vue' 2 | import { useNuxtApp } from '#app/nuxt' 3 | 4 | export default defineComponent({ 5 | emits: { 6 | error (_error: unknown) { 7 | return true 8 | } 9 | }, 10 | setup (_props, { slots, emit }) { 11 | const error = ref(null) 12 | const nuxtApp = useNuxtApp() 13 | 14 | onErrorCaptured((err, target, info) => { 15 | if (import.meta.client && !nuxtApp.isHydrating) { 16 | emit('error', err) 17 | nuxtApp.hooks.callHook('vue:error', err, target, info) 18 | error.value = err 19 | return false 20 | } 21 | }) 22 | 23 | function clearError () { 24 | error.value = null 25 | } 26 | 27 | return () => error.value ? slots.error?.({ error, clearError }) : slots.default?.() 28 | } 29 | }) 30 | -------------------------------------------------------------------------------- /test/fixtures/basic/components/client/Script.client.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 34 | 35 | 40 | 41 | 46 | -------------------------------------------------------------------------------- /.github/workflows/autofix-docs.yml: -------------------------------------------------------------------------------- 1 | name: autofix.ci # needed to securely identify the workflow 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "docs/**" 7 | - ".github/workflows/docs.yml" 8 | push: 9 | branches: 10 | - "renovate/**" 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | docs: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 21 | - run: corepack enable 22 | - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1 23 | with: 24 | node-version: 20 25 | cache: "pnpm" 26 | 27 | - name: Install dependencies 28 | run: pnpm install 29 | 30 | - name: Lint (docs) 31 | run: pnpm lint:docs:fix 32 | 33 | - uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc 34 | --------------------------------------------------------------------------------