mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
Merge remote-tracking branch 'origin/main' into remove-pending
This commit is contained in:
commit
c376a1f240
@ -1,4 +1,4 @@
|
|||||||
FROM node:lts
|
FROM node:lts@sha256:fffa89e023a3351904c04284029105d9e2ac7020886d683775a298569591e5bb
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
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 && \
|
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 && \
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// https://containers.dev/implementors/json_reference/
|
// https://containers.dev/implementors/json_reference/
|
||||||
{
|
{
|
||||||
"name": "nuxt-devcontainer",
|
"name": "nuxt-devcontainer",
|
||||||
"dockerFile": "Dockerfile",
|
"build": { "dockerfile": "Dockerfile" },
|
||||||
"features": {},
|
"features": {},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
|
168
.eslintrc
168
.eslintrc
@ -1,168 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/eslintrc",
|
|
||||||
"ignorePatterns": [
|
|
||||||
"dist",
|
|
||||||
"public",
|
|
||||||
"node_modules",
|
|
||||||
"packages/schema/schema"
|
|
||||||
],
|
|
||||||
"globals": {
|
|
||||||
"NodeJS": true,
|
|
||||||
"$fetch": true
|
|
||||||
},
|
|
||||||
"plugins": ["jsdoc", "import", "unicorn", "no-only-tests"],
|
|
||||||
"extends": [
|
|
||||||
"plugin:jsdoc/recommended",
|
|
||||||
"@nuxt/eslint-config",
|
|
||||||
"plugin:import/typescript"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"sort-imports": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"ignoreDeclarationSort": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-only-tests/no-only-tests": "error",
|
|
||||||
"unicorn/prefer-node-protocol": "error",
|
|
||||||
"no-console": "warn",
|
|
||||||
"vue/one-component-per-file": "off",
|
|
||||||
"vue/require-default-prop": "off",
|
|
||||||
|
|
||||||
// Vue stylistic rules from `@antfu/eslint-config`
|
|
||||||
"vue/array-bracket-spacing": ["error", "never"],
|
|
||||||
"vue/arrow-spacing": ["error", { "after": true, "before": true }],
|
|
||||||
"vue/block-spacing": ["error", "always"],
|
|
||||||
"vue/block-tag-newline": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"multiline": "always",
|
|
||||||
"singleline": "always"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vue/brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
|
|
||||||
"vue/comma-dangle": ["error", "always-multiline"],
|
|
||||||
"vue/comma-spacing": ["error", { "after": true, "before": false }],
|
|
||||||
"vue/comma-style": ["error", "last"],
|
|
||||||
"vue/html-comment-content-spacing": [
|
|
||||||
"error",
|
|
||||||
"always",
|
|
||||||
{
|
|
||||||
"exceptions": ["-"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vue/key-spacing": ["error", { "afterColon": true, "beforeColon": false }],
|
|
||||||
"vue/keyword-spacing": ["error", { "after": true, "before": true }],
|
|
||||||
"vue/object-curly-newline": "off",
|
|
||||||
"vue/object-curly-spacing": ["error", "always"],
|
|
||||||
"vue/object-property-newline": [
|
|
||||||
"error",
|
|
||||||
{ "allowMultiplePropertiesPerLine": true }
|
|
||||||
],
|
|
||||||
"vue/operator-linebreak": ["error", "before"],
|
|
||||||
"vue/padding-line-between-blocks": ["error", "always"],
|
|
||||||
"vue/quote-props": ["error", "consistent-as-needed"],
|
|
||||||
"vue/space-in-parens": ["error", "never"],
|
|
||||||
"vue/template-curly-spacing": "error",
|
|
||||||
|
|
||||||
"jsdoc/require-jsdoc": "off",
|
|
||||||
"jsdoc/require-param": "off",
|
|
||||||
"jsdoc/require-returns": "off",
|
|
||||||
"jsdoc/require-param-type": "off",
|
|
||||||
"import/order": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"pathGroups": [
|
|
||||||
{
|
|
||||||
"pattern": "#vue-router",
|
|
||||||
"group": "external"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"import/no-restricted-paths": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"zones": [
|
|
||||||
{
|
|
||||||
"from": "packages/nuxt/src/!(core)/**/*",
|
|
||||||
"target": "packages/nuxt/src/core",
|
|
||||||
"message": "core should not directly import from modules."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "packages/nuxt/src/!(app)/**/*",
|
|
||||||
"target": "packages/nuxt/src/app",
|
|
||||||
"message": "app should not directly import from modules."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "packages/nuxt/src/app/**/index.ts",
|
|
||||||
"target": "packages/nuxt/src",
|
|
||||||
"message": "should not import from barrel/index files"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "packages/nitro",
|
|
||||||
"target": "packages/!(nitro)/**/*",
|
|
||||||
"message": "nitro should not directly import other packages."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/consistent-type-imports": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"disallowTypeAnnotations": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/ban-ts-comment": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"ts-expect-error": "allow-with-description",
|
|
||||||
"ts-ignore": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/prefer-ts-expect-error": "error",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"argsIgnorePattern": "^_",
|
|
||||||
"varsIgnorePattern": "^_",
|
|
||||||
"ignoreRestSiblings": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"jsdoc/check-tag-names": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"definedTags": ["__NO_SIDE_EFFECTS__"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["packages/schema/**"],
|
|
||||||
"rules": {
|
|
||||||
"jsdoc/valid-types": "off",
|
|
||||||
"jsdoc/check-tag-names": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"definedTags": ["experimental"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["packages/nuxt/src/app/**", "test/**", "**/runtime/**"],
|
|
||||||
"rules": {
|
|
||||||
"no-console": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"jsdoc": {
|
|
||||||
"ignoreInternal": true,
|
|
||||||
"tagNamePreference": {
|
|
||||||
"warning": "warning",
|
|
||||||
"note": "note"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: "\U0001F41E Bug report"
|
name: "\U0001F41E Bug report"
|
||||||
description: Create a report to help us improve Nuxt
|
description: Create a report to help us improve Nuxt
|
||||||
labels: ["pending triage", "3.x"]
|
labels: ["pending triage"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
@ -36,7 +36,7 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: additonal
|
id: additional
|
||||||
attributes:
|
attributes:
|
||||||
label: Additional context
|
label: Additional context
|
||||||
description: If applicable, add any other context about the problem here
|
description: If applicable, add any other context about the problem here
|
||||||
|
9
.github/ISSUE_TEMPLATE/config.yml
vendored
9
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,11 +1,8 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 📚 Nuxt 3 Documentation
|
- name: 📚 Nuxt Documentation
|
||||||
url: https://nuxt.com/docs/
|
url: https://nuxt.com/docs
|
||||||
about: Check the documentation for usage of Nuxt 3
|
about: Check the documentation for usage of Nuxt
|
||||||
- name: 📚 Nuxt 2 Documentation
|
|
||||||
url: https://v2.nuxt.com/
|
|
||||||
about: Check the documentation for usage of Nuxt 2
|
|
||||||
- name: 💬 Discussions
|
- name: 💬 Discussions
|
||||||
url: https://github.com/nuxt/nuxt/discussions
|
url: https://github.com/nuxt/nuxt/discussions
|
||||||
about: Use discussions if you have another issue, an idea for improvement or for asking questions.
|
about: Use discussions if you have another issue, an idea for improvement or for asking questions.
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: "🚀 Feature request"
|
name: "🚀 Feature request"
|
||||||
description: Suggest a feature that will improve Nuxt
|
description: Suggest a feature that will improve Nuxt
|
||||||
labels: ["pending triage", "3.x"]
|
labels: ["pending triage"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
49
.github/ISSUE_TEMPLATE/z-bug-report-2.yml
vendored
49
.github/ISSUE_TEMPLATE/z-bug-report-2.yml
vendored
@ -1,49 +0,0 @@
|
|||||||
name: "\U0001F41E Bug report (Nuxt 2)"
|
|
||||||
description: Create a report to help us improve Nuxt
|
|
||||||
labels: ["pending triage", "2.x"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Please carefully read the contribution docs before creating a bug report
|
|
||||||
👉 https://nuxt.com/docs/community/reporting-bugs
|
|
||||||
|
|
||||||
Please use a template below to create a minimal reproduction
|
|
||||||
👉 https://stackblitz.com/github/nuxt/starter/tree/v2
|
|
||||||
👉 https://codesandbox.io/s/github/nuxt/starter/v2
|
|
||||||
- type: textarea
|
|
||||||
id: bug-env
|
|
||||||
attributes:
|
|
||||||
label: Environment
|
|
||||||
description: You can use `npx envinfo --system --npmPackages '{nuxt,@nuxt/*}' --binaries --browsers` to fill this section
|
|
||||||
placeholder: Environment
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: reproduction
|
|
||||||
attributes:
|
|
||||||
label: Reproduction
|
|
||||||
description: Please provide a link to a repo that can reproduce the problem you ran into. A [**minimal reproduction**](https://nuxt.com/docs/community/reporting-bugs#create-a-minimal-reproduction) is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "need reproduction" label. If no reproduction is provided we might close it.
|
|
||||||
placeholder: Reproduction
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: bug-description
|
|
||||||
attributes:
|
|
||||||
label: Describe the bug
|
|
||||||
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
|
|
||||||
placeholder: Bug description
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: additonal
|
|
||||||
attributes:
|
|
||||||
label: Additional context
|
|
||||||
description: If applicable, add any other context about the problem here
|
|
||||||
- type: textarea
|
|
||||||
id: logs
|
|
||||||
attributes:
|
|
||||||
label: Logs
|
|
||||||
description: |
|
|
||||||
Optional if provided reproduction. Please try not to insert an image but copy paste the log text.
|
|
||||||
render: shell-script
|
|
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,37 +1,19 @@
|
|||||||
<!---
|
|
||||||
☝️ PR title should follow conventional commits (https://conventionalcommits.org)
|
|
||||||
|
|
||||||
Please carefully read the contribution docs before creating a pull request
|
|
||||||
👉 https://nuxt.com/docs/community/contribution
|
|
||||||
-->
|
|
||||||
|
|
||||||
### 🔗 Linked issue
|
### 🔗 Linked issue
|
||||||
|
|
||||||
<!-- Please ensure there is an open issue and mention its number as #123 -->
|
<!-- Please ensure there is an open issue and mention its number. For example, "resolves #123" -->
|
||||||
|
|
||||||
### ❓ Type of change
|
|
||||||
|
|
||||||
<!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. -->
|
|
||||||
|
|
||||||
- [ ] 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
|
|
||||||
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
|
|
||||||
- [ ] 👌 Enhancement (improving an existing functionality like performance)
|
|
||||||
- [ ] ✨ New feature (a non-breaking change that adds functionality)
|
|
||||||
- [ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries)
|
|
||||||
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
|
|
||||||
|
|
||||||
### 📚 Description
|
### 📚 Description
|
||||||
|
|
||||||
<!-- Describe your changes in detail -->
|
<!-- Describe your changes in detail. Why is this change required? What problem does it solve? -->
|
||||||
<!-- Why is this change required? What problem does it solve? -->
|
|
||||||
<!-- If it resolves an open issue, please link to the issue here. For example "Resolves #1337" -->
|
|
||||||
|
|
||||||
### 📝 Checklist
|
<!----------------------------------------------------------------------
|
||||||
|
Before creating the pull request, please make sure you do the following:
|
||||||
|
|
||||||
<!-- Put an `x` in all the boxes that apply. -->
|
- Check that there isn't already a PR that solves the problem the same way. If you find a duplicate, please help us reviewing it.
|
||||||
<!-- If your change requires a documentation PR, please link it appropriately -->
|
- Read the contribution docs at https://nuxt.com/docs/community/contribution
|
||||||
<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
- Ensure that PR title follows conventional commits (https://www.conventionalcommits.org)
|
||||||
|
- Update the corresponding documentation if needed.
|
||||||
|
- Include relevant tests that fail without this PR but pass with it.
|
||||||
|
|
||||||
- [ ] I have linked an issue or discussion.
|
Thank you for contributing to Nuxt!
|
||||||
- [ ] I have added tests (if possible).
|
----------------------------------------------------------------------->
|
||||||
- [ ] I have updated the documentation accordingly.
|
|
||||||
|
10
.github/codeql/codeql-config.yml
vendored
Normal file
10
.github/codeql/codeql-config.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
paths:
|
||||||
|
- 'packages/*/dist/**'
|
||||||
|
- 'packages/nuxt/bin/**'
|
||||||
|
- 'packages/schema/schema/**'
|
||||||
|
paths-ignore:
|
||||||
|
- 'test/**'
|
||||||
|
- '**/*.test.js'
|
||||||
|
- '**/*.test.ts'
|
||||||
|
- '**/*.test.tsx'
|
||||||
|
- '**/__tests__/**'
|
9
.github/workflows/autofix-docs.yml
vendored
9
.github/workflows/autofix-docs.yml
vendored
@ -17,9 +17,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -27,7 +27,10 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Build (stub)
|
||||||
|
run: pnpm dev:prepare
|
||||||
|
|
||||||
- name: Lint (docs)
|
- name: Lint (docs)
|
||||||
run: pnpm lint:docs:fix
|
run: pnpm lint:docs:fix
|
||||||
|
|
||||||
- uses: autofix-ci/action@ea32e3a12414e6d3183163c3424a7d7a8631ad84
|
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
|
||||||
|
12
.github/workflows/autofix.yml
vendored
12
.github/workflows/autofix.yml
vendored
@ -13,9 +13,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -26,9 +26,6 @@ jobs:
|
|||||||
- name: Build (stub)
|
- name: Build (stub)
|
||||||
run: pnpm dev:prepare
|
run: pnpm dev:prepare
|
||||||
|
|
||||||
- name: Lint (code)
|
|
||||||
run: pnpm lint:fix
|
|
||||||
|
|
||||||
- name: Test (unit)
|
- name: Test (unit)
|
||||||
run: pnpm test:unit -u
|
run: pnpm test:unit -u
|
||||||
|
|
||||||
@ -52,4 +49,7 @@ jobs:
|
|||||||
if: ${{ !contains(github.head_ref, 'renovate') }}
|
if: ${{ !contains(github.head_ref, 'renovate') }}
|
||||||
run: pnpm vitest run bundle -u
|
run: pnpm vitest run bundle -u
|
||||||
|
|
||||||
- uses: autofix-ci/action@ea32e3a12414e6d3183163c3424a7d7a8631ad84
|
- name: Lint (code)
|
||||||
|
run: pnpm lint:fix
|
||||||
|
|
||||||
|
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
|
||||||
|
8
.github/workflows/benchmark.yml
vendored
8
.github/workflows/benchmark.yml
vendored
@ -15,8 +15,6 @@ env:
|
|||||||
# 7 GiB by default on GitHub, setting to 6 GiB
|
# 7 GiB by default on GitHub, setting to 6 GiB
|
||||||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||||
NODE_OPTIONS: --max-old-space-size=6144
|
NODE_OPTIONS: --max-old-space-size=6144
|
||||||
# install playwright binary manually (because pnpm only runs install script once)
|
|
||||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
@ -31,9 +29,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -48,7 +46,7 @@ jobs:
|
|||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Run benchmarks
|
- name: Run benchmarks
|
||||||
uses: CodSpeedHQ/action@fce3a2f16d0b352af341dcacb25caadfd9159055 # v2.1.1
|
uses: CodSpeedHQ/action@ab07afd34cbbb7a1306e8d14b7cc44e029eee37a # v3.0.0
|
||||||
with:
|
with:
|
||||||
run: pnpm vitest bench
|
run: pnpm vitest bench
|
||||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||||
|
38
.github/workflows/cache-cleanup.yml
vendored
Normal file
38
.github/workflows/cache-cleanup.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# From https://github.com/actions/cache/blob/main/tips-and-workarounds.md#force-deletion-of-caches-overriding-default-cache-eviction-policy
|
||||||
|
|
||||||
|
name: cache
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
# `actions:write` permission is required to delete caches
|
||||||
|
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
|
||||||
|
actions: write
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Cleanup
|
||||||
|
run: |
|
||||||
|
gh extension install actions/gh-actions-cache
|
||||||
|
|
||||||
|
echo "Fetching list of cache keys"
|
||||||
|
cacheKeysForPR=$(gh actions-cache list -R "$REPO" -B "$BRANCH" -L 100 | cut -f 1 )
|
||||||
|
|
||||||
|
## Setting this to not fail the workflow while deleting cache keys.
|
||||||
|
set +e
|
||||||
|
echo "Deleting caches..."
|
||||||
|
for cacheKey in $cacheKeysForPR
|
||||||
|
do
|
||||||
|
gh actions-cache delete "$cacheKey" -R "$REPO" -B "$BRANCH" --confirm
|
||||||
|
done
|
||||||
|
echo "Done"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
|
@ -1,30 +1,32 @@
|
|||||||
name: Release
|
name: changelog
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- 2.x
|
- 3.x
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
pull-requests: write
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
|
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
|
||||||
cancel-in-progress: ${{ github.event_name != 'push' }}
|
cancel-in-progress: ${{ github.event_name != 'push' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-changelog:
|
update:
|
||||||
if: github.repository_owner == 'nuxt' && !contains(github.event.head_commit.message, 'v3.')
|
if: github.repository_owner == 'nuxt' && !contains(github.event.head_commit.message, 'v3.') && !contains(github.event.head_commit.message, 'v4.')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
122
.github/workflows/ci.yml
vendored
122
.github/workflows/ci.yml
vendored
@ -7,12 +7,14 @@ on:
|
|||||||
- "*.md"
|
- "*.md"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "*.md"
|
- "*.md"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
- "!v[0-9]*"
|
- "!v[0-9]*"
|
||||||
|
|
||||||
# https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml
|
# https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml
|
||||||
@ -20,8 +22,6 @@ env:
|
|||||||
# 7 GiB by default on GitHub, setting to 6 GiB
|
# 7 GiB by default on GitHub, setting to 6 GiB
|
||||||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||||
NODE_OPTIONS: --max-old-space-size=6144
|
NODE_OPTIONS: --max-old-space-size=6144
|
||||||
# install playwright binary manually (because pnpm only runs install script once)
|
|
||||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
@ -37,9 +37,9 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -57,7 +57,7 @@ jobs:
|
|||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Cache dist
|
- name: Cache dist
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
|
||||||
with:
|
with:
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
name: dist
|
name: dist
|
||||||
@ -70,36 +70,30 @@ jobs:
|
|||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
security-events: write
|
security-events: write
|
||||||
needs:
|
|
||||||
- build
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: "pnpm"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
config: |
|
||||||
|
paths:
|
||||||
|
- 'packages/*/src/**'
|
||||||
|
- 'packages/nuxt/bin/**'
|
||||||
|
- 'packages/schema/schema/**'
|
||||||
|
paths-ignore:
|
||||||
|
- 'test/**'
|
||||||
|
- '**/*.spec.ts'
|
||||||
|
- '**/*.test.ts'
|
||||||
|
- '**/__snapshots__/**'
|
||||||
|
languages: javascript-typescript
|
||||||
queries: +security-and-quality
|
queries: +security-and-quality
|
||||||
|
|
||||||
- name: Restore dist cache
|
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
|
|
||||||
with:
|
|
||||||
name: dist
|
|
||||||
path: packages
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
|
||||||
with:
|
with:
|
||||||
category: "/language:javascript"
|
category: "/language:javascript-typescript"
|
||||||
|
|
||||||
typecheck:
|
typecheck:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
@ -113,9 +107,9 @@ jobs:
|
|||||||
module: ["bundler", "node"]
|
module: ["bundler", "node"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -124,7 +118,7 @@ jobs:
|
|||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Restore dist cache
|
- name: Restore dist cache
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: packages
|
path: packages
|
||||||
@ -144,9 +138,9 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -168,9 +162,9 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- build
|
- build
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -200,8 +194,17 @@ jobs:
|
|||||||
builder: ["vite", "webpack"]
|
builder: ["vite", "webpack"]
|
||||||
context: ["async", "default"]
|
context: ["async", "default"]
|
||||||
manifest: ["manifest-on", "manifest-off"]
|
manifest: ["manifest-on", "manifest-off"]
|
||||||
|
payload: ["json", "js"]
|
||||||
node: [18]
|
node: [18]
|
||||||
exclude:
|
exclude:
|
||||||
|
- builder: "webpack"
|
||||||
|
payload: "js"
|
||||||
|
- manifest: "manifest-off"
|
||||||
|
payload: "js"
|
||||||
|
- context: "default"
|
||||||
|
payload: "js"
|
||||||
|
- os: windows-latest
|
||||||
|
payload: "js"
|
||||||
- env: "dev"
|
- env: "dev"
|
||||||
builder: "webpack"
|
builder: "webpack"
|
||||||
- manifest: "manifest-off"
|
- manifest: "manifest-off"
|
||||||
@ -210,9 +213,9 @@ jobs:
|
|||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -220,34 +223,11 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
# Install playwright's binary under custom directory to cache
|
|
||||||
- name: (non-windows) Set Playwright path and Get playwright version
|
|
||||||
if: runner.os != 'Windows'
|
|
||||||
run: |
|
|
||||||
echo "PLAYWRIGHT_BROWSERS_PATH=$HOME/.cache/playwright-bin" >> $GITHUB_ENV
|
|
||||||
PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright-core | jq --raw-output '.[0].devDependencies["playwright-core"].version')"
|
|
||||||
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: (windows) Set Playwright path and Get playwright version
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
echo "PLAYWRIGHT_BROWSERS_PATH=$HOME\.cache\playwright-bin" >> $env:GITHUB_ENV
|
|
||||||
$env:PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright-core | jq --raw-output '.[0].devDependencies["playwright-core"].version')"
|
|
||||||
echo "PLAYWRIGHT_VERSION=$env:PLAYWRIGHT_VERSION" >> $env:GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Cache Playwright's binary
|
|
||||||
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
|
||||||
with:
|
|
||||||
key: ${{ runner.os }}-playwright-bin-v1-${{ env.PLAYWRIGHT_VERSION }}
|
|
||||||
path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-playwright-bin-v1-
|
|
||||||
|
|
||||||
- name: Install Playwright
|
- name: Install Playwright
|
||||||
run: pnpm playwright-core install chromium
|
run: pnpm playwright-core install chromium
|
||||||
|
|
||||||
- name: Restore dist cache
|
- name: Restore dist cache
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: packages
|
path: packages
|
||||||
@ -259,21 +239,23 @@ jobs:
|
|||||||
TEST_BUILDER: ${{ matrix.builder }}
|
TEST_BUILDER: ${{ matrix.builder }}
|
||||||
TEST_MANIFEST: ${{ matrix.manifest }}
|
TEST_MANIFEST: ${{ matrix.manifest }}
|
||||||
TEST_CONTEXT: ${{ matrix.context }}
|
TEST_CONTEXT: ${{ matrix.context }}
|
||||||
SKIP_BUNDLE_SIZE: ${{ github.event_name != 'push' || matrix.env == 'dev' || matrix.builder == 'webpack' || matrix.context == 'default' || runner.os == 'Windows' }}
|
TEST_PAYLOAD: ${{ matrix.payload }}
|
||||||
|
SKIP_BUNDLE_SIZE: ${{ github.event_name != 'push' || matrix.env == 'dev' || matrix.builder == 'webpack' || matrix.context == 'default' || matrix.payload == 'js' || runner.os == 'Windows' }}
|
||||||
|
|
||||||
- uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # v4.0.1
|
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
|
||||||
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
build-release:
|
build-release:
|
||||||
|
concurrency:
|
||||||
|
group: release
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
if: |
|
if: |
|
||||||
github.event_name == 'push' &&
|
github.event_name == 'push' &&
|
||||||
github.repository == 'nuxt/nuxt' &&
|
github.repository == 'nuxt/nuxt' &&
|
||||||
!contains(github.event.head_commit.message, '[skip-release]') &&
|
!contains(github.event.head_commit.message, '[skip-release]') &&
|
||||||
!startsWith(github.event.head_commit.message, 'chore') &&
|
|
||||||
!startsWith(github.event.head_commit.message, 'docs')
|
!startsWith(github.event.head_commit.message, 'docs')
|
||||||
needs:
|
needs:
|
||||||
- lint
|
- lint
|
||||||
@ -283,11 +265,11 @@ jobs:
|
|||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -296,18 +278,20 @@ jobs:
|
|||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Restore dist cache
|
- name: Restore dist cache
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: packages
|
path: packages
|
||||||
|
|
||||||
- name: Release Edge
|
- name: Release Edge
|
||||||
run: ./scripts/release-edge.sh
|
run: ./scripts/release-edge.sh ${{ github.ref == 'refs/heads/main' && 'latest' || '3x' }}
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
||||||
NPM_CONFIG_PROVENANCE: true
|
NPM_CONFIG_PROVENANCE: true
|
||||||
|
|
||||||
release-pr:
|
release-pr:
|
||||||
|
concurrency:
|
||||||
|
group: release
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
@ -322,11 +306,11 @@ jobs:
|
|||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -335,7 +319,7 @@ jobs:
|
|||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Restore dist cache
|
- name: Restore dist cache
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: packages
|
path: packages
|
||||||
|
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
@ -17,6 +17,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@fd07d42ce87ab09f10c61a2d1a5e59e6c655620a # v4.1.1
|
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
name: Check links with Lychee
|
name: docs
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -7,6 +7,7 @@ on:
|
|||||||
- "*.md"
|
- "*.md"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
@ -18,17 +19,17 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Cache lychee results (e.g. to avoid hitting rate limits)
|
# Cache lychee results (e.g. to avoid hitting rate limits)
|
||||||
- name: Restore lychee cache
|
- name: Restore lychee cache
|
||||||
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0
|
||||||
with:
|
with:
|
||||||
path: .lycheecache
|
path: .lycheecache
|
||||||
key: cache-lychee-${{ github.sha }}
|
key: cache-lychee-${{ github.sha }}
|
||||||
restore-keys: cache-lychee-
|
restore-keys: cache-lychee-
|
||||||
|
|
||||||
# check links with Lychee
|
# check links with Lychee
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Lychee link checker
|
- name: Lychee link checker
|
||||||
uses: lycheeverse/lychee-action@c053181aa0c3d17606addfe97a9075a32723548a # for v1.8.0
|
uses: lycheeverse/lychee-action@f87f0a62993c2647717456af92593666acb3a500 # for v1.8.0
|
||||||
with:
|
with:
|
||||||
# arguments with file types to check
|
# arguments with file types to check
|
||||||
args: >-
|
args: >-
|
4
.github/workflows/docs-deploy.yml
vendored
4
.github/workflows/docs-deploy.yml
vendored
@ -1,11 +1,11 @@
|
|||||||
name: Deploy docs
|
name: docs
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- 3.x
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
|
10
.github/workflows/docs.yml
vendored
10
.github/workflows/docs.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Docs
|
name: docs
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -9,6 +9,7 @@ on:
|
|||||||
# autofix workflow will be triggered instead for PRs
|
# autofix workflow will be triggered instead for PRs
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
- "!v[0-9]*"
|
- "!v[0-9]*"
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
@ -20,9 +21,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -30,6 +31,9 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Build (stub)
|
||||||
|
run: pnpm dev:prepare
|
||||||
|
|
||||||
- name: Lint (docs)
|
- name: Lint (docs)
|
||||||
run: pnpm lint:docs
|
run: pnpm lint:docs
|
||||||
|
|
||||||
|
28
.github/workflows/label-issue.yml
vendored
Normal file
28
.github/workflows/label-issue.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: chore
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-issue-labels:
|
||||||
|
name: Add labels
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'nuxt/nuxt'
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
// add 'pending triage' label if issue is created with no labels
|
||||||
|
if (context.payload.issue.labels.length === 0) {
|
||||||
|
github.rest.issues.addLabels({
|
||||||
|
issue_number: context.payload.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
labels: ['pending triage']
|
||||||
|
})
|
||||||
|
}
|
5
.github/workflows/label-pr.yml
vendored
5
.github/workflows/label-pr.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Label PR
|
name: chore
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
@ -6,6 +6,9 @@ on:
|
|||||||
- opened
|
- opened
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
add-pr-labels:
|
add-pr-labels:
|
||||||
|
36
.github/workflows/lint-sherif.yml
vendored
Normal file
36
.github/workflows/lint-sherif.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "**/package.json"
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- 3.x
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "**/package.json"
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- 3.x
|
||||||
|
- "!v[0-9]*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-monorepo:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
- run: corepack enable
|
||||||
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
|
- name: Lint monorepo
|
||||||
|
run: pnpm sherif -r multiple-dependency-versions
|
@ -6,11 +6,13 @@ on:
|
|||||||
- ".github/workflows/**"
|
- ".github/workflows/**"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/**"
|
- ".github/workflows/**"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 3.x
|
||||||
- "!v[0-9]*"
|
- "!v[0-9]*"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@ -21,9 +23,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
# From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions
|
# From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions
|
||||||
- name: Check workflow files
|
- name: Check workflow files
|
||||||
run: |
|
uses: docker://rhysd/actionlint:1.7.3@sha256:7617f05bd698cd2f1c3aedc05bc733ccec92cca0738f3e8722c32c5b42c70ae6
|
||||||
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/590d3bd9dde0c91f7a66071d40eb84716526e5a6/scripts/download-actionlint.bash) 1.6.25
|
with:
|
||||||
./actionlint -color -shellcheck=""
|
args: -color
|
3
.github/workflows/notify-nuxt-bridge.yml
vendored
3
.github/workflows/notify-nuxt-bridge.yml
vendored
@ -4,6 +4,9 @@ on:
|
|||||||
types: [closed]
|
types: [closed]
|
||||||
paths:
|
paths:
|
||||||
- "packages/nuxt/src/app/composables/**"
|
- "packages/nuxt/src/app/composables/**"
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
notify:
|
notify:
|
||||||
if: github.event.pull_request.merged == true
|
if: github.event.pull_request.merged == true
|
||||||
|
61
.github/workflows/nuxt2-edge.yml
vendored
61
.github/workflows/nuxt2-edge.yml
vendored
@ -1,61 +0,0 @@
|
|||||||
name: nuxt2-nightly
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
# https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml
|
|
||||||
env:
|
|
||||||
# 7 GiB by default on GitHub, setting to 6 GiB
|
|
||||||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
|
||||||
NODE_OPTIONS: --max-old-space-size=6144
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
nightly:
|
|
||||||
if: github.repository_owner == 'nuxt'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
id-token: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
with:
|
|
||||||
ref: '2.x'
|
|
||||||
fetch-depth: 0 # All history
|
|
||||||
- name: fetch tags
|
|
||||||
run: git fetch --depth=1 origin "+refs/tags/*:refs/tags/*"
|
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
- name: install
|
|
||||||
run: yarn --check-files --frozen-lockfile --non-interactive
|
|
||||||
- name: lint
|
|
||||||
run: yarn test:lint
|
|
||||||
- name: audit
|
|
||||||
run: yarn run audit
|
|
||||||
- name: build
|
|
||||||
run: yarn test:fixtures -i
|
|
||||||
- name: lint app
|
|
||||||
run: yarn lint:app
|
|
||||||
- name: test types
|
|
||||||
run: yarn test:types
|
|
||||||
- name: test dev
|
|
||||||
run: yarn test:dev
|
|
||||||
- name: test unit
|
|
||||||
run: yarn test:unit
|
|
||||||
- name: test e2e
|
|
||||||
run: yarn test:e2e
|
|
||||||
- name: bump version
|
|
||||||
run: yarn lerna version --yes --no-changelog --no-git-tag-version --no-push --force-publish "*" --loglevel verbose
|
|
||||||
- name: build
|
|
||||||
run: PACKAGE_SUFFIX=edge yarn build
|
|
||||||
- name: publish
|
|
||||||
run: ./scripts/workspace-run npm publish -q
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
|
||||||
NPM_CONFIG_PROVENANCE: true
|
|
||||||
|
|
31
.github/workflows/release-pr.yml
vendored
31
.github/workflows/release-pr.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: release
|
name: release-pr
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issue_comment:
|
issue_comment:
|
||||||
@ -14,6 +14,8 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
release-pr:
|
release-pr:
|
||||||
if: github.repository == 'nuxt/nuxt' && github.event.issue.pull_request && github.event.comment.body == '/trigger release'
|
if: github.repository == 'nuxt/nuxt' && github.event.issue.pull_request && github.event.comment.body == '/trigger release'
|
||||||
|
concurrency:
|
||||||
|
group: release
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
@ -22,20 +24,37 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Ensure action is by maintainer
|
- name: Ensure action is by maintainer
|
||||||
uses: octokit/request-action@89697eb6635e52c6e1e5559f15b5c91ba5100cb0 # v2.1.9
|
uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0
|
||||||
id: check_role
|
id: check_role
|
||||||
with:
|
with:
|
||||||
route: GET /repos/nuxt/nuxt/collaborators/${{ github.event.comment.user.login }}
|
route: GET /repos/nuxt/nuxt/collaborators/${{ github.event.comment.user.login }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- name: Get PR Info
|
||||||
|
id: pr
|
||||||
|
env:
|
||||||
|
PR_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
|
COMMENT_AT: ${{ github.event.comment.created_at }}
|
||||||
|
run: |
|
||||||
|
pr="$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/"${GH_REPO}"/pulls/"${PR_NUMBER}")"
|
||||||
|
head_sha="$(echo "$pr" | jq -r .head.sha)"
|
||||||
|
updated_at="$(echo "$pr" | jq -r .updated_at)"
|
||||||
|
|
||||||
|
if [[ $(date -d "$updated_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT"
|
||||||
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: refs/pull/${{ github.event.issue.number }}/merge
|
ref: ${{ steps.pr.outputs.head_sha }}
|
||||||
fetch-depth: 0
|
fetch-depth: 1
|
||||||
|
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
42
.github/workflows/release.yml
vendored
Normal file
42
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
# Remove default permissions of GITHUB_TOKEN for security
|
||||||
|
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
if: github.repository == 'nuxt/nuxt' && (startsWith(github.event.head_commit.message, 'v3.') || startsWith(github.event.head_commit.message, 'v4.'))
|
||||||
|
concurrency:
|
||||||
|
group: release
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- run: corepack enable
|
||||||
|
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
registry-url: "https://registry.npmjs.org/"
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Build (stub)
|
||||||
|
run: pnpm dev:prepare
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
run: ./scripts/release.sh
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{secrets.RELEASE_NODE_AUTH_TOKEN}}
|
||||||
|
NPM_CONFIG_PROVENANCE: true
|
4
.github/workflows/reproduire.yml
vendored
4
.github/workflows/reproduire.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Reproduire
|
name: chore
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [labeled]
|
types: [labeled]
|
||||||
@ -10,7 +10,7 @@ jobs:
|
|||||||
reproduire:
|
reproduire:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp
|
- uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp
|
||||||
with:
|
with:
|
||||||
label: needs reproduction
|
label: needs reproduction
|
||||||
|
13
.github/workflows/scorecards.yml
vendored
13
.github/workflows/scorecards.yml
vendored
@ -2,7 +2,7 @@
|
|||||||
# by a third-party and are governed by separate terms of service, privacy
|
# by a third-party and are governed by separate terms of service, privacy
|
||||||
# policy, and support documentation.
|
# policy, and support documentation.
|
||||||
|
|
||||||
name: Scorecard supply-chain security
|
name: ossf
|
||||||
on:
|
on:
|
||||||
# For Branch-Protection check. Only the default branch is supported. See
|
# For Branch-Protection check. Only the default branch is supported. See
|
||||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||||
@ -28,15 +28,16 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
contents: read
|
contents: read
|
||||||
actions: read
|
actions: read
|
||||||
|
if: github.event_name == 'push' || github.repository == 'nuxt/nuxt'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
@ -58,7 +59,8 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
|
||||||
|
if: github.repository == 'nuxt/nuxt' && success()
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
@ -66,6 +68,7 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
|
||||||
|
if: github.repository == 'nuxt/nuxt' && success()
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
12
.github/workflows/semantic-pull-requests.yml
vendored
12
.github/workflows/semantic-pull-requests.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Semantic pull request
|
name: chore
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
@ -7,12 +7,12 @@ on:
|
|||||||
- edited
|
- edited
|
||||||
- synchronize
|
- synchronize
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
semantic-pr:
|
||||||
permissions:
|
permissions:
|
||||||
|
contents: read
|
||||||
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
|
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
|
||||||
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
|
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
|
||||||
if: github.repository == 'nuxt/nuxt' && !startsWith(github.head_ref, 'v')
|
if: github.repository == 'nuxt/nuxt' && !startsWith(github.head_ref, 'v')
|
||||||
@ -20,14 +20,16 @@ jobs:
|
|||||||
name: Semantic pull request
|
name: Semantic pull request
|
||||||
steps:
|
steps:
|
||||||
- name: Validate PR title
|
- name: Validate PR title
|
||||||
uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f # v5.4.0
|
uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
|
||||||
with:
|
with:
|
||||||
scopes: |
|
scopes: |
|
||||||
kit
|
kit
|
||||||
nuxi
|
nuxi
|
||||||
nuxt
|
nuxt
|
||||||
|
rspack
|
||||||
schema
|
schema
|
||||||
test-utils
|
test-utils
|
||||||
|
ui-templates
|
||||||
vite
|
vite
|
||||||
webpack
|
webpack
|
||||||
deps
|
deps
|
||||||
|
17
.github/workflows/stackblitz-link.yml
vendored
Normal file
17
.github/workflows/stackblitz-link.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: chore
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
opened
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stackblitz:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
- uses: huang-julien/reproduire-sur-stackblitz@9ceccbfbb0f2f9a9a8db2d1f0dd909cf5cfe67aa # v1.0.2
|
||||||
|
with:
|
||||||
|
reproduction-heading: '### Reproduction'
|
@ -1,4 +1,4 @@
|
|||||||
name: Close incomplete issues
|
name: chore
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
@ -10,6 +10,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'workflow_dispatch' || github.repository == 'nuxt/nuxt'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||||
with:
|
with:
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -73,3 +73,5 @@ Temporary Items
|
|||||||
|
|
||||||
fixtures-temp
|
fixtures-temp
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
|
eslint-typegen.d.ts
|
||||||
|
.eslintcache
|
||||||
|
5
.npmrc
5
.npmrc
@ -1,3 +1,4 @@
|
|||||||
shamefully-hoist=true
|
# TODO: consider resolving webpack loaders to absolute path
|
||||||
strict-peer-dependencies=false
|
public-hoist-pattern[]=*-loader
|
||||||
|
public-hoist-pattern[]=webpack-*
|
||||||
shell-emulator=true
|
shell-emulator=true
|
||||||
|
1
CODEOWNERS
Normal file
1
CODEOWNERS
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @danielroe
|
64
README.md
64
README.md
@ -5,7 +5,7 @@
|
|||||||
<p>
|
<p>
|
||||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a>
|
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a>
|
||||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a>
|
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a>
|
||||||
<a href="./LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
|
<a href="https://github.com/nuxt/nuxt/tree/main/LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
|
||||||
<a href="https://nuxt.com"><img src="https://img.shields.io/badge/Nuxt%20Docs-18181B?logo=nuxt.js" alt="Website"></a>
|
<a href="https://nuxt.com"><img src="https://img.shields.io/badge/Nuxt%20Docs-18181B?logo=nuxt.js" alt="Website"></a>
|
||||||
<a href="https://chat.nuxt.dev"><img src="https://img.shields.io/badge/Nuxt%20Discord-18181B?logo=discord" alt="Discord"></a>
|
<a href="https://chat.nuxt.dev"><img src="https://img.shields.io/badge/Nuxt%20Discord-18181B?logo=discord" alt="Discord"></a>
|
||||||
</p>
|
</p>
|
||||||
@ -13,16 +13,33 @@
|
|||||||
Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.
|
Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.
|
||||||
|
|
||||||
It provides a number of features that make it easy to build fast, SEO-friendly, and scalable web applications, including:
|
It provides a number of features that make it easy to build fast, SEO-friendly, and scalable web applications, including:
|
||||||
- Server-side rendering, Static Site Generation or Hybrid Rendering
|
- Server-side rendering, Static Site Generation, Hybrid Rendering and Edge-Side Rendering
|
||||||
- Automatic routing with code-splitting
|
- Automatic routing with code-splitting and pre-fetching
|
||||||
- State management
|
- Data fetching and state management
|
||||||
- SEO Optimization
|
- SEO Optimization and Meta tags definition
|
||||||
- Auto imports
|
- Auto imports of components, composables and utils
|
||||||
- Extensible with [180+ modules](https://nuxt.com/modules)
|
- TypeScript with zero configuration
|
||||||
|
- Go fullstack with our server/ directory
|
||||||
|
- Extensible with [200+ modules](https://nuxt.com/modules)
|
||||||
- Deployment to a variety of [hosting platforms](https://nuxt.com/deploy)
|
- Deployment to a variety of [hosting platforms](https://nuxt.com/deploy)
|
||||||
- ...[and much more](https://nuxt.com) 🚀
|
- ...[and much more](https://nuxt.com) 🚀
|
||||||
|
|
||||||
## Getting Started
|
### Table of Contents
|
||||||
|
|
||||||
|
- 🚀 [Getting Started](#getting-started)
|
||||||
|
- 💻 [ Vue Development](#vue-development)
|
||||||
|
- 📖 [Documentation](#documentation)
|
||||||
|
- 🧩 [Modules](#modules)
|
||||||
|
- ❤️ [Contribute](#contribute)
|
||||||
|
- 🏠 [Local Development](#local-development)
|
||||||
|
- ⛰️ [Nuxt 2](#nuxt-2)
|
||||||
|
- 🛟 [Professional Support](#professional-support)
|
||||||
|
- 🔗 [Follow Us](#follow-us)
|
||||||
|
- ⚖️ [License](#license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## <a name="getting-started">🚀 Getting Started</a>
|
||||||
|
|
||||||
Use the following command to create a new starter project. This will create a starter project with all the necessary files and dependencies:
|
Use the following command to create a new starter project. This will create a starter project with all the necessary files and dependencies:
|
||||||
|
|
||||||
@ -30,9 +47,10 @@ Use the following command to create a new starter project. This will create a st
|
|||||||
npx nuxi@latest init <my-project>
|
npx nuxi@latest init <my-project>
|
||||||
```
|
```
|
||||||
|
|
||||||
Discover also [nuxt.new](https://nuxt.new): Open a Nuxt starter on CodeSandbox, StackBlitz or locally to get up and running in a few seconds.
|
> [!TIP]
|
||||||
|
> Discover also [nuxt.new](https://nuxt.new): Open a Nuxt starter on CodeSandbox, StackBlitz or locally to get up and running in a few seconds.
|
||||||
|
|
||||||
## Vue Development
|
## <a name="vue-development">💻 Vue Development</a>
|
||||||
|
|
||||||
Simple, intuitive and powerful, Nuxt lets you write Vue components in a way that makes sense. Every repetitive task is automated, so you can focus on writing your full-stack Vue application with confidence.
|
Simple, intuitive and powerful, Nuxt lets you write Vue components in a way that makes sense. Every repetitive task is automated, so you can focus on writing your full-stack Vue application with confidence.
|
||||||
|
|
||||||
@ -54,7 +72,7 @@ useSeoMeta({
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style scoped>
|
||||||
#app {
|
#app {
|
||||||
background-color: #020420;
|
background-color: #020420;
|
||||||
color: #00DC82;
|
color: #00DC82;
|
||||||
@ -62,38 +80,38 @@ useSeoMeta({
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## <a name="documentation">📖 Documentation</a>
|
||||||
|
|
||||||
We highly recommend you take a look at the [Nuxt documentation](https://nuxt.com/docs) to level up. It’s a great resource for learning more about the framework. It covers everything from getting started to advanced topics.
|
We highly recommend you take a look at the [Nuxt documentation](https://nuxt.com/docs) to level up. It’s a great resource for learning more about the framework. It covers everything from getting started to advanced topics.
|
||||||
|
|
||||||
## Modules
|
## <a name="modules">🧩 Modules</a>
|
||||||
|
|
||||||
Discover our [list of modules](https://nuxt.com/modules) to supercharge your Nuxt project, created by the Nuxt team and community.
|
Discover our [list of modules](https://nuxt.com/modules) to supercharge your Nuxt project, created by the Nuxt team and community.
|
||||||
|
|
||||||
## Contribute
|
## <a name="contribute">❤️ Contribute</a>
|
||||||
|
|
||||||
We invite you to contribute and help improve Nuxt 💚
|
We invite you to contribute and help improve Nuxt 💚
|
||||||
|
|
||||||
Here are a few ways you can get involved:
|
Here are a few ways you can get involved:
|
||||||
- **Reporting Bugs:** If you come across any bugs or issues, please check out the [reporting bugs guide](https://nuxt.com/docs/community/reporting-bugs) to learn how to submit a bug report.
|
- **Reporting Bugs:** If you come across any bugs or issues, please check out the [reporting bugs guide](https://nuxt.com/docs/community/reporting-bugs) to learn how to submit a bug report.
|
||||||
- **Suggestions:** Have ideas to enhance Nuxt? We'd love to hear them! Check out the [contribution guide](https://nuxt.com/docs/community/contribution#creating-an-issue) to share your suggestions.
|
- **Suggestions:** Have ideas to enhance Nuxt? We'd love to hear them! Check out the [contribution guide](https://nuxt.com/docs/community/contribution) to share your suggestions.
|
||||||
- **Questions:** If you have questions or need assistance, the [getting help guide](https://nuxt.com/docs/community/getting-help) provides resources to help you out.
|
- **Questions:** If you have questions or need assistance, the [getting help guide](https://nuxt.com/docs/community/getting-help) provides resources to help you out.
|
||||||
|
|
||||||
## Local Development
|
## <a name="local-development">🏠 Local Development</a>
|
||||||
|
|
||||||
Follow the docs to [Set Up Your Local Development Environment](https://nuxt.com/docs/community/framework-contribution#setup) to contribute to the framework and documentation.
|
Follow the docs to [Set Up Your Local Development Environment](https://nuxt.com/docs/community/framework-contribution#setup) to contribute to the framework and documentation.
|
||||||
|
|
||||||
## Nuxt 2
|
## <a name="professional-support">🛟 Professional Support</a>
|
||||||
|
|
||||||
You can find the code for Nuxt 2 on the [`2.x` branch](https://github.com/nuxt/nuxt/tree/2.x) and the documentation at [v2.nuxt.com](https://v2.nuxt.com).
|
- Technical audit & consulting: [Nuxt Experts](https://nuxt.com/enterprise/support)
|
||||||
|
- Custom development & more: [Nuxt Agencies Partners](https://nuxt.com/enterprise/agencies)
|
||||||
|
|
||||||
## Follow us
|
## <a name="follow-us">🔗 Follow Us</a>
|
||||||
|
|
||||||
<p valign="center">
|
<p valign="center">
|
||||||
<a href="https://chat.nuxt.dev"><img width="20px" src="./.github/assets/discord.svg" alt="Discord"></a> <a href="https://twitter.nuxt.dev"><img width="20px" src="./.github/assets/twitter.svg" alt="Twitter"></a> <a href="https://github.nuxt.dev"><img width="20px" src="./.github/assets/github.svg" alt="GitHub"></a>
|
<a href="https://go.nuxt.com/discord"><img width="20px" src="./.github/assets/discord.svg" alt="Discord"></a> <a href="https://go.nuxt.com/x"><img width="20px" src="./.github/assets/twitter.svg" alt="Twitter"></a> <a href="https://go.nuxt.com/github"><img width="20px" src="./.github/assets/github.svg" alt="GitHub"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## License
|
## <a name="license">⚖️ License</a>
|
||||||
|
|
||||||
[MIT](./LICENSE)
|
|
||||||
|
|
||||||
|
[MIT](https://github.com/nuxt/nuxt/tree/main/LICENSE)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: 'Introduction'
|
title: Introduction
|
||||||
description: Nuxt's goal is to make web development intuitive and performant with a great Developer Experience in mind.
|
description: Nuxt's goal is to make web development intuitive and performant with a great Developer Experience in mind.
|
||||||
navigation.icon: i-ph-info-duotone
|
navigation:
|
||||||
|
icon: i-ph-info
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt is a free and [open-source framework](https://github.com/nuxt/nuxt) with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with [Vue.js](https://vuejs.org).
|
Nuxt is a free and [open-source framework](https://github.com/nuxt/nuxt) with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with [Vue.js](https://vuejs.org).
|
||||||
@ -10,6 +11,10 @@ We made everything so you can start writing `.vue` files from the beginning whil
|
|||||||
|
|
||||||
Nuxt has no vendor lock-in, allowing you to deploy your application [**everywhere, even on the edge**](/blog/nuxt-on-the-edge).
|
Nuxt has no vendor lock-in, allowing you to deploy your application [**everywhere, even on the edge**](/blog/nuxt-on-the-edge).
|
||||||
|
|
||||||
|
::tip
|
||||||
|
If you want to play around with Nuxt in your browser, you can [try it out in one of our online sandboxes](/docs/getting-started/installation#play-online).
|
||||||
|
::
|
||||||
|
|
||||||
## Automation and Conventions
|
## Automation and Conventions
|
||||||
|
|
||||||
Nuxt uses conventions and an opinionated directory structure to automate repetitive tasks and allow developers to focus on pushing features. The configuration file can still customize and override its default behaviors.
|
Nuxt uses conventions and an opinionated directory structure to automate repetitive tasks and allow developers to focus on pushing features. The configuration file can still customize and override its default behaviors.
|
||||||
@ -72,7 +77,5 @@ Nuxt is composed of different [core packages](https://github.com/nuxt/nuxt/tree/
|
|||||||
- Command line interface: [nuxi](https://github.com/nuxt/nuxt/tree/main/packages/nuxi)
|
- Command line interface: [nuxi](https://github.com/nuxt/nuxt/tree/main/packages/nuxi)
|
||||||
- Server engine: [nitro](https://github.com/unjs/nitro)
|
- Server engine: [nitro](https://github.com/unjs/nitro)
|
||||||
- Development kit: [@nuxt/kit](https://github.com/nuxt/nuxt/tree/main/packages/kit)
|
- Development kit: [@nuxt/kit](https://github.com/nuxt/nuxt/tree/main/packages/kit)
|
||||||
- Nuxt 2 Bridge: [@nuxt/bridge](https://github.com/nuxt/bridge)
|
|
||||||
|
|
||||||
We recommend reading each concept to have a full vision of Nuxt capabilities and the scope of each package.
|
We recommend reading each concept to have a full vision of Nuxt capabilities and the scope of each package.
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 'Deployment'
|
title: 'Deployment'
|
||||||
description: Learn how to deploy your Nuxt application to any hosting provider.
|
description: Learn how to deploy your Nuxt application to any hosting provider.
|
||||||
navigation.icon: i-ph-cloud-duotone
|
navigation.icon: i-ph-cloud
|
||||||
---
|
---
|
||||||
|
|
||||||
A Nuxt application can be deployed on a Node.js server, pre-rendered for static hosting, or deployed to serverless or edge (CDN) environments.
|
A Nuxt application can be deployed on a Node.js server, pre-rendered for static hosting, or deployed to serverless or edge (CDN) environments.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you are looking for a list of cloud providers that support Nuxt 3, see the [Hosting providers](/deploy) section.
|
If you are looking for a list of cloud providers that support Nuxt 3, see the [Hosting providers](/deploy) section.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -64,6 +64,10 @@ By default, the workload gets distributed to the workers with the round robin st
|
|||||||
|
|
||||||
:read-more{to="https://nitro.unjs.io/deploy/node" title="the Nitro documentation for node-server preset"}
|
:read-more{to="https://nitro.unjs.io/deploy/node" title="the Nitro documentation for node-server preset"}
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=0x1H6K5yOfs" target="\_blank"}
|
||||||
|
Watch Daniel Roe's short video on the topic.
|
||||||
|
::
|
||||||
|
|
||||||
## Static Hosting
|
## Static Hosting
|
||||||
|
|
||||||
There are two ways to deploy a Nuxt application to any static hosting services:
|
There are two ways to deploy a Nuxt application to any static hosting services:
|
||||||
@ -71,62 +75,7 @@ There are two ways to deploy a Nuxt application to any static hosting services:
|
|||||||
- Static site generation (SSG) with `ssr: true` pre-renders routes of your application at build time. (This is the default behavior when running `nuxi generate`.) It will also generate `/200.html` and `/404.html` single-page app fallback pages, which can render dynamic routes or 404 errors on the client (though you may need to configure this on your static host).
|
- Static site generation (SSG) with `ssr: true` pre-renders routes of your application at build time. (This is the default behavior when running `nuxi generate`.) It will also generate `/200.html` and `/404.html` single-page app fallback pages, which can render dynamic routes or 404 errors on the client (though you may need to configure this on your static host).
|
||||||
- Alternatively, you can prerender your site with `ssr: false` (static single-page app). This will produce HTML pages with an empty `<div id="__nuxt"></div>` where your Vue app would normally be rendered. You will lose many SEO benefits of prerendering your site, so it is suggested instead to use [`<ClientOnly>`](/docs/api/components/client-only) to wrap the portions of your site that cannot be server rendered (if any).
|
- Alternatively, you can prerender your site with `ssr: false` (static single-page app). This will produce HTML pages with an empty `<div id="__nuxt"></div>` where your Vue app would normally be rendered. You will lose many SEO benefits of prerendering your site, so it is suggested instead to use [`<ClientOnly>`](/docs/api/components/client-only) to wrap the portions of your site that cannot be server rendered (if any).
|
||||||
|
|
||||||
### Crawl-based Pre-rendering
|
:read-more{title="Nuxt prerendering" to="/docs/getting-started/prerendering"}
|
||||||
|
|
||||||
Use the [`nuxi generate` command](/docs/api/commands/generate) to build and pre-render your application using the [Nitro](/docs/guide/concepts/server-engine) crawler. This command is similar to `nuxt build` with the `nitro.static` option set to `true`, or running `nuxt build --prerender`.
|
|
||||||
|
|
||||||
```bash [Terminal]
|
|
||||||
npx nuxi generate
|
|
||||||
```
|
|
||||||
|
|
||||||
That's it! You can now deploy the `.output/public` directory to any static hosting service or preview it locally with `npx serve .output/public`.
|
|
||||||
|
|
||||||
Working of the Nitro crawler:
|
|
||||||
|
|
||||||
1. Load the HTML of your application's root route (`/`), any non-dynamic pages in your `~/pages` directory, and any other routes in the `nitro.prerender.routes` array.
|
|
||||||
2. Save the HTML and `payload.json` to the `~/.output/public/` directory to be served statically.
|
|
||||||
3. Find all anchor tags (`<a href="...">`) in the HTML to navigate to other routes.
|
|
||||||
4. Repeat steps 1-3 for each anchor tag found until there are no more anchor tags to crawl.
|
|
||||||
|
|
||||||
This is important to understand since pages that are not linked to a discoverable page can't be pre-rendered automatically.
|
|
||||||
|
|
||||||
::read-more{to="/docs/api/commands/generate#nuxi-generate"}
|
|
||||||
Read more about the `nuxi generate` command.
|
|
||||||
::
|
|
||||||
|
|
||||||
### Selective Pre-rendering
|
|
||||||
|
|
||||||
You can manually specify routes that [Nitro](/docs/guide/concepts/server-engine) will fetch and pre-render during the build or ignore routes that you don't want to pre-render like `/dynamic` in the `nuxt.config` file:
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
nitro: {
|
|
||||||
prerender: {
|
|
||||||
routes: ['/user/1', '/user/2'],
|
|
||||||
ignore: ['/dynamic']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can combine this with the `crawlLinks` option to pre-render a set of routes that the crawler can't discover like your `/sitemap.xml` or `/robots.txt`:
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
nitro: {
|
|
||||||
prerender: {
|
|
||||||
crawlLinks: true,
|
|
||||||
routes: ['/sitemap.xml', '/robots.txt']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Setting `nitro.prerender` to `true` is similar to `nitro.prerender.crawlLinks` to `true`.
|
|
||||||
|
|
||||||
::read-more{to="https://nitro.unjs.io/config#prerender"}
|
|
||||||
Read more about pre-rendering in the Nitro documentation.
|
|
||||||
::
|
|
||||||
|
|
||||||
### Client-side Only Rendering
|
### Client-side Only Rendering
|
||||||
|
|
||||||
@ -140,13 +89,13 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
## Hosting Providers
|
## Hosting Providers
|
||||||
|
|
||||||
Nuxt 3 can be deployed to several cloud providers with a minimal amount of configuration:
|
Nuxt can be deployed to several cloud providers with a minimal amount of configuration:
|
||||||
|
|
||||||
:read-more{to="/deploy"}
|
:read-more{to="/deploy"}
|
||||||
|
|
||||||
## Presets
|
## Presets
|
||||||
|
|
||||||
In addition to Node.js servers and static hosting services, a Nuxt 3 project can be deployed with several well-tested presets and minimal amount of configuration.
|
In addition to Node.js servers and static hosting services, a Nuxt project can be deployed with several well-tested presets and minimal amount of configuration.
|
||||||
|
|
||||||
You can explicitly set the desired preset in the [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file:
|
You can explicitly set the desired preset in the [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file:
|
||||||
|
|
||||||
@ -172,10 +121,13 @@ In most cases, Nuxt can work with third-party content that is not generated or c
|
|||||||
|
|
||||||
Accordingly, you should make sure that the following options are unchecked / disabled in Cloudflare. Otherwise, unnecessary re-rendering or hydration errors could impact your production application.
|
Accordingly, you should make sure that the following options are unchecked / disabled in Cloudflare. Otherwise, unnecessary re-rendering or hydration errors could impact your production application.
|
||||||
|
|
||||||
1. Speed > Optimization > Auto Minify: Uncheck JavaScript, CSS and HTML
|
1. Speed > Optimization > Content Optimization > Auto Minify: Uncheck JavaScript, CSS and HTML
|
||||||
2. Speed > Optimization > Disable "Rocket Loader™"
|
2. Speed > Optimization > Content Optimization > Disable "Rocket Loader™"
|
||||||
3. Speed > Optimization > Disable "Mirage"
|
3. Speed > Optimization > Image Optimization > Disable "Mirage"
|
||||||
4. Scrape Shield > Disable "Email Address Obfuscation"
|
4. Scrape Shield > Disable "Email Address Obfuscation"
|
||||||
5. Scrape Shield > Disable "Server-side Excludes"
|
|
||||||
|
|
||||||
With these settings, you can be sure that Cloudflare won't inject scripts into your Nuxt application that may cause unwanted side effects.
|
With these settings, you can be sure that Cloudflare won't inject scripts into your Nuxt application that may cause unwanted side effects.
|
||||||
|
|
||||||
|
::tip
|
||||||
|
Their location on the Cloudflare dashboard sometimes changes so don't hesitate to look around.
|
||||||
|
::
|
||||||
|
@ -1,30 +1,34 @@
|
|||||||
---
|
---
|
||||||
title: Testing
|
title: Testing
|
||||||
description: How to test your Nuxt application.
|
description: How to test your Nuxt application.
|
||||||
navigation.icon: i-ph-check-circle-duotone
|
navigation.icon: i-ph-check-circle
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you are a module author, you can find more specific information in the [Module Author's guide](/docs/guide/going-further/modules#testing).
|
If you are a module author, you can find more specific information in the [Module Author's guide](/docs/guide/going-further/modules#testing).
|
||||||
::
|
::
|
||||||
|
|
||||||
Nuxt offers first-class support for end-to-end and unit testing of your Nuxt application via `@nuxt/test-utils`, a library of test utilities and configuration that currently powers the [tests we use on Nuxt itself](https://github.com/nuxt/nuxt/tree/main/test) and tests throughout the module ecosystem.
|
Nuxt offers first-class support for end-to-end and unit testing of your Nuxt application via `@nuxt/test-utils`, a library of test utilities and configuration that currently powers the [tests we use on Nuxt itself](https://github.com/nuxt/nuxt/tree/main/test) and tests throughout the module ecosystem.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=yGzwk9xi9gU" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about getting started with the `@nuxt/test-utils`.
|
||||||
|
::
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
In order to allow you to manage your other testing dependencies, `@nuxt/test-utils` ships with various optional peer dependencies. For example:
|
In order to allow you to manage your other testing dependencies, `@nuxt/test-utils` ships with various optional peer dependencies. For example:
|
||||||
|
|
||||||
- you can choose between `happy-dom` and `jsdom` for a runtime Nuxt environment
|
- you can choose between `happy-dom` and `jsdom` for a runtime Nuxt environment
|
||||||
- you can choose between `vitest` and `jest` for end-to-end test runners
|
- you can choose between `vitest`, `cucumber`, `jest` and `playwright` for end-to-end test runners
|
||||||
- `playwright-core` is only required if you wish to use the built-in browser testing utilities
|
- `playwright-core` is only required if you wish to use the built-in browser testing utilities (and are not using `@playwright/test` as your test runner)
|
||||||
|
|
||||||
::code-group
|
::package-managers
|
||||||
```bash [yarn]
|
|
||||||
yarn add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
|
||||||
```
|
|
||||||
```bash [npm]
|
```bash [npm]
|
||||||
npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
||||||
```
|
```
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
||||||
|
```
|
||||||
```bash [pnpm]
|
```bash [pnpm]
|
||||||
pnpm add -D @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
pnpm add -D @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
|
||||||
```
|
```
|
||||||
@ -59,6 +63,11 @@ We currently ship an environment for unit testing code that needs a [Nuxt](https
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::tip
|
||||||
|
When importing `@nuxt/test-utils` in your vitest config, It is necessary to have `"type": "module"` specified in your `package.json` or rename your vitest config file appropriately.
|
||||||
|
> ie. `vitest.config.m{ts,js}`.
|
||||||
|
::
|
||||||
|
|
||||||
### Using a Nuxt Runtime Environment
|
### Using a Nuxt Runtime Environment
|
||||||
|
|
||||||
By default, `@nuxt/test-utils` will not change your default Vitest environment, so you can do fine-grained opt-in and run Nuxt tests together with other unit tests.
|
By default, `@nuxt/test-utils` will not change your default Vitest environment, so you can do fine-grained opt-in and run Nuxt tests together with other unit tests.
|
||||||
@ -88,6 +97,7 @@ export default defineVitestConfig({
|
|||||||
// environmentOptions: {
|
// environmentOptions: {
|
||||||
// nuxt: {
|
// nuxt: {
|
||||||
// rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
|
// rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
|
||||||
|
// domEnvironment: 'happy-dom', // 'happy-dom' (default) or 'jsdom'
|
||||||
// overrides: {
|
// overrides: {
|
||||||
// // other Nuxt config you want to pass
|
// // other Nuxt config you want to pass
|
||||||
// }
|
// }
|
||||||
@ -108,12 +118,10 @@ test('my test', () => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::warning
|
||||||
|
|
||||||
When you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) or [`jsdom`](https://github.com/jsdom/jsdom) environment. Before your tests run, a global Nuxt app will be initialized (including, for example, running any plugins or code you've defined in your `app.vue`).
|
When you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) or [`jsdom`](https://github.com/jsdom/jsdom) environment. Before your tests run, a global Nuxt app will be initialized (including, for example, running any plugins or code you've defined in your `app.vue`).
|
||||||
|
|
||||||
This means you should take particular care not to mutate the global state in your tests (or, if you need to, to reset it afterwards).
|
This means you should take particular care not to mutate the global state in your tests (or, if you need to, to reset it afterwards).
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
### 🎭 Built-In Mocks
|
### 🎭 Built-In Mocks
|
||||||
@ -153,24 +161,41 @@ export default defineVitestConfig({
|
|||||||
|
|
||||||
#### `mountSuspended`
|
#### `mountSuspended`
|
||||||
|
|
||||||
`mountSuspended` allows you to mount any Vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins. For example:
|
`mountSuspended` allows you to mount any Vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins.
|
||||||
|
|
||||||
|
::alert{type=info}
|
||||||
|
Under the hood, `mountSuspended` wraps `mount` from `@vue/test-utils`, so you can check out [the Vue Test Utils documentation](https://test-utils.vuejs.org/guide/) for more on the options you can pass, and how to use this utility.
|
||||||
|
::
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
```ts twoslash
|
```ts twoslash
|
||||||
import type { Component } from 'vue'
|
|
||||||
import { it, expect } from 'vitest'
|
import { it, expect } from 'vitest'
|
||||||
declare const SomeComponent: Component
|
import type { Component } from 'vue'
|
||||||
declare const App: Component
|
declare module '#components' {
|
||||||
|
export const SomeComponent: Component
|
||||||
|
}
|
||||||
// ---cut---
|
// ---cut---
|
||||||
// tests/components/SomeComponents.nuxt.spec.ts
|
// tests/components/SomeComponents.nuxt.spec.ts
|
||||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||||
|
import { SomeComponent } from '#components'
|
||||||
|
|
||||||
it('can mount some component', async () => {
|
it('can mount some component', async () => {
|
||||||
const component = await mountSuspended(SomeComponent)
|
const component = await mountSuspended(SomeComponent)
|
||||||
expect(component.text()).toMatchInlineSnapshot(
|
expect(component.text()).toMatchInlineSnapshot(
|
||||||
'This is an auto-imported component'
|
'"This is an auto-imported component"'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts twoslash
|
||||||
|
import { it, expect } from 'vitest'
|
||||||
|
// ---cut---
|
||||||
|
// tests/components/SomeComponents.nuxt.spec.ts
|
||||||
|
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||||
|
import App from '~/app.vue'
|
||||||
|
|
||||||
// tests/App.nuxt.spec.ts
|
// tests/App.nuxt.spec.ts
|
||||||
it('can also mount an app', async () => {
|
it('can also mount an app', async () => {
|
||||||
const component = await mountSuspended(App, { route: '/test' })
|
const component = await mountSuspended(App, { route: '/test' })
|
||||||
@ -188,6 +213,7 @@ it('can also mount an app', async () => {
|
|||||||
`renderSuspended` allows you to render any Vue component within the Nuxt environment using `@testing-library/vue`, allowing async setup and access to injections from your Nuxt plugins.
|
`renderSuspended` allows you to render any Vue component within the Nuxt environment using `@testing-library/vue`, allowing async setup and access to injections from your Nuxt plugins.
|
||||||
|
|
||||||
This should be used together with utilities from Testing Library, e.g. `screen` and `fireEvent`. Install [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro) in your project to use these.
|
This should be used together with utilities from Testing Library, e.g. `screen` and `fireEvent`. Install [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro) in your project to use these.
|
||||||
|
|
||||||
Additionally, Testing Library also relies on testing globals for cleanup. You should turn these on in your [Vitest config](https://vitest.dev/config/#globals).
|
Additionally, Testing Library also relies on testing globals for cleanup. You should turn these on in your [Vitest config](https://vitest.dev/config/#globals).
|
||||||
|
|
||||||
The passed in component will be rendered inside a `<div id="test-wrapper"></div>`.
|
The passed in component will be rendered inside a `<div id="test-wrapper"></div>`.
|
||||||
@ -195,13 +221,15 @@ The passed in component will be rendered inside a `<div id="test-wrapper"></div>
|
|||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
```ts twoslash
|
```ts twoslash
|
||||||
import type { Component } from 'vue'
|
|
||||||
import { it, expect } from 'vitest'
|
import { it, expect } from 'vitest'
|
||||||
declare const SomeComponent: Component
|
import type { Component } from 'vue'
|
||||||
declare const App: Component
|
declare module '#components' {
|
||||||
|
export const SomeComponent: Component
|
||||||
|
}
|
||||||
// ---cut---
|
// ---cut---
|
||||||
// tests/components/SomeComponents.nuxt.spec.ts
|
// tests/components/SomeComponents.nuxt.spec.ts
|
||||||
import { renderSuspended } from '@nuxt/test-utils/runtime'
|
import { renderSuspended } from '@nuxt/test-utils/runtime'
|
||||||
|
import { SomeComponent } from '#components'
|
||||||
import { screen } from '@testing-library/vue'
|
import { screen } from '@testing-library/vue'
|
||||||
|
|
||||||
it('can render some component', async () => {
|
it('can render some component', async () => {
|
||||||
@ -211,13 +239,11 @@ it('can render some component', async () => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```ts twoslash
|
```ts twoslash
|
||||||
import type { Component } from 'vue'
|
|
||||||
import { it, expect } from 'vitest'
|
import { it, expect } from 'vitest'
|
||||||
declare const SomeComponent: Component
|
|
||||||
declare const App: Component
|
|
||||||
// ---cut---
|
// ---cut---
|
||||||
// tests/App.nuxt.spec.ts
|
// tests/App.nuxt.spec.ts
|
||||||
import { renderSuspended } from '@nuxt/test-utils/runtime'
|
import { renderSuspended } from '@nuxt/test-utils/runtime'
|
||||||
|
import App from '~/app.vue'
|
||||||
|
|
||||||
it('can also render an app', async () => {
|
it('can also render an app', async () => {
|
||||||
const html = await renderSuspended(App, { route: '/test' })
|
const html = await renderSuspended(App, { route: '/test' })
|
||||||
@ -247,7 +273,9 @@ mockNuxtImport('useStorage', () => {
|
|||||||
// your tests here
|
// your tests here
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**: `mockNuxtImport` can only be used once per mocked import per test file. It is actually a macro that gets transformed to `vi.mock` and `vi.mock` is hoisted, as described [here](https://vitest.dev/api/vi.html#vi-mock).
|
::alert{type=info}
|
||||||
|
`mockNuxtImport` can only be used once per mocked import per test file. It is actually a macro that gets transformed to `vi.mock` and `vi.mock` is hoisted, as described [here](https://vitest.dev/api/vi.html#vi-mock).
|
||||||
|
::
|
||||||
|
|
||||||
If you need to mock a Nuxt import and provide different implementations between tests, you can do it by creating and exposing your mocks using [`vi.hoisted`](https://vitest.dev/api/vi.html#vi-hoisted), and then use those mocks in `mockNuxtImport`. You then have access to the mocked imports, and can change the implementation between tests. Be careful to [restore mocks](https://vitest.dev/api/mock.html#mockrestore) before or after each test to undo mock state changes between runs.
|
If you need to mock a Nuxt import and provide different implementations between tests, you can do it by creating and exposing your mocks using [`vi.hoisted`](https://vitest.dev/api/vi.html#vi-hoisted), and then use those mocks in `mockNuxtImport`. You then have access to the mocked imports, and can change the implementation between tests. Be careful to [restore mocks](https://vitest.dev/api/mock.html#mockrestore) before or after each test to undo mock state changes between runs.
|
||||||
|
|
||||||
@ -338,8 +366,8 @@ For example, to mock `/test/` endpoint, you can do:
|
|||||||
```ts twoslash
|
```ts twoslash
|
||||||
import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
||||||
|
|
||||||
registerEndpoint("/test/", () => ({
|
registerEndpoint('/test/', () => ({
|
||||||
test: "test-field"
|
test: 'test-field'
|
||||||
}))
|
}))
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -348,13 +376,13 @@ By default, your request will be made using the `GET` method. You may use anothe
|
|||||||
```ts twoslash
|
```ts twoslash
|
||||||
import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
||||||
|
|
||||||
registerEndpoint("/test/", {
|
registerEndpoint('/test/', {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
handler: () => ({ test: "test-field" })
|
handler: () => ({ test: 'test-field' })
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**: If your requests in a component go to external API, you can use `baseURL` and then make it empty using Nuxt Environment Config (`$test`) so all your requests will go to Nitro server.
|
> **Note**: If your requests in a component go to an external API, you can use `baseURL` and then make it empty using [Nuxt Environment Override Config](/docs/getting-started/configuration#environment-overrides) (`$test`) so all your requests will go to Nitro server.
|
||||||
|
|
||||||
#### Conflict with End-To-End Testing
|
#### Conflict with End-To-End Testing
|
||||||
|
|
||||||
@ -365,7 +393,7 @@ If you would like to use both the end-to-end and unit testing functionality of `
|
|||||||
`app.nuxt.spec.ts`
|
`app.nuxt.spec.ts`
|
||||||
|
|
||||||
```ts twoslash
|
```ts twoslash
|
||||||
import { mockNuxtImport } from "@nuxt/test-utils/runtime"
|
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
|
||||||
|
|
||||||
mockNuxtImport('useStorage', () => {
|
mockNuxtImport('useStorage', () => {
|
||||||
return () => {
|
return () => {
|
||||||
@ -387,9 +415,98 @@ await setup({
|
|||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using `@vue/test-utils`
|
||||||
|
|
||||||
|
If you prefer to use `@vue/test-utils` on its own for unit testing in Nuxt, and you are only testing components which do not rely on Nuxt composables, auto-imports or context, you can follow these steps to set it up.
|
||||||
|
|
||||||
|
1. Install the needed dependencies
|
||||||
|
|
||||||
|
::package-managers
|
||||||
|
```bash [npm]
|
||||||
|
npm i --save-dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
|
||||||
|
```
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add --dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
|
||||||
|
```
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm add -D vitest @vue/test-utils happy-dom @vitejs/plugin-vue
|
||||||
|
```
|
||||||
|
```bash [bun]
|
||||||
|
bun add --dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
2. Create a `vitest.config.ts` with the following content:
|
||||||
|
|
||||||
|
```ts twoslash
|
||||||
|
import { defineConfig } from 'vitest/config'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
test: {
|
||||||
|
environment: 'happy-dom',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Add a new command for test in your `package.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
...
|
||||||
|
"test": "vitest"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Create a simple `<HelloWorld>` component `components/HelloWorld.vue` with the following content:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<p>Hello world</p>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Create a simple unit test for this newly created component `~/components/HelloWorld.spec.ts`
|
||||||
|
|
||||||
|
```ts twoslash
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
|
||||||
|
import HelloWorld from './HelloWorld.vue'
|
||||||
|
|
||||||
|
describe('HelloWorld', () => {
|
||||||
|
it('component renders Hello world properly', () => {
|
||||||
|
const wrapper = mount(HelloWorld)
|
||||||
|
expect(wrapper.text()).toContain('Hello world')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Run vitest command
|
||||||
|
|
||||||
|
::package-managers
|
||||||
|
```bash [npm]
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
```bash [yarn]
|
||||||
|
yarn test
|
||||||
|
```
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm run test
|
||||||
|
```
|
||||||
|
```bash [bun]
|
||||||
|
bun run test
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
Congratulations, you're all set to start unit testing with `@vue/test-utils` in Nuxt! Happy testing!
|
||||||
|
|
||||||
## End-To-End Testing
|
## End-To-End Testing
|
||||||
|
|
||||||
For end-to-end testing, we support [Vitest](https://github.com/vitest-dev/vitest) and [Jest](https://jestjs.io) as test runners.
|
For end-to-end testing, we support [Vitest](https://github.com/vitest-dev/vitest), [Jest](https://jestjs.io), [Cucumber](https://cucumber.io/) and [Playwright](https://playwright.dev/) as test runners.
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
@ -436,17 +553,22 @@ Please use the options below for the `setup` method.
|
|||||||
|
|
||||||
#### Features
|
#### Features
|
||||||
|
|
||||||
|
- `build`: Whether to run a separate build step.
|
||||||
|
- Type: `boolean`
|
||||||
|
- Default: `true` (`false` if `browser` or `server` is disabled, or if a `host` is provided)
|
||||||
|
|
||||||
- `server`: Whether to launch a server to respond to requests in the test suite.
|
- `server`: Whether to launch a server to respond to requests in the test suite.
|
||||||
- Type: `boolean`
|
- Type: `boolean`
|
||||||
- Default: `true`
|
- Default: `true` (`false` if a `host` is provided)
|
||||||
|
|
||||||
- `port`: If provided, set the launched test server port to the value.
|
- `port`: If provided, set the launched test server port to the value.
|
||||||
- Type: `number | undefined`
|
- Type: `number | undefined`
|
||||||
- Default: `undefined`
|
- Default: `undefined`
|
||||||
|
|
||||||
- `build`: Whether to run a separate build step.
|
- `host`: If provided, a URL to use as the test target instead of building and running a new server. Useful for running "real" end-to-end tests against a deployed version of your application, or against an already running local server (which may provide a significant reduction in test execution timings). See the [target host end-to-end example below](#target-host-end-to-end-example).
|
||||||
- Type: `boolean`
|
- Type: `string`
|
||||||
- Default: `true` (`false` if `browser` or `server` is disabled)
|
- Default: `undefined`
|
||||||
|
|
||||||
- `browser`: Under the hood, Nuxt test utils uses [`playwright`](https://playwright.dev) to carry out browser testing. If this option is set, a browser will be launched and can be controlled in the subsequent test suite.
|
- `browser`: Under the hood, Nuxt test utils uses [`playwright`](https://playwright.dev) to carry out browser testing. If this option is set, a browser will be launched and can be controlled in the subsequent test suite.
|
||||||
- Type: `boolean`
|
- Type: `boolean`
|
||||||
- Default: `false`
|
- Default: `false`
|
||||||
@ -455,9 +577,34 @@ Please use the options below for the `setup` method.
|
|||||||
- `type`: The type of browser to launch - either `chromium`, `firefox` or `webkit`
|
- `type`: The type of browser to launch - either `chromium`, `firefox` or `webkit`
|
||||||
- `launch`: `object` of options that will be passed to playwright when launching the browser. See [full API reference](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
|
- `launch`: `object` of options that will be passed to playwright when launching the browser. See [full API reference](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
|
||||||
- `runner`: Specify the runner for the test suite. Currently, [Vitest](https://vitest.dev) is recommended.
|
- `runner`: Specify the runner for the test suite. Currently, [Vitest](https://vitest.dev) is recommended.
|
||||||
- Type: `'vitest' | 'jest'`
|
- Type: `'vitest' | 'jest' | 'cucumber'`
|
||||||
- Default: `'vitest'`
|
- Default: `'vitest'`
|
||||||
|
|
||||||
|
##### Target `host` end-to-end example
|
||||||
|
|
||||||
|
A common use-case for end-to-end testing is running the tests against a deployed application running in the same environment typically used for Production.
|
||||||
|
|
||||||
|
For local development or automated deploy pipelines, testing against a separate local server can be more efficient and is typically faster than allowing the test framework to rebuild between tests.
|
||||||
|
|
||||||
|
To utilize a separate target host for end-to-end tests, simply provide the `host` property of the `setup` function with the desired URL.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { setup, createPage } from '@nuxt/test-utils/e2e'
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
|
||||||
|
describe('login page', async () => {
|
||||||
|
await setup({
|
||||||
|
host: 'http://localhost:8787',
|
||||||
|
})
|
||||||
|
|
||||||
|
it('displays the email and password fields', async () => {
|
||||||
|
const page = await createPage('/login')
|
||||||
|
expect(await page.getByTestId('email').isVisible()).toBe(true)
|
||||||
|
expect(await page.getByTestId('password').isVisible()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
### APIs
|
### APIs
|
||||||
|
|
||||||
#### `$fetch(url)`
|
#### `$fetch(url)`
|
||||||
@ -494,11 +641,11 @@ const pageUrl = url('/page')
|
|||||||
|
|
||||||
### Testing in a Browser
|
### Testing in a Browser
|
||||||
|
|
||||||
We provide built-in support using Playwright within `@nuxt/test-utils`, but you can also use other test runners for end-to-end browser testing.
|
We provide built-in support using Playwright within `@nuxt/test-utils`, either programmatically or via the Playwright test runner.
|
||||||
|
|
||||||
#### `createPage(url)`
|
#### `createPage(url)`
|
||||||
|
|
||||||
You can create a configured Playwright browser instance, and (optionally) point it at a path from the running server. You can find out more about the API methods available from [in the Playwright documentation](https://playwright.dev/docs/api/class-page).
|
Within `vitest`, `jest` or `cucumber`, you can create a configured Playwright browser instance with `createPage`, and (optionally) point it at a path from the running server. You can find out more about the API methods available from [in the Playwright documentation](https://playwright.dev/docs/api/class-page).
|
||||||
|
|
||||||
```ts twoslash
|
```ts twoslash
|
||||||
import { createPage } from '@nuxt/test-utils/e2e'
|
import { createPage } from '@nuxt/test-utils/e2e'
|
||||||
@ -506,3 +653,70 @@ import { createPage } from '@nuxt/test-utils/e2e'
|
|||||||
const page = await createPage('/page')
|
const page = await createPage('/page')
|
||||||
// you can access all the Playwright APIs from the `page` variable
|
// you can access all the Playwright APIs from the `page` variable
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Testing with Playwright Test Runner
|
||||||
|
|
||||||
|
We also provide first-class support for testing Nuxt within [the Playwright test runner](https://playwright.dev/docs/intro).
|
||||||
|
|
||||||
|
::package-managers
|
||||||
|
```bash [npm]
|
||||||
|
npm i --save-dev @playwright/test @nuxt/test-utils
|
||||||
|
```
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add --dev @playwright/test @nuxt/test-utils
|
||||||
|
```
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm add -D @playwright/test @nuxt/test-utils
|
||||||
|
```
|
||||||
|
```bash [bun]
|
||||||
|
bun add --dev @playwright/test @nuxt/test-utils
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
You can provide global Nuxt configuration, with the same configuration details as the `setup()` function mentioned earlier in this section.
|
||||||
|
|
||||||
|
```ts [playwright.config.ts]
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { defineConfig, devices } from '@playwright/test'
|
||||||
|
import type { ConfigOptions } from '@nuxt/test-utils/playwright'
|
||||||
|
|
||||||
|
export default defineConfig<ConfigOptions>({
|
||||||
|
use: {
|
||||||
|
nuxt: {
|
||||||
|
rootDir: fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
::read-more{title="See full example config" to="https://github.com/nuxt/test-utils/blob/main/examples/app-playwright/playwright.config.ts" target="_blank"}
|
||||||
|
::
|
||||||
|
|
||||||
|
Your test file should then use `expect` and `test` directly from `@nuxt/test-utils/playwright`:
|
||||||
|
|
||||||
|
```ts [tests/example.test.ts]
|
||||||
|
import { expect, test } from '@nuxt/test-utils/playwright'
|
||||||
|
|
||||||
|
test('test', async ({ page, goto }) => {
|
||||||
|
await goto('/', { waitUntil: 'hydration' })
|
||||||
|
await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
You can alternatively configure your Nuxt server directly within your test file:
|
||||||
|
|
||||||
|
```ts [tests/example.test.ts]
|
||||||
|
import { expect, test } from '@nuxt/test-utils/playwright'
|
||||||
|
|
||||||
|
test.use({
|
||||||
|
nuxt: {
|
||||||
|
rootDir: fileURLToPath(new URL('..', import.meta.url))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test', async ({ page, goto }) => {
|
||||||
|
await goto('/', { waitUntil: 'hydration' })
|
||||||
|
await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
@ -1,32 +1,606 @@
|
|||||||
---
|
---
|
||||||
title: Upgrade Guide
|
title: Upgrade Guide
|
||||||
description: 'Learn how to upgrade to the latest Nuxt version.'
|
description: 'Learn how to upgrade to the latest Nuxt version.'
|
||||||
navigation.icon: i-ph-arrow-circle-up-duotone
|
navigation.icon: i-ph-arrow-circle-up
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Upgrading Nuxt
|
||||||
## Upgrading Nuxt 3
|
|
||||||
|
|
||||||
### Latest release
|
### Latest release
|
||||||
|
|
||||||
To upgrade Nuxt 3 to the [latest release](https://github.com/nuxt/nuxt/releases), use the `nuxi upgrade` command.
|
To upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases), use the `nuxi upgrade` command.
|
||||||
|
|
||||||
```bash [Terminal]
|
::package-managers
|
||||||
|
|
||||||
|
```bash [npm]
|
||||||
npx nuxi upgrade
|
npx nuxi upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn dlx nuxi upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm dlx nuxi upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [bun]
|
||||||
|
bun x nuxi upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
### Nightly Release Channel
|
### Nightly Release Channel
|
||||||
|
|
||||||
To use the latest Nuxt 3 build and test features before their release, read about the [nightly release channel](/docs/guide/going-further/nightly-release-channel) guide.
|
To use the latest Nuxt build and test features before their release, read about the [nightly release channel](/docs/guide/going-further/nightly-release-channel) guide.
|
||||||
|
|
||||||
## Nuxt 2 vs Nuxt 3
|
::alert{type="warning"}
|
||||||
|
The nightly release channel `latest` tag is currently tracking the Nuxt v4 branch, meaning that it is particularly likely to have breaking changes right now - be careful!
|
||||||
|
|
||||||
|
You can opt in to the 3.x branch nightly releases with `"nuxt": "npm:nuxt-nightly@3x"`.
|
||||||
|
::
|
||||||
|
|
||||||
|
## Testing Nuxt 4
|
||||||
|
|
||||||
|
The release date of Nuxt 4 is **to be announced**. It is dependent on having enough time after Nitro's major release to be properly tested in the community. You can follow progress towards Nitro's release in [this PR](https://github.com/unjs/nitro/pull/2521).
|
||||||
|
|
||||||
|
Until the release, it is possible to test many of Nuxt 4's breaking changes from Nuxt version 3.12+.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=r4wFKlcJK6c" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter showing how to opt in to Nuxt 4's breaking changes already.
|
||||||
|
::
|
||||||
|
|
||||||
|
### Opting in to Nuxt 4
|
||||||
|
|
||||||
|
First, upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases).
|
||||||
|
|
||||||
|
Then you can set your `compatibilityVersion` to match Nuxt 4 behavior:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
future: {
|
||||||
|
compatibilityVersion: 4,
|
||||||
|
},
|
||||||
|
// To re-enable _all_ Nuxt v3 behavior, set the following options:
|
||||||
|
// srcDir: '.',
|
||||||
|
// dir: {
|
||||||
|
// app: 'app'
|
||||||
|
// },
|
||||||
|
// experimental: {
|
||||||
|
// sharedPrerenderData: false,
|
||||||
|
// compileTemplate: true,
|
||||||
|
// resetAsyncDataToUndefined: true,
|
||||||
|
// templateUtils: true,
|
||||||
|
// relativeWatchPaths: true,
|
||||||
|
// normalizeComponentNames: false
|
||||||
|
// defaults: {
|
||||||
|
// useAsyncData: {
|
||||||
|
// deep: true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// unhead: {
|
||||||
|
// renderSSRHeadOptions: {
|
||||||
|
// omitLineBreaks: false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
When you set your `compatibilityVersion` to `4`, defaults throughout your Nuxt configuration will change to opt in to Nuxt v4 behavior, but you can granularly re-enable Nuxt v3 behavior when testing, following the commented out lines above. Please file issues if so, so that we can address them in Nuxt or in the ecosystem.
|
||||||
|
|
||||||
|
### Migrating to Nuxt 4
|
||||||
|
|
||||||
|
Breaking or significant changes will be noted here along with migration steps for backward/forward compatibility.
|
||||||
|
|
||||||
|
::alert
|
||||||
|
This section is subject to change until the final release, so please check back here regularly if you are testing Nuxt 4 using `compatibilityVersion: 4`.
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Migrating Using Codemods
|
||||||
|
|
||||||
|
To facilitate the upgrade process, we have collaborated with the [Codemod](https://github.com/codemod-com/codemod) team to automate many migration steps with some open-source codemods.
|
||||||
|
|
||||||
|
::note
|
||||||
|
If you encounter any issues, please report them to the Codemod team with `npx codemod feedback` 🙏
|
||||||
|
::
|
||||||
|
|
||||||
|
For a complete list of Nuxt 4 codemods, detailed information on each, their source, and various ways to run them, visit the [Codemod Registry](https://go.codemod.com/codemod-registry).
|
||||||
|
|
||||||
|
You can run all the codemods mentioned in this guide using the following `codemod` recipe:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx codemod@latest nuxt/4/migration-recipe
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will execute all codemods in sequence, with the option to deselect any that you do not wish to run. Each codemod is also listed below alongside its respective change and can be executed independently.
|
||||||
|
|
||||||
|
#### New Directory Structure
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Significant
|
||||||
|
|
||||||
|
Nuxt now defaults to a new directory structure, with backwards compatibility (so if Nuxt detects you are using the old structure, such as with a top-level `pages/` directory, this new structure will not apply).
|
||||||
|
|
||||||
|
👉 [See full RFC](https://github.com/nuxt/nuxt/issues/26444)
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
* the new Nuxt default `srcDir` is `app/` by default, and most things are resolved from there.
|
||||||
|
* `serverDir` now defaults to `<rootDir>/server` rather than `<srcDir>/server`
|
||||||
|
* `layers/`, `modules/` and `public/` are resolved relative to `<rootDir>` by default
|
||||||
|
* if using [Nuxt Content v2.13+](https://github.com/nuxt/content/pull/2649), `content/` is resolved relative to `<rootDir>`
|
||||||
|
* a new `dir.app` is added, which is the directory we look for `router.options.ts` and `spa-loading-template.html` - this defaults to `<srcDir>/`
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>An example v4 folder structure.</summary>
|
||||||
|
|
||||||
|
```sh
|
||||||
|
.output/
|
||||||
|
.nuxt/
|
||||||
|
app/
|
||||||
|
assets/
|
||||||
|
components/
|
||||||
|
composables/
|
||||||
|
layouts/
|
||||||
|
middleware/
|
||||||
|
pages/
|
||||||
|
plugins/
|
||||||
|
utils/
|
||||||
|
app.config.ts
|
||||||
|
app.vue
|
||||||
|
router.options.ts
|
||||||
|
content/
|
||||||
|
layers/
|
||||||
|
modules/
|
||||||
|
node_modules/
|
||||||
|
public/
|
||||||
|
server/
|
||||||
|
api/
|
||||||
|
middleware/
|
||||||
|
plugins/
|
||||||
|
routes/
|
||||||
|
utils/
|
||||||
|
nuxt.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
👉 For more details, see the [PR implementing this change](https://github.com/nuxt/nuxt/pull/27029).
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
1. **Performance** - placing all your code in the root of your repo causes issues with `.git/` and `node_modules/` folders being scanned/included by FS watchers which can significantly delay startup on non-Mac OSes.
|
||||||
|
1. **IDE type-safety** - `server/` and the rest of your app are running in two entirely different contexts with different global imports available, and making sure `server/` isn't _inside_ the same folder as the rest of your app is a big first step to ensuring you get good auto-completes in your IDE.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
1. Create a new directory called `app/`.
|
||||||
|
1. Move your `assets/`, `components/`, `composables/`, `layouts/`, `middleware/`, `pages/`, `plugins/` and `utils/` folders under it, as well as `app.vue`, `error.vue`, `app.config.ts`. If you have an `app/router-options.ts` or `app/spa-loading-template.html`, these paths remain the same.
|
||||||
|
1. Make sure your `nuxt.config.ts`, `content/`, `layers/`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project.
|
||||||
|
1. Remember to update any third-party configuration files to work with the new directory structure, such as your `tailwindcss` or `eslint` configuration (if required - `@nuxtjs/tailwindcss` should automatically configure `tailwindcss` correctly).
|
||||||
|
|
||||||
|
::tip
|
||||||
|
You can automate this migration by running `npx codemod@latest nuxt/4/file-structure`
|
||||||
|
::
|
||||||
|
|
||||||
|
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) The one exception is that if you _already_ have a custom `srcDir`. In this case, you should be aware that your `modules/`, `public/` and `server/` folders will be resolved from your `rootDir` rather than from your custom `srcDir`. You can override this by configuring `dir.modules`, `dir.public` and `serverDir` if you need to.
|
||||||
|
|
||||||
|
You can also force a v3 folder structure with the following configuration:
|
||||||
|
|
||||||
|
```ts [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
// This reverts the new srcDir default from `app` back to your root directory
|
||||||
|
srcDir: '.',
|
||||||
|
// This specifies the directory prefix for `app/router.options.ts` and `app/spa-loading-template.html`
|
||||||
|
dir: {
|
||||||
|
app: 'app'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Normalized Component Names
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Moderate
|
||||||
|
|
||||||
|
Vue will now generate component names that match the Nuxt pattern for component naming.
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
By default, if you haven't set it manually, Vue will assign a component name that matches
|
||||||
|
the filename of the component.
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
├─ components/
|
||||||
|
├─── SomeFolder/
|
||||||
|
├───── MyComponent.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `<KeepAlive>` with it, or identify it in the Vue DevTools, you would need to use this name.
|
||||||
|
|
||||||
|
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
|
||||||
|
|
||||||
|
With this change, these two values will match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
Ensure that you use the updated name in any tests which use `findComponent` from `@vue/test-utils` and in any `<KeepAlive>` which depends on the name of your component.
|
||||||
|
|
||||||
|
Alternatively, for now, you can disable this behaviour with:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
normalizeComponentNames: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Shared Prerender Data
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Medium
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
We enabled a previously experimental feature to share data from `useAsyncData` and `useFetch` calls, across different pages. See [original PR](https://github.com/nuxt/nuxt/pull/24894).
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
This feature automatically shares payload _data_ between pages that are prerendered. This can result in a significant performance improvement when prerendering sites that use `useAsyncData` or `useFetch` and fetch the same data in different pages.
|
||||||
|
|
||||||
|
For example, if your site requires a `useFetch` call for every page (for example, to get navigation data for a menu, or site settings from a CMS), this data would only be fetched once when prerendering the first page that uses it, and then cached for use when prerendering other pages.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
Make sure that any unique key of your data is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch` should do this automatically for you.)
|
||||||
|
|
||||||
|
```ts [app/pages/test/[slug\\].vue]
|
||||||
|
// This would be unsafe in a dynamic page (e.g. `[slug].vue`) because the route slug makes a difference
|
||||||
|
// to the data fetched, but Nuxt can't know that because it's not reflected in the key.
|
||||||
|
const route = useRoute()
|
||||||
|
const { data } = await useAsyncData(async () => {
|
||||||
|
return await $fetch(`/api/my-page/${route.params.slug}`)
|
||||||
|
})
|
||||||
|
// Instead, you should use a key that uniquely identifies the data fetched.
|
||||||
|
const { data } = await useAsyncData(route.params.slug, async () => {
|
||||||
|
return await $fetch(`/api/my-page/${route.params.slug}`)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can disable this feature with:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
sharedPrerenderData: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Default `data` and `error` values in `useAsyncData` and `useFetch`
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
`data` and `error` objects returned from `useAsyncData` will now default to `undefined`.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
Previously `data` was initialized to `null` but reset in `clearNuxtData` to `undefined`. `error` was initialized to `null`. This change is to bring greater consistency.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
If you were checking if `data.value` or `error.value` were `null`, you can update these checks to check for `undefined` instead.
|
||||||
|
|
||||||
|
::tip
|
||||||
|
You can automate this step by running `npx codemod@latest nuxt/4/default-data-error-value`
|
||||||
|
::
|
||||||
|
|
||||||
|
If you encounter any issues you can revert back to the previous behavior with:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
// @errors: 2353
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
defaults: {
|
||||||
|
useAsyncData: {
|
||||||
|
value: 'null',
|
||||||
|
errorValue: 'null'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Please report an issue if you are doing this, as we do not plan to keep this as configurable.
|
||||||
|
|
||||||
|
#### Removal of deprecated `boolean` values for `dedupe` option when calling `refresh` in `useAsyncData` and `useFetch`
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
Previously it was possible to pass `dedupe: boolean` to `refresh`. These were aliases of `cancel` (`true`) and `defer` (`false`).
|
||||||
|
|
||||||
|
```ts twoslash [app.vue]
|
||||||
|
// @errors: 2322
|
||||||
|
const { refresh } = await useAsyncData(async () => ({ message: 'Hello, Nuxt 3!' }))
|
||||||
|
|
||||||
|
async function refreshData () {
|
||||||
|
await refresh({ dedupe: true })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
These aliases were removed, for greater clarity.
|
||||||
|
|
||||||
|
The issue came up when adding `dedupe` as an option to `useAsyncData`, and we removed the boolean values as they ended up being _opposites_.
|
||||||
|
|
||||||
|
`refresh({ dedupe: false })` meant 'do not _cancel_ existing requests in favour of this new one'. But passing `dedupe: true` within the options of `useAsyncData` means 'do not make any new requests if there is an existing pending request.' (See [PR](https://github.com/nuxt/nuxt/pull/24564#pullrequestreview-1764584361).)
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
The migration should be straightforward:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
const { refresh } = await useAsyncData(async () => ({ message: 'Hello, Nuxt 3!' }))
|
||||||
|
|
||||||
|
async function refreshData () {
|
||||||
|
- await refresh({ dedupe: true })
|
||||||
|
+ await refresh({ dedupe: 'cancel' })
|
||||||
|
|
||||||
|
- await refresh({ dedupe: false })
|
||||||
|
+ await refresh({ dedupe: 'defer' })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::tip
|
||||||
|
You can automate this step by running `npx codemod@latest nuxt/4/deprecated-dedupe-value`
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Respect defaults when clearing `data` in `useAsyncData` and `useFetch`
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
If you provide a custom `default` value for `useAsyncData`, this will now be used when calling `clear` or `clearNuxtData` and it will be reset to its default value rather than simply unset.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
Often users set an appropriately empty value, such as an empty array, to avoid the need to check for `null`/`undefined` when iterating over it. This should be respected when resetting/clearing the data.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
If you encounter any issues you can revert back to the previous behavior, for now, with:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
// @errors: 2353
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
resetAsyncDataToUndefined: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Please report an issue if you are doing so, as we do not plan to keep this as configurable.
|
||||||
|
|
||||||
|
#### Shallow Data Reactivity in `useAsyncData` and `useFetch`
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
The `data` object returned from `useAsyncData`, `useFetch`, `useLazyAsyncData` and `useLazyFetch` is now a `shallowRef` rather than a `ref`.
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
When new data is fetched, anything depending on `data` will still be reactive because the entire object is replaced. But if your code changes a property _within_ that data structure, this will not trigger any reactivity in your app.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
This brings a **significant** performance improvement for deeply nested objects and arrays because Vue does not need to watch every single property/array for modification. In most cases, `data` should also be immutable.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
In most cases, no migration steps are required, but if you rely on the reactivity of the data object then you have two options:
|
||||||
|
|
||||||
|
1. You can granularly opt in to deep reactivity on a per-composable basis:
|
||||||
|
```diff
|
||||||
|
- const { data } = useFetch('/api/test')
|
||||||
|
+ const { data } = useFetch('/api/test', { deep: true })
|
||||||
|
```
|
||||||
|
1. You can change the default behavior on a project-wide basis (not recommended):
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
defaults: {
|
||||||
|
useAsyncData: {
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
::tip
|
||||||
|
If you need to, you can automate this step by running `npx codemod@latest nuxt/4/shallow-function-reactivity`
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Absolute Watch Paths in `builder:watch`
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
The Nuxt `builder:watch` hook now emits a path which is absolute rather than relative to your project `srcDir`.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
This allows us to support watching paths which are outside your `srcDir`, and offers better support for layers and other more complex patterns.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
We have already proactively migrated the public Nuxt modules which we are aware use this hook. See [issue #25339](https://github.com/nuxt/nuxt/issues/25339).
|
||||||
|
|
||||||
|
However, if you are a module author using the `builder:watch` hook and wishing to remain backwards/forwards compatible, you can use the following code to ensure that your code works the same in both Nuxt v3 and Nuxt v4:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
+ import { relative, resolve } from 'node:fs'
|
||||||
|
// ...
|
||||||
|
nuxt.hook('builder:watch', async (event, path) => {
|
||||||
|
+ path = relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, path))
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
::tip
|
||||||
|
You can automate this step by running `npx codemod@latest nuxt/4/absolute-watch-path`
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Removal of `window.__NUXT__` object
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
We are removing the global `window.__NUXT__` object after the app finishes hydration.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
This opens the way to multi-app patterns ([#21635](https://github.com/nuxt/nuxt/issues/21635)) and enables us to focus on a single way to access Nuxt app data - `useNuxtApp()`.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
The data is still available, but can be accessed with `useNuxtApp().payload`:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- console.log(window.__NUXT__)
|
||||||
|
+ console.log(useNuxtApp().payload)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Directory index scanning
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Medium
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
Child folders in your `middleware/` folder are also scanned for `index` files and these are now also registered as middleware in your project.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
Nuxt scans a number of folders automatically, including `middleware/` and `plugins/`.
|
||||||
|
|
||||||
|
Child folders in your `plugins/` folder are scanned for `index` files and we wanted to make this behavior consistent between scanned directories.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
Probably no migration is necessary but if you wish to revert to previous behavior you can add a hook to filter out these middleware:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
hooks: {
|
||||||
|
'app:resolve'(app) {
|
||||||
|
app.middleware = app.middleware.filter(mw => !/\/index\.[^/]+$/.test(mw.path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Template Compilation Changes
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
Previously, Nuxt used `lodash/template` to compile templates located on the file system using the `.ejs` file format/syntax.
|
||||||
|
|
||||||
|
In addition, we provided some template utilities (`serialize`, `importName`, `importSources`) which could be used for code-generation within these templates, which are now being removed.
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
In Nuxt v3 we moved to a 'virtual' syntax with a `getContents()` function which is much more flexible and performant.
|
||||||
|
|
||||||
|
In addition, `lodash/template` has had a succession of security issues. These do not really apply to Nuxt projects because it is being used at build-time, not runtime, and by trusted code. However, they still appear in security audits. Moreover, `lodash` is a hefty dependency and is unused by most projects.
|
||||||
|
|
||||||
|
Finally, providing code serialization functions directly within Nuxt is not ideal. Instead, we maintain projects like [unjs/knitwork](http://github.com/unjs/knitwork) which can be dependencies of your project, and where security issues can be reported/resolved directly without requiring an upgrade of Nuxt itself.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
We have raised PRs to update modules using EJS syntax, but if you need to do this yourself, you have three backwards/forwards-compatible alternatives:
|
||||||
|
|
||||||
|
* Moving your string interpolation logic directly into `getContents()`.
|
||||||
|
* Using a custom function to handle the replacement, such as in https://github.com/nuxt-modules/color-mode/pull/240.
|
||||||
|
* Continuing to use `lodash`, as a dependency of _your_ project rather than Nuxt:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
+ import { readFileSync } from 'node:fs'
|
||||||
|
+ import { template } from 'lodash-es'
|
||||||
|
// ...
|
||||||
|
addTemplate({
|
||||||
|
fileName: 'appinsights-vue.js'
|
||||||
|
options: { /* some options */ },
|
||||||
|
- src: resolver.resolve('./runtime/plugin.ejs'),
|
||||||
|
+ getContents({ options }) {
|
||||||
|
+ const contents = readFileSync(resolver.resolve('./runtime/plugin.ejs'), 'utf-8')
|
||||||
|
+ return template(contents)({ options })
|
||||||
|
+ },
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, if you are using the template utilities (`serialize`, `importName`, `importSources`), you can replace them as follows with utilities from `knitwork`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork'
|
||||||
|
|
||||||
|
const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"(?=,?$)/gm, r => JSON.parse(r).replace(/^{(.*)}$/, '$1'))
|
||||||
|
|
||||||
|
const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
||||||
|
return toArray(sources).map((src) => {
|
||||||
|
if (lazy) {
|
||||||
|
return `const ${genSafeVariableName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
|
||||||
|
}
|
||||||
|
return genImport(src, genSafeVariableName(src))
|
||||||
|
}).join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
const importName = genSafeVariableName
|
||||||
|
```
|
||||||
|
|
||||||
|
::tip
|
||||||
|
You can automate this step by running `npx codemod@latest nuxt/4/template-compilation-changes`
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Removal of Experimental Features
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Minimal
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
Four experimental features are no longer configurable in Nuxt 4:
|
||||||
|
|
||||||
|
* `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
|
||||||
|
* `experimental.configSchema` will be `true` (default since v3.3)
|
||||||
|
* `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
|
||||||
|
* `experimental.respectNoSSRHeader` will be `false` (default since v3.4)
|
||||||
|
* `vite.devBundler` is no longer configurable - it will use `vite-node` by default
|
||||||
|
|
||||||
|
##### Reasons for Change
|
||||||
|
|
||||||
|
These options have been set to their current values for some time and we do not have a reason to believe that they need to remain configurable.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
* `polyfillVueUseHead` is implementable in user-land with [this plugin](https://github.com/nuxt/nuxt/blob/f209158352b09d1986aa320e29ff36353b91c358/packages/nuxt/src/head/runtime/plugins/vueuse-head-polyfill.ts#L10-L11)
|
||||||
|
|
||||||
|
* `respectNoSSRHeader`is implementable in user-land with [server middleware](https://github.com/nuxt/nuxt/blob/c660b39447f0d5b8790c0826092638d321cd6821/packages/nuxt/src/core/runtime/nitro/no-ssr.ts#L8-L9)
|
||||||
|
|
||||||
|
## Nuxt 2 vs Nuxt 3+
|
||||||
|
|
||||||
In the table below, there is a quick comparison between 3 versions of Nuxt:
|
In the table below, there is a quick comparison between 3 versions of Nuxt:
|
||||||
|
|
||||||
Feature / Version | Nuxt 2 | Nuxt Bridge | Nuxt 3
|
Feature / Version | Nuxt 2 | Nuxt Bridge | Nuxt 3+
|
||||||
-------------------------|-----------------|------------------|---------
|
-------------------------|-----------------|------------------|---------
|
||||||
Vue | 2 | 2 | 3
|
Vue | 2 | 2 | 3
|
||||||
Stability | 😊 Stable | 😌 Semi-stable | 😊 Stable
|
Stability | 😊 Stable | 😊 Stable | 😊 Stable
|
||||||
Performance | 🏎 Fast | ✈️ Faster | 🚀 Fastest
|
Performance | 🏎 Fast | ✈️ Faster | 🚀 Fastest
|
||||||
Nitro Engine | ❌ | ✅ | ✅
|
Nitro Engine | ❌ | ✅ | ✅
|
||||||
ESM support | 🌙 Partial | 👍 Better | ✅
|
ESM support | 🌙 Partial | 👍 Better | ✅
|
||||||
@ -41,9 +615,9 @@ Vite | ⚠️ Partial | 🚧 Partial | ✅
|
|||||||
Nuxi CLI | ❌ Old | ✅ nuxi | ✅ nuxi
|
Nuxi CLI | ❌ Old | ✅ nuxi | ✅ nuxi
|
||||||
Static sites | ✅ | ✅ | ✅
|
Static sites | ✅ | ✅ | ✅
|
||||||
|
|
||||||
## Nuxt 2 to Nuxt 3
|
## Nuxt 2 to Nuxt 3+
|
||||||
|
|
||||||
The migration guide provides a step-by-step comparison of Nuxt 2 features to Nuxt 3 features and guidance to adapt your current application.
|
The migration guide provides a step-by-step comparison of Nuxt 2 features to Nuxt 3+ features and guidance to adapt your current application.
|
||||||
|
|
||||||
::read-more{to="/docs/migration/overview"}
|
::read-more{to="/docs/migration/overview"}
|
||||||
Check out the **guide to migrating from Nuxt 2 to Nuxt 3**.
|
Check out the **guide to migrating from Nuxt 2 to Nuxt 3**.
|
||||||
@ -51,7 +625,7 @@ Check out the **guide to migrating from Nuxt 2 to Nuxt 3**.
|
|||||||
|
|
||||||
## Nuxt 2 to Nuxt Bridge
|
## Nuxt 2 to Nuxt Bridge
|
||||||
|
|
||||||
If you prefer to progressively migrate your Nuxt 2 application to Nuxt 3, you can use Nuxt Bridge. Nuxt Bridge is a compatibility layer that allows you to use Nuxt 3 features in Nuxt 2 with an opt-in mechanism.
|
If you prefer to progressively migrate your Nuxt 2 application to Nuxt 3, you can use Nuxt Bridge. Nuxt Bridge is a compatibility layer that allows you to use Nuxt 3+ features in Nuxt 2 with an opt-in mechanism.
|
||||||
|
|
||||||
::read-more{to="/docs/bridge/overview"}
|
::read-more{to="/docs/bridge/overview"}
|
||||||
**Migrate from Nuxt 2 to Nuxt Bridge**
|
**Migrate from Nuxt 2 to Nuxt Bridge**
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
---
|
---
|
||||||
title: 'Installation'
|
title: 'Installation'
|
||||||
description: 'Get started with Nuxt quickly with our online starters or start locally with your terminal.'
|
description: 'Get started with Nuxt quickly with our online starters or start locally with your terminal.'
|
||||||
navigation.icon: i-ph-play-duotone
|
navigation.icon: i-ph-play
|
||||||
---
|
---
|
||||||
|
|
||||||
## Play Online
|
## Play Online
|
||||||
|
|
||||||
You can start playing with Nuxt 3 in your browser using our online sandboxes:
|
If you just want to play around with Nuxt in your browser without setting up a project, you can use one of our online sandboxes:
|
||||||
|
|
||||||
::card-group
|
::card-group
|
||||||
:card{title="Open on StackBlitz" icon="i-simple-icons-stackblitz" to="https://nuxt.new/s/v3" target="_blank"}
|
:card{title="Open on StackBlitz" icon="i-simple-icons-stackblitz" to="https://nuxt.new/s/v3" target="_blank"}
|
||||||
:card{title="Open on CodeSandbox" icon="i-simple-icons-codesandbox" to="https://nuxt.new/c/v3" target="_blank"}
|
:card{title="Open on CodeSandbox" icon="i-simple-icons-codesandbox" to="https://nuxt.new/c/v3" target="_blank"}
|
||||||
::
|
::
|
||||||
|
|
||||||
Start with one of our starters and themes directly by opening [nuxt.new](https://nuxt.new).
|
Or follow the steps below to set up a new Nuxt project on your computer.
|
||||||
|
|
||||||
## New Project
|
## New Project
|
||||||
|
|
||||||
@ -22,46 +22,43 @@ Start with one of our starters and themes directly by opening [nuxt.new](https:/
|
|||||||
#### Prerequisites
|
#### Prerequisites
|
||||||
|
|
||||||
- **Node.js** - [`v18.0.0`](https://nodejs.org/en) or newer
|
- **Node.js** - [`v18.0.0`](https://nodejs.org/en) or newer
|
||||||
- **Text editor** - We recommend [Visual Studio Code](https://code.visualstudio.com/) with the [Volar Extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
- **Text editor** - We recommend [Visual Studio Code](https://code.visualstudio.com/) with the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously known as Volar)
|
||||||
- **Terminal** - In order to run Nuxt commands
|
- **Terminal** - In order to run Nuxt commands
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
::details
|
::details
|
||||||
:summary[Additional notes for an optimal setup:]
|
:summary[Additional notes for an optimal setup:]
|
||||||
- **Node.js**: Make sure to use an even numbered version (18, 20, etc)
|
- **Node.js**: Make sure to use an even numbered version (18, 20, etc)
|
||||||
- **Nuxtr**: Install the community-developed [Nuxtr extension](https://marketplace.visualstudio.com/items?itemName=Nuxtr.nuxtr-vscode)
|
- **Nuxtr**: Install the community-developed [Nuxtr extension](https://marketplace.visualstudio.com/items?itemName=Nuxtr.nuxtr-vscode)
|
||||||
- **Volar**: Either enable [**Take Over Mode**](https://vuejs.org/guide/typescript/overview.html#volar-takeover-mode) (recommended) or add the [TypeScript Vue Plugin](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin)
|
|
||||||
|
|
||||||
If you have enabled **Take Over Mode** or installed the **TypeScript Vue Plugin (Volar)**, you can disable generating the shim for `*.vue` files in your [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file:
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
typescript: {
|
|
||||||
shim: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
::
|
::
|
||||||
::
|
::
|
||||||
|
|
||||||
Open a terminal (if you're using [Visual Studio Code](https://code.visualstudio.com), you can open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal)) and use the following command to create a new starter project:
|
Open a terminal (if you're using [Visual Studio Code](https://code.visualstudio.com), you can open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal)) and use the following command to create a new starter project:
|
||||||
|
|
||||||
::code-group
|
::package-managers
|
||||||
|
|
||||||
```bash [npx]
|
```bash [npm]
|
||||||
npx nuxi@latest init <project-name>
|
npx nuxi@latest init <project-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn dlx nuxi@latest init <project-name>
|
||||||
|
```
|
||||||
|
|
||||||
```bash [pnpm]
|
```bash [pnpm]
|
||||||
pnpm dlx nuxi@latest init <project-name>
|
pnpm dlx nuxi@latest init <project-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash [bun]
|
```bash [bun]
|
||||||
bunx nuxi@latest init <project-name>
|
bun x nuxi@latest init <project-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::tip
|
||||||
|
Alternatively, you can find other starters or themes by opening [nuxt.new](https://nuxt.new) and following the instructions there.
|
||||||
|
::
|
||||||
|
|
||||||
Open your project folder in Visual Studio Code:
|
Open your project folder in Visual Studio Code:
|
||||||
|
|
||||||
```bash [Terminal]
|
```bash [Terminal]
|
||||||
@ -74,47 +71,20 @@ Or change directory into your new project from your terminal:
|
|||||||
cd <project-name>
|
cd <project-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the dependencies:
|
|
||||||
|
|
||||||
::code-group
|
|
||||||
|
|
||||||
```bash [yarn]
|
|
||||||
yarn install
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [npm]
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [pnpm]
|
|
||||||
pnpm install
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [bun]
|
|
||||||
bun install
|
|
||||||
```
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
::callout
|
|
||||||
If you are using Yarn 2+ (Berry), add `nodeLinker: node-modules` to your `.yarnrc.yml` file.
|
|
||||||
[You can follow this issue status here](https://github.com/nuxt/nuxt/issues/22861)
|
|
||||||
::
|
|
||||||
|
|
||||||
## Development Server
|
## Development Server
|
||||||
|
|
||||||
Now you'll be able to start your Nuxt app in development mode:
|
Now you'll be able to start your Nuxt app in development mode:
|
||||||
|
|
||||||
::code-group
|
::package-managers
|
||||||
|
|
||||||
```bash [yarn]
|
|
||||||
yarn dev --open
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [npm]
|
```bash [npm]
|
||||||
npm run dev -- -o
|
npm run dev -- -o
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn dev --open
|
||||||
|
```
|
||||||
|
|
||||||
```bash [pnpm]
|
```bash [pnpm]
|
||||||
pnpm dev -o
|
pnpm dev -o
|
||||||
```
|
```
|
||||||
@ -124,12 +94,12 @@ bun run dev -o
|
|||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-ph-check-circle-duotone"}
|
::tip{icon="i-ph-check-circle"}
|
||||||
Well done! A browser window should automatically open for <http://localhost:3000>.
|
Well done! A browser window should automatically open for <http://localhost:3000>.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
Now that you've created your Nuxt 3 project, you are ready to start building your application.
|
Now that you've created your Nuxt project, you are ready to start building your application.
|
||||||
|
|
||||||
:read-more{title="Nuxt Concepts" to="/docs/guide/concepts"}
|
:read-more{title="Nuxt Concepts" to="/docs/guide/concepts"}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Configuration
|
title: Configuration
|
||||||
description: Nuxt is configured with sensible defaults to make you productive.
|
description: Nuxt is configured with sensible defaults to make you productive.
|
||||||
navigation.icon: i-ph-gear-duotone
|
navigation.icon: i-ph-gear
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
By default, Nuxt is configured to cover most use cases. The [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file can override or extend this default configuration.
|
By default, Nuxt is configured to cover most use cases. The [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file can override or extend this default configuration.
|
||||||
|
|
||||||
## Nuxt Configuration
|
## Nuxt Configuration
|
||||||
@ -25,11 +24,11 @@ This file will often be mentioned in the documentation, for example to add custo
|
|||||||
Every option is described in the **Configuration Reference**.
|
Every option is described in the **Configuration Reference**.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
You don't have to use TypeScript to build an application with Nuxt. However, it is strongly recommended to use the `.ts` extension for the `nuxt.config` file. This way you can benefit from hints in your IDE to avoid typos and mistakes while editing your configuration.
|
You don't have to use TypeScript to build an application with Nuxt. However, it is strongly recommended to use the `.ts` extension for the `nuxt.config` file. This way you can benefit from hints in your IDE to avoid typos and mistakes while editing your configuration.
|
||||||
::
|
::
|
||||||
|
|
||||||
### Environment overrides
|
### Environment Overrides
|
||||||
|
|
||||||
You can configure fully typed, per-environment overrides in your nuxt.config
|
You can configure fully typed, per-environment overrides in your nuxt.config
|
||||||
|
|
||||||
@ -46,7 +45,11 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=DFZI2iVCrNc" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about the env-aware `nuxt.config.ts`.
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
If you're authoring layers, you can also use the `$meta` key to provide metadata that you or the consumers of your layer might use.
|
If you're authoring layers, you can also use the `$meta` key to provide metadata that you or the consumers of your layer might use.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -135,7 +138,7 @@ Non primitive JS types | ❌ No | ✅ Yes
|
|||||||
|
|
||||||
## External Configuration Files
|
## External Configuration Files
|
||||||
|
|
||||||
Nuxt uses [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file as the single source of trust for configurations and skips reading external configuration files. During the course of building your project, you may have a need to configure those. The following table highlights common configurations and, where applicable, how they can be configured with Nuxt.
|
Nuxt uses [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file as the single source of truth for configurations and skips reading external configuration files. During the course of building your project, you may have a need to configure those. The following table highlights common configurations and, where applicable, how they can be configured with Nuxt.
|
||||||
|
|
||||||
Name | Config File | How To Configure
|
Name | Config File | How To Configure
|
||||||
---------------------------------------------|---------------------------|-------------------------
|
---------------------------------------------|---------------------------|-------------------------
|
||||||
@ -149,7 +152,7 @@ Here is a list of other common config files:
|
|||||||
Name | Config File | How To Configure
|
Name | Config File | How To Configure
|
||||||
---------------------------------------------|-------------------------|--------------------------
|
---------------------------------------------|-------------------------|--------------------------
|
||||||
[TypeScript](https://www.typescriptlang.org) | `tsconfig.json` | [More Info](/docs/guide/concepts/typescript#nuxttsconfigjson)
|
[TypeScript](https://www.typescriptlang.org) | `tsconfig.json` | [More Info](/docs/guide/concepts/typescript#nuxttsconfigjson)
|
||||||
[ESLint](https://eslint.org) | `.eslintrc.js` | [More Info](https://eslint.org/docs/latest/use/configure/configuration-files)
|
[ESLint](https://eslint.org) | `eslint.config.js` | [More Info](https://eslint.org/docs/latest/use/configure/configuration-files)
|
||||||
[Prettier](https://prettier.io) | `.prettierrc.json` | [More Info](https://prettier.io/docs/en/configuration.html)
|
[Prettier](https://prettier.io) | `.prettierrc.json` | [More Info](https://prettier.io/docs/en/configuration.html)
|
||||||
[Stylelint](https://stylelint.io) | `.stylelintrc.json` | [More Info](https://stylelint.io/user-guide/configure)
|
[Stylelint](https://stylelint.io) | `.stylelintrc.json` | [More Info](https://stylelint.io/user-guide/configure)
|
||||||
[TailwindCSS](https://tailwindcss.com) | `tailwind.config.js` | [More Info](https://tailwindcss.nuxtjs.org/tailwind/config)
|
[TailwindCSS](https://tailwindcss.com) | `tailwind.config.js` | [More Info](https://tailwindcss.nuxtjs.org/tailwind/config)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Views'
|
title: 'Views'
|
||||||
description: 'Nuxt provides several component layers to implement the user interface of your application.'
|
description: 'Nuxt provides several component layers to implement the user interface of your application.'
|
||||||
navigation.icon: i-ph-layout-duotone
|
navigation.icon: i-ph-layout
|
||||||
---
|
---
|
||||||
|
|
||||||
## `app.vue`
|
## `app.vue`
|
||||||
@ -18,7 +18,7 @@ By default, Nuxt will treat this file as the **entrypoint** and render its conte
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you are familiar with Vue, you might wonder where `main.js` is (the file that normally creates a Vue app). Nuxt does this behind the scene.
|
If you are familiar with Vue, you might wonder where `main.js` is (the file that normally creates a Vue app). Nuxt does this behind the scene.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -90,12 +90,22 @@ To use pages, create `pages/index.vue` file and add `<NuxtPage />` component to
|
|||||||
|
|
||||||
Layouts are wrappers around pages that contain a common User Interface for several pages, such as a header and footer display. Layouts are Vue files using `<slot />` components to display the **page** content. The `layouts/default.vue` file will be used by default. Custom layouts can be set as part of your page metadata.
|
Layouts are wrappers around pages that contain a common User Interface for several pages, such as a header and footer display. Layouts are Vue files using `<slot />` components to display the **page** content. The `layouts/default.vue` file will be used by default. Custom layouts can be set as part of your page metadata.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/guide/directory-structure/app) with [`<NuxtPage />`](/docs/api/components/nuxt-page) instead.
|
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/guide/directory-structure/app) with [`<NuxtPage />`](/docs/api/components/nuxt-page) instead.
|
||||||
::
|
::
|
||||||
|
|
||||||
::code-group
|
::code-group
|
||||||
|
|
||||||
|
```vue [app.vue]
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<NuxtLayout>
|
||||||
|
<NuxtPage />
|
||||||
|
</NuxtLayout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
```vue [layouts/default.vue]
|
```vue [layouts/default.vue]
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
@ -131,7 +141,7 @@ If you want to create more layouts and learn how to use them in your pages, find
|
|||||||
|
|
||||||
## Advanced: Extending the HTML template
|
## Advanced: Extending the HTML template
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you only need to modify the `<head>`, you can refer to the [SEO and meta section](/docs/getting-started/seo-meta).
|
If you only need to modify the `<head>`, you can refer to the [SEO and meta section](/docs/getting-started/seo-meta).
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Assets'
|
title: 'Assets'
|
||||||
description: 'Nuxt offers two options for your assets.'
|
description: 'Nuxt offers two options for your assets.'
|
||||||
navigation.icon: i-ph-image-duotone
|
navigation.icon: i-ph-image
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt uses two directories to handle assets like stylesheets, fonts or images.
|
Nuxt uses two directories to handle assets like stylesheets, fonts or images.
|
||||||
@ -43,7 +43,7 @@ For example, referencing an image file that will be processed if a build tool is
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Nuxt won't serve files in the [`assets/`](/docs/guide/directory-structure/assets) directory at a static URL like `/assets/my-file.png`. If you need a static URL, use the [`public/`](#public-directory) directory.
|
Nuxt won't serve files in the [`assets/`](/docs/guide/directory-structure/assets) directory at a static URL like `/assets/my-file.png`. If you need a static URL, use the [`public/`](#public-directory) directory.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Styling'
|
title: 'Styling'
|
||||||
description: 'Learn how to style your Nuxt application.'
|
description: 'Learn how to style your Nuxt application.'
|
||||||
navigation.icon: i-ph-palette-duotone
|
navigation.icon: i-ph-palette
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt is highly flexible when it comes to styling. Write your own styles, or reference local and external stylesheets.
|
Nuxt is highly flexible when it comes to styling. Write your own styles, or reference local and external stylesheets.
|
||||||
@ -30,7 +30,7 @@ import('~/assets/css/first.css')
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
The stylesheets will be inlined in the HTML rendered by Nuxt.
|
The stylesheets will be inlined in the HTML rendered by Nuxt.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
The stylesheets will be inlined in the HTML rendered by Nuxt, injected globally and present in all pages.
|
The stylesheets will be inlined in the HTML rendered by Nuxt, injected globally and present in all pages.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -77,10 +77,26 @@ h1 {
|
|||||||
|
|
||||||
You can also reference stylesheets that are distributed through npm. Let's use the popular `animate.css` library as an example.
|
You can also reference stylesheets that are distributed through npm. Let's use the popular `animate.css` library as an example.
|
||||||
|
|
||||||
```bash [Terminal]
|
::package-managers
|
||||||
|
|
||||||
|
```bash [npm]
|
||||||
npm install animate.css
|
npm install animate.css
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add animate.css
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm install animate.css
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [bun]
|
||||||
|
bun install animate.css
|
||||||
|
```
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
Then you can reference it directly in your pages, layouts and components:
|
Then you can reference it directly in your pages, layouts and components:
|
||||||
|
|
||||||
```vue [app.vue]
|
```vue [app.vue]
|
||||||
@ -113,7 +129,8 @@ export default defineNuxtConfig({
|
|||||||
head: {
|
head: {
|
||||||
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
|
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
|
||||||
}
|
}
|
||||||
}})
|
}
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Dynamically Adding Stylesheets
|
### Dynamically Adding Stylesheets
|
||||||
@ -153,15 +170,15 @@ To use a preprocessor like SCSS, Sass, Less or Stylus, install it first.
|
|||||||
::code-group
|
::code-group
|
||||||
|
|
||||||
```bash [Sass & SCSS]
|
```bash [Sass & SCSS]
|
||||||
npm install sass
|
npm install -D sass
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash [Less]
|
```bash [Less]
|
||||||
npm install less
|
npm install -D less
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash [Stylus]
|
```bash [Stylus]
|
||||||
npm install stylus
|
npm install -D stylus
|
||||||
```
|
```
|
||||||
|
|
||||||
::
|
::
|
||||||
@ -183,7 +200,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
In both cases, the compiled stylesheets will be inlined in the HTML rendered by Nuxt.
|
In both cases, the compiled stylesheets will be inlined in the HTML rendered by Nuxt.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -243,7 +260,7 @@ Nuxt uses Vite by default. If you wish to use webpack instead, refer to each pre
|
|||||||
|
|
||||||
## Single File Components (SFC) Styling
|
## Single File Components (SFC) Styling
|
||||||
|
|
||||||
One of the best things about Vue and SFC is how great it is at naturally dealing with styling. You can directly write CSS or preprocessor code in the style block of your components file, therefore you will have fantastic developer experience without having to use something like CSS-in-JS. However if you wish to use CSS-in-JS, you can find 3rd party libraries and modules that support it, such as [pinceau](https://pinceau.dev).
|
One of the best things about Vue and SFC is how great it is at naturally dealing with styling. You can directly write CSS or preprocessor code in the style block of your components file, therefore you will have fantastic developer experience without having to use something like CSS-in-JS. However if you wish to use CSS-in-JS, you can find 3rd party libraries and modules that support it, such as [pinceau](https://github.com/Tahul/pinceau).
|
||||||
|
|
||||||
You can refer to the [Vue docs](https://vuejs.org/api/sfc-css-features.html) for a comprehensive reference about styling components in SFC.
|
You can refer to the [Vue docs](https://vuejs.org/api/sfc-css-features.html) for a comprehensive reference about styling components in SFC.
|
||||||
|
|
||||||
@ -410,8 +427,8 @@ Nuxt comes with postcss built-in. You can configure it in your `nuxt.config` fil
|
|||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: {
|
plugins: {
|
||||||
'postcss-nested': {}
|
'postcss-nested': {},
|
||||||
"postcss-custom-media": {}
|
'postcss-custom-media': {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -421,7 +438,7 @@ For proper syntax highlighting in SFC, you can use the postcss lang attribute.
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
/* Write stylus here */
|
/* Write postcss here */
|
||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -430,7 +447,7 @@ By default, Nuxt comes with the following plugins already pre-configured:
|
|||||||
- [postcss-import](https://github.com/postcss/postcss-import): Improves the `@import` rule
|
- [postcss-import](https://github.com/postcss/postcss-import): Improves the `@import` rule
|
||||||
- [postcss-url](https://github.com/postcss/postcss-url): Transforms `url()` statements
|
- [postcss-url](https://github.com/postcss/postcss-url): Transforms `url()` statements
|
||||||
- [autoprefixer](https://github.com/postcss/autoprefixer): Automatically adds vendor prefixes
|
- [autoprefixer](https://github.com/postcss/autoprefixer): Automatically adds vendor prefixes
|
||||||
- [cssnano](https://cssnano.co): Minification and purge
|
- [cssnano](https://cssnano.github.io/cssnano): Minification and purge
|
||||||
|
|
||||||
## Leveraging Layouts For Multiple Styles
|
## Leveraging Layouts For Multiple Styles
|
||||||
|
|
||||||
@ -458,14 +475,14 @@ Use different styles for different layouts.
|
|||||||
|
|
||||||
Nuxt isn't opinionated when it comes to styling and provides you with a wide variety of options. You can use any styling tool that you want, such as popular libraries like [UnoCSS](https://unocss.dev) or [Tailwind CSS](https://tailwindcss.com).
|
Nuxt isn't opinionated when it comes to styling and provides you with a wide variety of options. You can use any styling tool that you want, such as popular libraries like [UnoCSS](https://unocss.dev) or [Tailwind CSS](https://tailwindcss.com).
|
||||||
|
|
||||||
The community and the Nuxt team have developed plenty of Nuxt modules to makes the integration easier.
|
The community and the Nuxt team have developed plenty of Nuxt modules to make the integration easier.
|
||||||
You can discover them on the [modules section](/modules) of the website.
|
You can discover them on the [modules section](/modules) of the website.
|
||||||
Here are a few modules to help you get started:
|
Here are a few modules to help you get started:
|
||||||
|
|
||||||
- [UnoCSS](/modules/unocss): Instant on-demand atomic CSS engine
|
- [UnoCSS](/modules/unocss): Instant on-demand atomic CSS engine
|
||||||
- [Tailwind CSS](/modules/tailwindcss): Utility-first CSS framework
|
- [Tailwind CSS](/modules/tailwindcss): Utility-first CSS framework
|
||||||
- [Fontaine](https://github.com/nuxt-modules/fontaine): Font metric fallback
|
- [Fontaine](https://github.com/nuxt-modules/fontaine): Font metric fallback
|
||||||
- [Pinceau](https://pinceau.dev): Adaptable styling framework
|
- [Pinceau](https://github.com/Tahul/pinceau): Adaptable styling framework
|
||||||
- [Nuxt UI](https://ui.nuxt.com): A UI Library for Modern Web Apps
|
- [Nuxt UI](https://ui.nuxt.com): A UI Library for Modern Web Apps
|
||||||
- [Panda CSS](https://panda-css.com/docs/installation/nuxt): CSS-in-JS engine that generates atomic CSS at build time
|
- [Panda CSS](https://panda-css.com/docs/installation/nuxt): CSS-in-JS engine that generates atomic CSS at build time
|
||||||
|
|
||||||
@ -489,7 +506,7 @@ Nuxt comes with the same `<Transition>` element that Vue has, and also has suppo
|
|||||||
|
|
||||||
We would recommend using [Fontaine](https://github.com/nuxt-modules/fontaine) to reduce your [CLS](https://web.dev/cls). If you need something more advanced, consider creating a Nuxt module to extend the build process or the Nuxt runtime.
|
We would recommend using [Fontaine](https://github.com/nuxt-modules/fontaine) to reduce your [CLS](https://web.dev/cls). If you need something more advanced, consider creating a Nuxt module to extend the build process or the Nuxt runtime.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
Always remember to take advantage of the various tools and techniques available in the Web ecosystem at large to make styling your application easier and more efficient. Whether you're using native CSS, a preprocessor, postcss, a UI library or a module, Nuxt has got you covered. Happy styling!
|
Always remember to take advantage of the various tools and techniques available in the Web ecosystem at large to make styling your application easier and more efficient. Whether you're using native CSS, a preprocessor, postcss, a UI library or a module, Nuxt has got you covered. Happy styling!
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -513,7 +530,7 @@ export default defineNuxtConfig({
|
|||||||
hooks: {
|
hooks: {
|
||||||
'build:manifest': (manifest) => {
|
'build:manifest': (manifest) => {
|
||||||
// find the app entry, css list
|
// find the app entry, css list
|
||||||
const css = manifest['node_modules/nuxt/dist/app/entry.js']?.css
|
const css = Object.values(manifest).find(options => options.isEntry)?.css
|
||||||
if (css) {
|
if (css) {
|
||||||
// start from the end of the array and go to the beginning
|
// start from the end of the array and go to the beginning
|
||||||
for (let i = css.length - 1; i >= 0; i--) {
|
for (let i = css.length - 1; i >= 0; i--) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Routing'
|
title: 'Routing'
|
||||||
description: Nuxt file-system routing creates a route for every file in the pages/ directory.
|
description: Nuxt file-system routing creates a route for every file in the pages/ directory.
|
||||||
navigation.icon: i-ph-signpost-duotone
|
navigation.icon: i-ph-signpost
|
||||||
---
|
---
|
||||||
|
|
||||||
One core feature of Nuxt is the file system router. Every Vue file inside the [`pages/`](/docs/guide/directory-structure/pages) directory creates a corresponding URL (or route) that displays the contents of the file. By using dynamic imports for each page, Nuxt leverages code-splitting to ship the minimum amount of JavaScript for the requested route.
|
One core feature of Nuxt is the file system router. Every Vue file inside the [`pages/`](/docs/guide/directory-structure/pages) directory creates a corresponding URL (or route) that displays the contents of the file. By using dynamic imports for each page, Nuxt leverages code-splitting to ship the minimum amount of JavaScript for the requested route.
|
||||||
@ -15,7 +15,7 @@ This file system routing uses naming conventions to create dynamic and nested ro
|
|||||||
::code-group
|
::code-group
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| pages/
|
-| pages/
|
||||||
---| about.vue
|
---| about.vue
|
||||||
---| index.vue
|
---| index.vue
|
||||||
---| posts/
|
---| posts/
|
||||||
@ -86,7 +86,7 @@ console.log(route.params.id)
|
|||||||
|
|
||||||
Nuxt provides a customizable route middleware framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
|
Nuxt provides a customizable route middleware framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Route middleware runs within the Vue part of your Nuxt app. Despite the similar name, they are completely different from server middleware, which are run in the Nitro server part of your app.
|
Route middleware runs within the Vue part of your Nuxt app. Despite the similar name, they are completely different from server middleware, which are run in the Nitro server part of your app.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ If you have a more complex use case, then you can use anonymous route middleware
|
|||||||
definePageMeta({
|
definePageMeta({
|
||||||
validate: async (route) => {
|
validate: async (route) => {
|
||||||
// Check if the id is made up of digits
|
// Check if the id is made up of digits
|
||||||
return /^\d+$/.test(route.params.id)
|
return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: SEO and Meta
|
title: SEO and Meta
|
||||||
description: Improve your Nuxt app's SEO with powerful head config, composables and components.
|
description: Improve your Nuxt app's SEO with powerful head config, composables and components.
|
||||||
navigation.icon: i-ph-file-search-duotone
|
navigation.icon: i-ph-file-search
|
||||||
---
|
---
|
||||||
|
|
||||||
## Defaults
|
## Defaults
|
||||||
|
|
||||||
Out-of-the-box, Nuxt provides sane defaults, which you can override if needed.
|
Out-of-the-box, Nuxt provides sensible defaults, which you can override if needed.
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
```ts twoslash [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
@ -21,7 +21,7 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
Providing an [`app.head`](/docs/api/nuxt-config#head) property in your [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) allows you to customize the head for your entire app.
|
Providing an [`app.head`](/docs/api/nuxt-config#head) property in your [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) allows you to customize the head for your entire app.
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
This method does not allow you to provide reactive data. We recommend to use `useHead()` in `app.vue`.
|
This method does not allow you to provide reactive data. We recommend to use `useHead()` in `app.vue`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -128,8 +128,6 @@ See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/schema/sr
|
|||||||
|
|
||||||
Reactivity is supported on all properties, by providing a computed value, a getter, or a reactive object.
|
Reactivity is supported on all properties, by providing a computed value, a getter, or a reactive object.
|
||||||
|
|
||||||
It's recommended to use getters (`() => value`) over computed (`computed(() => value)`).
|
|
||||||
|
|
||||||
::code-group
|
::code-group
|
||||||
|
|
||||||
```vue twoslash [useHead]
|
```vue twoslash [useHead]
|
||||||
@ -174,7 +172,7 @@ You can use the `titleTemplate` option to provide a dynamic template for customi
|
|||||||
|
|
||||||
The `titleTemplate` can either be a string, where `%s` is replaced with the title, or a function.
|
The `titleTemplate` can either be a string, where `%s` is replaced with the title, or a function.
|
||||||
|
|
||||||
If you want to use a function (for full control), then this cannot be set in your `nuxt.config`, and it is recommended instead to set it within your `app.vue` file, where it will apply to all pages on your site:
|
If you want to use a function (for full control), then this cannot be set in your `nuxt.config`. It is recommended instead to set it within your `app.vue` file where it will apply to all pages on your site:
|
||||||
|
|
||||||
::code-group
|
::code-group
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: 'Transitions'
|
title: 'Transitions'
|
||||||
description: Apply transitions between pages and layouts with Vue or native browser View Transitions.
|
description: Apply transitions between pages and layouts with Vue or native browser View Transitions.
|
||||||
navigation.icon: i-ph-exclude-square-duotone
|
navigation.icon: i-ph-exclude-square
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Nuxt leverages Vue's [`<Transition>`](https://vuejs.org/guide/built-ins/transition.html#the-transition-component) component to apply transitions between pages and layouts.
|
Nuxt leverages Vue's [`<Transition>`](https://vuejs.org/guide/built-ins/transition.html#the-transition-component) component to apply transitions between pages and layouts.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you are changing layouts as well as page, the page transition you set here will not run. Instead, you should set a [layout transition](/docs/getting-started/transitions#layout-transitions).
|
If you are changing layouts as well as page, the page transition you set here will not run. Instead, you should set a [layout transition](/docs/getting-started/transitions#layout-transitions).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::warning
|
||||||
If you change the `name` property, you also have to rename the CSS classes accordingly.
|
If you change the `name` property, you also have to rename the CSS classes accordingly.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ definePageMeta({
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
Learn more about additional [JavaScript hooks](https://vuejs.org/guide/built-ins/transition.html#javascript-hooks) available in the `Transition` component.
|
Learn more about additional [JavaScript hooks](https://vuejs.org/guide/built-ins/transition.html#javascript-hooks) available in the `Transition` component.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ definePageMeta({
|
|||||||
},
|
},
|
||||||
middleware (to, from) {
|
middleware (to, from) {
|
||||||
if (to.meta.pageTransition && typeof to.meta.pageTransition !== 'boolean')
|
if (to.meta.pageTransition && typeof to.meta.pageTransition !== 'boolean')
|
||||||
to.meta.pageTransition.name = +to.params.id > +from.params.id ? 'slide-left' : 'slide-right'
|
to.meta.pageTransition.name = +to.params.id! > +from.params.id! ? 'slide-left' : 'slide-right'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -392,7 +392,7 @@ The page now applies the `slide-left` transition when going to the next id and `
|
|||||||
|
|
||||||
## Transition with NuxtPage
|
## Transition with NuxtPage
|
||||||
|
|
||||||
When `<NuxtPage />` is used in `app.vue`, transition-props can be passed directly as a component props to activate global transition.
|
When `<NuxtPage />` is used in `app.vue`, transitions can be configured with the `transition` prop to activate transitions globally.
|
||||||
|
|
||||||
```vue [app.vue]
|
```vue [app.vue]
|
||||||
<template>
|
<template>
|
||||||
@ -407,7 +407,7 @@ When `<NuxtPage />` is used in `app.vue`, transition-props can be passed directl
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Remember, this page transition cannot be overridden with `definePageMeta` on individual pages.
|
Remember, this page transition cannot be overridden with `definePageMeta` on individual pages.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -470,6 +470,4 @@ export default defineNuxtRouteMiddleware(to => {
|
|||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- View transitions may not work as expected with nested pages/layouts/async components owing to this upstream Vue bug: <https://github.com/vuejs/core/issues/5513>. If you make use of this pattern, you may need to delay adopting this experimental feature or implement it yourself. Feedback is very welcome.
|
|
||||||
|
|
||||||
- If you perform data fetching within your page setup functions, that you may wish to reconsider using this feature for the moment. (By design, View Transitions completely freeze DOM updates whilst they are taking place.) We're looking at restrict the View Transition to the final moments before `<Suspense>` resolves, but in the interim you may want to consider carefully whether to adopt this feature if this describes you.
|
- If you perform data fetching within your page setup functions, that you may wish to reconsider using this feature for the moment. (By design, View Transitions completely freeze DOM updates whilst they are taking place.) We're looking at restrict the View Transition to the final moments before `<Suspense>` resolves, but in the interim you may want to consider carefully whether to adopt this feature if this describes you.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Data fetching'
|
title: 'Data fetching'
|
||||||
description: Nuxt provides composables to handle data fetching within your application.
|
description: Nuxt provides composables to handle data fetching within your application.
|
||||||
navigation.icon: i-ph-plugs-connected-duotone
|
navigation.icon: i-ph-plugs-connected
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch`.
|
Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch`.
|
||||||
@ -16,9 +16,9 @@ Both `useFetch` and `useAsyncData` share a common set of options and patterns th
|
|||||||
|
|
||||||
Before that, it's imperative to know why these composables exist in the first place.
|
Before that, it's imperative to know why these composables exist in the first place.
|
||||||
|
|
||||||
## Why using specific composables?
|
## Why use specific composables for data fetching?
|
||||||
|
|
||||||
When using a framework like Nuxt that can perform calls and render pages on both client and server environments, some challenges must be addressed. This is why Nuxt provides composables to wrap your queries, instead of letting the developer rely on [`$fetch`](/docs/api/utils/dollarfetch) calls alone.
|
Nuxt is a framework which can run isomorphic (or universal) code in both server and client environments. If the [`$fetch` function](/docs/api/utils/dollarfetch) is used to perform data fetching in the setup function of a Vue component, this may cause data to be fetched twice, once on the server (to render the HTML) and once again on the client (when the HTML is hydrated). This is why Nuxt offers specific data fetching composables so data is fetched only once.
|
||||||
|
|
||||||
### Network calls duplication
|
### Network calls duplication
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ The [`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api
|
|||||||
|
|
||||||
The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/guide/concepts/rendering#universal-rendering).
|
The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/guide/concepts/rendering#universal-rendering).
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::tip
|
||||||
Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the **Payload tab**.
|
Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the **Payload tab**.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the *
|
|||||||
|
|
||||||
Nuxt uses Vue’s [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-calls basis.
|
Nuxt uses Vue’s [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-calls basis.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
You can add the [`<NuxtLoadingIndicator>`](/docs/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
|
You can add the [`<NuxtLoadingIndicator>`](/docs/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -54,13 +54,17 @@ const { data: count } = await useFetch('/api/count')
|
|||||||
|
|
||||||
This composable is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility.
|
This composable is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=njsGVmcWviY" target="_blank"}
|
||||||
|
Watch the video from Alexander Lichter to avoid using `useFetch` the wrong way!
|
||||||
|
::
|
||||||
|
|
||||||
:read-more{to="/docs/api/composables/use-fetch"}
|
:read-more{to="/docs/api/composables/use-fetch"}
|
||||||
|
|
||||||
:link-example{to="/docs/examples/features/data-fetching"}
|
:link-example{to="/docs/examples/features/data-fetching"}
|
||||||
|
|
||||||
## `$fetch`
|
## `$fetch`
|
||||||
|
|
||||||
Nuxt includes the `ofetch` library, and is auto-imported as the `$fetch` alias globally across your application. It's what `useFetch` uses behind the scenes.
|
Nuxt includes the [ofetch](https://github.com/unjs/ofetch) library, and is auto-imported as the `$fetch` alias globally across your application. It's what `useFetch` uses behind the scenes.
|
||||||
|
|
||||||
```vue twoslash [pages/todos.vue]
|
```vue twoslash [pages/todos.vue]
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -75,8 +79,8 @@ async function addTodo() {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](#why-using-specific-composables). :br
|
Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](#why-use-specific-composables-for-data-fetching). :br
|
||||||
It is recommended to use `$fetch` for client-side interactions (event based) or combined with [`useAsyncData`](#useasyncdata) when fetching the initial component data.
|
It is recommended to use `$fetch` for client-side interactions (event based) or combined with [`useAsyncData`](#useasyncdata) when fetching the initial component data.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -88,11 +92,15 @@ Read more about `$fetch`.
|
|||||||
|
|
||||||
The `useAsyncData` composable is responsible for wrapping async logic and returning the result once it is resolved.
|
The `useAsyncData` composable is responsible for wrapping async logic and returning the result once it is resolved.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
`useFetch(url)` is nearly equivalent to `useAsyncData(url, () => $fetch(url))`. :br
|
`useFetch(url)` is nearly equivalent to `useAsyncData(url, () => $fetch(url))`. :br
|
||||||
It's developer experience sugar for the most common use case.
|
It's developer experience sugar for the most common use case.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=0X-aOpSGabA" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter to dig deeper into the difference between `useFetch` and `useAsyncData`.
|
||||||
|
::
|
||||||
|
|
||||||
There are some cases when using the [`useFetch`](/docs/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
|
There are some cases when using the [`useFetch`](/docs/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
|
||||||
|
|
||||||
```vue [pages/users.vue]
|
```vue [pages/users.vue]
|
||||||
@ -104,7 +112,7 @@ const { data, error } = await useAsyncData(() => myGetFunction('users'))
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated.
|
The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated.
|
||||||
:br :br
|
:br :br
|
||||||
Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, like when you are creating your own custom composable wrapping `useAsyncData`.
|
Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, like when you are creating your own custom composable wrapping `useAsyncData`.
|
||||||
@ -122,11 +130,11 @@ const { data, error } = await useAsyncData(`user:${id}`, () => {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
The `useAsyncData` composable is a great way to wrap and wait for multiple `useFetch` to be done, and then retrieve the results of each.
|
The `useAsyncData` composable is a great way to wrap and wait for multiple `$fetch` requests to be completed, and then process the results.
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { data: discounts, pending } = await useAsyncData('cart-discount', async () => {
|
const { data: discounts, status } = await useAsyncData('cart-discount', async () => {
|
||||||
const [coupons, offers] = await Promise.all([
|
const [coupons, offers] = await Promise.all([
|
||||||
$fetch('/cart/coupons'),
|
$fetch('/cart/coupons'),
|
||||||
$fetch('/cart/offers')
|
$fetch('/cart/offers')
|
||||||
@ -148,18 +156,18 @@ Read more about `useAsyncData`.
|
|||||||
`useFetch` and `useAsyncData` have the same return values listed below.
|
`useFetch` and `useAsyncData` have the same return values listed below.
|
||||||
|
|
||||||
- `data`: the result of the asynchronous function that is passed in.
|
- `data`: the result of the asynchronous function that is passed in.
|
||||||
- `pending`: a boolean indicating whether the data is still being fetched.
|
|
||||||
- `refresh`/`execute`: a function that can be used to refresh the data returned by the `handler` function.
|
- `refresh`/`execute`: a function that can be used to refresh the data returned by the `handler` function.
|
||||||
|
- `clear`: a function that can be used to set `data` to `undefined`, set `error` to `null`, set `status` to `idle`, and mark any currently pending requests as cancelled.
|
||||||
- `error`: an error object if the data fetching failed.
|
- `error`: an error object if the data fetching failed.
|
||||||
- `status`: a string indicating the status of the data request (`"idle"`, `"pending"`, `"success"`, `"error"`).
|
- `status`: a string indicating the status of the data request (`"idle"`, `"pending"`, `"success"`, `"error"`).
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
`data`, `pending`, `error` and `status` are Vue refs accessible with `.value` in `<script setup>`
|
`data`, `error` and `status` are Vue refs accessible with `.value` in `<script setup>`
|
||||||
::
|
::
|
||||||
|
|
||||||
By default, Nuxt waits until a `refresh` is finished before it can be executed again.
|
By default, Nuxt waits until a `refresh` is finished before it can be executed again.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you have not fetched data on the server (for example, with `server: false`), then the data _will not_ be fetched until hydration completes. This means even if you await `useFetch` on client-side, `data` will remain null within `<script setup>`.
|
If you have not fetched data on the server (for example, with `server: false`), then the data _will not_ be fetched until hydration completes. This means even if you await `useFetch` on client-side, `data` will remain null within `<script setup>`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -169,18 +177,18 @@ If you have not fetched data on the server (for example, with `server: false`),
|
|||||||
|
|
||||||
### Lazy
|
### Lazy
|
||||||
|
|
||||||
By default, data fetching composables will wait for the resolution of their asynchronous function before navigating to a new page by using Vue’s Suspense. This feature can be ignored on client-side navigation with the `lazy` option. In that case, you will have to manually handle loading state using the `pending` value.
|
By default, data fetching composables will wait for the resolution of their asynchronous function before navigating to a new page by using Vue’s Suspense. This feature can be ignored on client-side navigation with the `lazy` option. In that case, you will have to manually handle loading state using the `status` value.
|
||||||
|
|
||||||
```vue twoslash [app.vue]
|
```vue twoslash [app.vue]
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { pending, data: posts } = useFetch('/api/posts', {
|
const { status, data: posts } = useFetch('/api/posts', {
|
||||||
lazy: true
|
lazy: true
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- you will need to handle a loading state -->
|
<!-- you will need to handle a loading state -->
|
||||||
<div v-if="pending">
|
<div v-if="status === 'pending'">
|
||||||
Loading ...
|
Loading ...
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
@ -195,7 +203,7 @@ You can alternatively use [`useLazyFetch`](/docs/api/composables/use-lazy-fetch)
|
|||||||
|
|
||||||
```vue twoslash
|
```vue twoslash
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { pending, data: posts } = useLazyFetch('/api/posts')
|
const { status, data: posts } = useLazyFetch('/api/posts')
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -218,7 +226,7 @@ Combined with the `lazy` option, this can be useful for data that is not needed
|
|||||||
const articles = await useFetch('/api/article')
|
const articles = await useFetch('/api/article')
|
||||||
|
|
||||||
/* This call will only be performed on the client */
|
/* This call will only be performed on the client */
|
||||||
const { pending, data: posts } = useFetch('/api/comments', {
|
const { status, data: comments } = useFetch('/api/comments', {
|
||||||
lazy: true,
|
lazy: true,
|
||||||
server: false
|
server: false
|
||||||
})
|
})
|
||||||
@ -254,7 +262,7 @@ const { data: mountains } = await useFetch('/api/mountains', {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Both `pick` and `transform` don't prevent the unwanted data from being fetched initially. But they will prevent unwanted data from being added to the payload transferred from server to client.
|
Both `pick` and `transform` don't prevent the unwanted data from being fetched initially. But they will prevent unwanted data from being added to the payload transferred from server to client.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -267,7 +275,7 @@ Both `pick` and `transform` don't prevent the unwanted data from being fetched i
|
|||||||
- [`useFetch`](/docs/api/composables/use-fetch) uses the provided URL as a key. Alternatively, a `key` value can be provided in the `options` object passed as a last argument.
|
- [`useFetch`](/docs/api/composables/use-fetch) uses the provided URL as a key. Alternatively, a `key` value can be provided in the `options` object passed as a last argument.
|
||||||
- [`useAsyncData`](/docs/api/composables/use-async-data) uses its first argument as a key if it is a string. If the first argument is the handler function that performs the query, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
|
- [`useAsyncData`](/docs/api/composables/use-async-data) uses its first argument as a key if it is a string. If the first argument is the handler function that performs the query, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
To get the cached data by key, you can use [`useNuxtData`](/docs/api/composables/use-nuxt-data)
|
To get the cached data by key, you can use [`useNuxtData`](/docs/api/composables/use-nuxt-data)
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -283,17 +291,32 @@ const { data, error, execute, refresh } = await useFetch('/api/users')
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p>{{ data }}</p>
|
<p>{{ data }}</p>
|
||||||
<button @click="refresh">Refresh data</button>
|
<button @click="() => refresh()">Refresh data</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
The `execute` function is an alias for `refresh` that works in exactly the same way but is more semantic for cases when the fetch is [not immediate](#not-immediate).
|
The `execute` function is an alias for `refresh` that works in exactly the same way but is more semantic for cases when the fetch is [not immediate](#not-immediate).
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::tip
|
||||||
To globally refetch or invalidate cached data, see [`clearNuxtData`](/docs/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/api/utils/refresh-nuxt-data).
|
To globally refetch or invalidate cached data, see [`clearNuxtData`](/docs/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/api/utils/refresh-nuxt-data).
|
||||||
::
|
::
|
||||||
|
|
||||||
|
#### Clear
|
||||||
|
|
||||||
|
If you want to clear the data provided, for whatever reason, without needing to know the specific key to pass to `clearNuxtData`, you can use the `clear` function provided by the composables.
|
||||||
|
|
||||||
|
```vue twoslash
|
||||||
|
<script setup lang="ts">
|
||||||
|
const { data, clear } = await useFetch('/api/users')
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
watch(() => route.path, (path) => {
|
||||||
|
if (path === '/') clear()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
#### Watch
|
#### Watch
|
||||||
|
|
||||||
To re-run your fetching function each time other reactive values in your application change, use the `watch` option. You can use it for one or multiple _watchable_ elements.
|
To re-run your fetching function each time other reactive values in your application change, use the `watch` option. You can use it for one or multiple _watchable_ elements.
|
||||||
@ -331,7 +354,7 @@ Sometimes you may need to compute an URL from reactive values, and refresh the d
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const id = ref(null)
|
const id = ref(null)
|
||||||
|
|
||||||
const { data, pending } = useLazyFetch('/api/user', {
|
const { data, status } = useLazyFetch('/api/user', {
|
||||||
query: {
|
query: {
|
||||||
user_id: id
|
user_id: id
|
||||||
}
|
}
|
||||||
@ -347,9 +370,11 @@ Every time a dependency changes, the data will be fetched using the newly constr
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const id = ref(null)
|
const id = ref(null)
|
||||||
|
|
||||||
const { data, pending, status } = useLazyFetch(() => `/api/users/${id.value}`, {
|
const { data, status } = useLazyFetch(() => `/api/users/${id.value}`, {
|
||||||
immediate: false
|
immediate: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pending = computed(() => status.value === 'pending');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -382,7 +407,7 @@ With that, you will need both the `status` to handle the fetch lifecycle, and `e
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { data, error, execute, pending, status } = await useLazyFetch('/api/comments', {
|
const { data, error, execute, status } = await useLazyFetch('/api/comments', {
|
||||||
immediate: false
|
immediate: false
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -392,7 +417,7 @@ const { data, error, execute, pending, status } = await useLazyFetch('/api/comme
|
|||||||
<button @click="execute">Get data</button>
|
<button @click="execute">Get data</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="pending">
|
<div v-else-if="status === 'pending'">
|
||||||
Loading comments...
|
Loading comments...
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -427,7 +452,7 @@ const { data } = await useFetch('/api/me', { headers })
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::caution
|
||||||
Be very careful before proxying headers to an external API and just include headers that you need. Not all headers are safe to be bypassed and might introduce unwanted behavior. Here is a list of common headers that are NOT to be proxied:
|
Be very careful before proxying headers to an external API and just include headers that you need. Not all headers are safe to be bypassed and might introduce unwanted behavior. Here is a list of common headers that are NOT to be proxied:
|
||||||
|
|
||||||
- `host`, `accept`
|
- `host`, `accept`
|
||||||
@ -441,13 +466,14 @@ Be very careful before proxying headers to an external API and just include head
|
|||||||
If you want to pass on/proxy cookies in the other direction, from an internal request back to the client, you will need to handle this yourself.
|
If you want to pass on/proxy cookies in the other direction, from an internal request back to the client, you will need to handle this yourself.
|
||||||
|
|
||||||
```ts [composables/fetch.ts]
|
```ts [composables/fetch.ts]
|
||||||
import { appendResponseHeader, H3Event } from 'h3'
|
import { appendResponseHeader } from 'h3'
|
||||||
|
import type { H3Event } from 'h3'
|
||||||
|
|
||||||
export const fetchWithCookie = async (event: H3Event, url: string) => {
|
export const fetchWithCookie = async (event: H3Event, url: string) => {
|
||||||
/* Get the response from the server endpoint */
|
/* Get the response from the server endpoint */
|
||||||
const res = await $fetch.raw(url)
|
const res = await $fetch.raw(url)
|
||||||
/* Get the cookies from the response */
|
/* Get the cookies from the response */
|
||||||
const cookies = (res.headers.get('set-cookie') || '').split(',')
|
const cookies = res.headers.getSetCookie()
|
||||||
/* Attach each cookie to our incoming Request */
|
/* Attach each cookie to our incoming Request */
|
||||||
for (const cookie of cookies) {
|
for (const cookie of cookies) {
|
||||||
appendResponseHeader(event, 'set-cookie', cookie)
|
appendResponseHeader(event, 'set-cookie', cookie)
|
||||||
@ -470,7 +496,7 @@ onMounted(() => console.log(document.cookie))
|
|||||||
|
|
||||||
## Options API support
|
## Options API support
|
||||||
|
|
||||||
Nuxt 3 provides a way to perform `asyncData` fetching within the Options API. You must wrap your component definition within `defineNuxtComponent` for this to work.
|
Nuxt provides a way to perform `asyncData` fetching within the Options API. You must wrap your component definition within `defineNuxtComponent` for this to work.
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script>
|
<script>
|
||||||
@ -486,7 +512,7 @@ export default defineNuxtComponent({
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
Using `<script setup>` or `<script setup lang="ts">` are the recommended way of declaring Vue components in Nuxt 3.
|
Using `<script setup>` or `<script setup lang="ts">` are the recommended way of declaring Vue components in Nuxt 3.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -498,7 +524,7 @@ When using `useAsyncData` and `useLazyAsyncData` to transfer data fetched on ser
|
|||||||
|
|
||||||
It is also possible to define your own serializer/deserializer for types that are not supported by Nuxt. You can read more in the [`useNuxtApp`](/docs/api/composables/use-nuxt-app#payload) docs.
|
It is also possible to define your own serializer/deserializer for types that are not supported by Nuxt. You can read more in the [`useNuxtApp`](/docs/api/composables/use-nuxt-app#payload) docs.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Note that this _does not apply_ to data passed from your server routes when fetched with `$fetch` or `useFetch` - see the next section for more information.
|
Note that this _does not apply_ to data passed from your server routes when fetched with `$fetch` or `useFetch` - see the next section for more information.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -599,3 +625,37 @@ const { data } = await useFetch('/api/superjson', {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Recipes
|
||||||
|
|
||||||
|
### Consuming SSE (Server Sent Events) via POST request
|
||||||
|
|
||||||
|
::tip
|
||||||
|
If you're consuming SSE via GET request, you can use [`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) or VueUse composable [`useEventSource`](https://vueuse.org/core/useEventSource/).
|
||||||
|
::
|
||||||
|
|
||||||
|
When consuming SSE via POST request, you need to handle the connection manually. Here's how you can do it:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Make a POST request to the SSE endpoint
|
||||||
|
const response = await $fetch<ReadableStream>('/chats/ask-ai', {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
query: "Hello AI, how are you?",
|
||||||
|
},
|
||||||
|
responseType: 'stream',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create a new ReadableStream from the response with TextDecoderStream to get the data as text
|
||||||
|
const reader = response.pipeThrough(new TextDecoderStream()).getReader()
|
||||||
|
|
||||||
|
// Read the chunk of data as we get it
|
||||||
|
while (true) {
|
||||||
|
const { value, done } = await reader.read()
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
break
|
||||||
|
|
||||||
|
console.log('Received:', value)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
---
|
---
|
||||||
title: 'State Management'
|
title: 'State Management'
|
||||||
description: Nuxt provides powerful state management libraries and the useState composable to create a reactive and SSR-friendly shared state.
|
description: Nuxt provides powerful state management libraries and the useState composable to create a reactive and SSR-friendly shared state.
|
||||||
navigation.icon: i-ph-database-duotone
|
navigation.icon: i-ph-database
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt provides the [`useState`](/docs/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components.
|
Nuxt provides the [`useState`](/docs/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components.
|
||||||
|
|
||||||
[`useState`](/docs/api/composables/use-state) is an SSR-friendly [`ref`](https://vuejs.org/api/reactivity-core.html#ref) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
|
[`useState`](/docs/api/composables/use-state) is an SSR-friendly [`ref`](https://vuejs.org/api/reactivity-core.html#ref) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
|
||||||
|
|
||||||
::callout
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=mv0WcBABcIk" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about why and when to use `useState()`.
|
||||||
|
::
|
||||||
|
|
||||||
|
::important
|
||||||
Because the data inside [`useState`](/docs/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.
|
Because the data inside [`useState`](/docs/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -18,12 +22,12 @@ Read more about `useState` composable.
|
|||||||
|
|
||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Never define `const state = ref()` outside of `<script setup>` or `setup()` function.<br>
|
Never define `const state = ref()` outside of `<script setup>` or `setup()` function.<br>
|
||||||
Such state will be shared across all users visiting your website and can lead to memory leaks!
|
For example, doing `export myState = ref({})` would result in state shared across requests on the server and can lead to memory leaks.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="green" icon="i-ph-check-circle-duotone"}
|
::tip{icon="i-ph-check-circle"}
|
||||||
Instead use `const useX = () => useState('x')`
|
Instead use `const useX = () => useState('x')`
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -53,7 +57,7 @@ const counter = useState('counter', () => Math.round(Math.random() * 1000))
|
|||||||
|
|
||||||
:link-example{to="/docs/examples/features/state-management"}
|
:link-example{to="/docs/examples/features/state-management"}
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
To globally invalidate cached state, see [`clearNuxtState`](/docs/api/utils/clear-nuxt-state) util.
|
To globally invalidate cached state, see [`clearNuxtState`](/docs/api/utils/clear-nuxt-state) util.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -71,7 +75,7 @@ await callOnce(async () => {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
This is similar to the [`nuxtServerInit` action](https://v2.nuxt.com/docs/directory-structure/store/#the-nuxtserverinit-action) in Nuxt 2, which allows filling the initial state of your store server-side before rendering the page.
|
This is similar to the [`nuxtServerInit` action](https://v2.nuxt.com/docs/directory-structure/store/#the-nuxtserverinit-action) in Nuxt 2, which allows filling the initial state of your store server-side before rendering the page.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -81,7 +85,7 @@ This is similar to the [`nuxtServerInit` action](https://v2.nuxt.com/docs/direct
|
|||||||
|
|
||||||
In this example, we leverage the [Pinia module](/modules/pinia) to create a global store and use it across the app.
|
In this example, we leverage the [Pinia module](/modules/pinia) to create a global store and use it across the app.
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
Make sure to install the Pinia module with `npx nuxi@latest module add pinia` or follow the [module's installation steps](https://pinia.vuejs.org/ssr/nuxt.html#Installation).
|
Make sure to install the Pinia module with `npx nuxi@latest module add pinia` or follow the [module's installation steps](https://pinia.vuejs.org/ssr/nuxt.html#Installation).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -130,12 +134,12 @@ export const useLocale = () => {
|
|||||||
|
|
||||||
export const useDefaultLocale = (fallback = 'en-US') => {
|
export const useDefaultLocale = (fallback = 'en-US') => {
|
||||||
const locale = ref(fallback)
|
const locale = ref(fallback)
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
|
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
|
||||||
if (reqLocale) {
|
if (reqLocale) {
|
||||||
locale.value = reqLocale
|
locale.value = reqLocale
|
||||||
}
|
}
|
||||||
} else if (process.client) {
|
} else if (import.meta.client) {
|
||||||
const navLang = navigator.language
|
const navLang = navigator.language
|
||||||
if (navLang) {
|
if (navLang) {
|
||||||
locale.value = navLang
|
locale.value = navLang
|
||||||
@ -192,7 +196,6 @@ const date = useLocaleDate(new Date('2016-10-26'))
|
|||||||
By using [auto-imported composables](/docs/guide/directory-structure/composables) we can define global type-safe states and import them across the app.
|
By using [auto-imported composables](/docs/guide/directory-structure/composables) we can define global type-safe states and import them across the app.
|
||||||
|
|
||||||
```ts twoslash [composables/states.ts]
|
```ts twoslash [composables/states.ts]
|
||||||
export const useCounter = () => useState<number>('counter', () => 0)
|
|
||||||
export const useColor = () => useState<string>('color', () => 'pink')
|
export const useColor = () => useState<string>('color', () => 'pink')
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -209,6 +212,10 @@ const color = useColor() // Same as useState('color')
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=dZSNW07sO-A" target="_blank"}
|
||||||
|
Watch a video from Daniel Roe on how to deal with global state and SSR in Nuxt.
|
||||||
|
::
|
||||||
|
|
||||||
## Using third-party libraries
|
## Using third-party libraries
|
||||||
|
|
||||||
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide](/docs/migration/configuration#vuex).
|
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide](/docs/migration/configuration#vuex).
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
---
|
---
|
||||||
title: 'Error Handling'
|
title: 'Error Handling'
|
||||||
description: 'Learn how to catch and handle errors in Nuxt.'
|
description: 'Learn how to catch and handle errors in Nuxt.'
|
||||||
navigation.icon: i-ph-bug-beetle-duotone
|
navigation.icon: i-ph-bug-beetle
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt 3 is a full-stack framework, which means there are several sources of unpreventable user runtime errors that can happen in different contexts:
|
Nuxt is a full-stack framework, which means there are several sources of unpreventable user runtime errors that can happen in different contexts:
|
||||||
|
|
||||||
- Errors during the Vue rendering lifecycle (SSR & CSR)
|
- Errors during the Vue rendering lifecycle (SSR & CSR)
|
||||||
- Errors during Nitro server lifecycle ([`server/`](/docs/guide/directory-structure/server) directory)
|
|
||||||
- Server and client startup errors (SSR + CSR)
|
- Server and client startup errors (SSR + CSR)
|
||||||
|
- Errors during Nitro server lifecycle ([`server/`](/docs/guide/directory-structure/server) directory)
|
||||||
- Errors downloading JS chunks
|
- Errors downloading JS chunks
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
**SSR** stands for **Server-Side Rendering** and **CSR** for **Client-Side Rendering**.
|
**SSR** stands for **Server-Side Rendering** and **CSR** for **Client-Side Rendering**.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Vue Rendering Lifecycle
|
## Vue Errors
|
||||||
|
|
||||||
You can hook into Vue errors using [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured).
|
You can hook into Vue errors using [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured).
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Note that the `vue:error` hook is based on [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured) lifecycle hook.
|
Note that the `vue:error` hook is based on [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured) lifecycle hook.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -51,11 +51,11 @@ This includes:
|
|||||||
- mounting the app (on client-side), though you should handle this case with `onErrorCaptured` or with `vue:error`
|
- mounting the app (on client-side), though you should handle this case with `onErrorCaptured` or with `vue:error`
|
||||||
- processing the `app:mounted` hook
|
- processing the `app:mounted` hook
|
||||||
|
|
||||||
## Nitro Server Lifecycle
|
## Nitro Server Errors
|
||||||
|
|
||||||
You cannot currently define a server-side handler for these errors, but can render an error page, see the [Render an Error Page](#error-page) section.
|
You cannot currently define a server-side handler for these errors, but can render an error page, see the [Render an Error Page](#error-page) section.
|
||||||
|
|
||||||
## Errors with JS chunks
|
## Errors with JS Chunks
|
||||||
|
|
||||||
You might encounter chunk loading errors due to a network connectivity failure or a new deployment (which invalidates your old, hashed JS chunk URLs). Nuxt provides built-in support for handling chunk loading errors by performing a hard reload when a chunk fails to load during route navigation.
|
You might encounter chunk loading errors due to a network connectivity failure or a new deployment (which invalidates your old, hashed JS chunk URLs). Nuxt provides built-in support for handling chunk loading errors by performing a hard reload when a chunk fails to load during route navigation.
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ You can change this behavior by setting `experimental.emitRouteChunkError` to `f
|
|||||||
|
|
||||||
## Error Page
|
## Error Page
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
When Nuxt encounters a fatal error (any unhandled error on the server, or an error created with `fatal: true` on the client) it will either render a JSON response (if requested with `Accept: application/json` header) or trigger a full-screen error page.
|
When Nuxt encounters a fatal error (any unhandled error on the server, or an error created with `fatal: true` on the client) it will either render a JSON response (if requested with `Accept: application/json` header) or trigger a full-screen error page.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -121,11 +121,15 @@ export default defineNuxtPlugin(nuxtApp => {
|
|||||||
|
|
||||||
When you are ready to remove the error page, you can call the [`clearError`](/docs/api/utils/clear-error) helper function, which takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
|
When you are ready to remove the error page, you can call the [`clearError`](/docs/api/utils/clear-error) helper function, which takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
Make sure to check before using anything dependent on Nuxt plugins, such as `$route` or `useRouter`, as if a plugin threw an error, then it won't be re-run until you clear the error.
|
Make sure to check before using anything dependent on Nuxt plugins, such as `$route` or `useRouter`, as if a plugin threw an error, then it won't be re-run until you clear the error.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
|
Rendering an error page is an entirely separate page load, meaning any registered middleware will run again. You can use [`useError`](#useerror) in middleware to check if an error is being handled.
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
If you are running on Node 16 and you set any cookies when rendering your error page, they will [overwrite cookies previously set](https://github.com/nuxt/nuxt/pull/20585). We recommend using a newer version of Node as Node 16 reached end-of-life in September 2023.
|
If you are running on Node 16 and you set any cookies when rendering your error page, they will [overwrite cookies previously set](https://github.com/nuxt/nuxt/pull/20585). We recommend using a newer version of Node as Node 16 reached end-of-life in September 2023.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -146,10 +150,10 @@ Read more about `useError` composable.
|
|||||||
### `createError`
|
### `createError`
|
||||||
|
|
||||||
```ts [TS Signature]
|
```ts [TS Signature]
|
||||||
function createError (err: { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
|
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
|
||||||
```
|
```
|
||||||
|
|
||||||
Create an error object with additional metadata. It is usable in both the Vue and Server portions of your app, and is meant to be thrown.
|
Create an error object with additional metadata. You can pass a string to be set as the error `message` or an object containing error properties. It is usable in both the Vue and Server portions of your app, and is meant to be thrown.
|
||||||
|
|
||||||
If you throw an error created with `createError`:
|
If you throw an error created with `createError`:
|
||||||
- on server-side, it will trigger a full-screen error page which you can clear with [`clearError`](#clearerror).
|
- on server-side, it will trigger a full-screen error page which you can clear with [`clearError`](#clearerror).
|
||||||
@ -207,7 +211,7 @@ This component is responsible for handling errors that occur within its default
|
|||||||
|
|
||||||
The `#error` slot will receive `error` as a prop. (If you set `error = null` it will trigger re-rendering the default slot; you'll need to ensure that the error is fully resolved first or the error slot will just be rendered a second time.)
|
The `#error` slot will receive `error` as a prop. (If you set `error = null` it will trigger re-rendering the default slot; you'll need to ensure that the error is fully resolved first or the error slot will just be rendered a second time.)
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you navigate to another route, the error will be cleared automatically.
|
If you navigate to another route, the error will be cleared automatically.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Server'
|
title: 'Server'
|
||||||
description: Build full-stack applications with Nuxt's server framework. You can fetch data from your database or another server, create APIs, or even generate static server-side content like a sitemap or a RSS feed - all from a single codebase.
|
description: Build full-stack applications with Nuxt's server framework. You can fetch data from your database or another server, create APIs, or even generate static server-side content like a sitemap or a RSS feed - all from a single codebase.
|
||||||
navigation.icon: i-ph-computer-tower-duotone
|
navigation.icon: i-ph-computer-tower
|
||||||
---
|
---
|
||||||
|
|
||||||
:read-more{to="/docs/guide/directory-structure/server"}
|
:read-more{to="/docs/guide/directory-structure/server"}
|
||||||
@ -20,6 +20,10 @@ Using Nitro gives Nuxt superpowers:
|
|||||||
|
|
||||||
Nitro is internally using [h3](https://github.com/unjs/h3), a minimal H(TTP) framework built for high performance and portability.
|
Nitro is internally using [h3](https://github.com/unjs/h3), a minimal H(TTP) framework built for high performance and portability.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=DkvgJa-X31k" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter to understand the responsibilities of Nuxt and Nitro in your application.
|
||||||
|
::
|
||||||
|
|
||||||
## Server Endpoints & Middleware
|
## Server Endpoints & Middleware
|
||||||
|
|
||||||
You can easily manage the server-only part of your Nuxt app, from API endpoints to middleware.
|
You can easily manage the server-only part of your Nuxt app, from API endpoints to middleware.
|
||||||
@ -83,9 +87,9 @@ export default defineNuxtConfig({
|
|||||||
Learn about all available route rules are available to customize the rendering mode of your routes.
|
Learn about all available route rules are available to customize the rendering mode of your routes.
|
||||||
::
|
::
|
||||||
|
|
||||||
In addition, there are some route rules (for example, `ssr` and `experimentalNoScripts`) that are Nuxt specific to change the behavior when rendering your pages to HTML.
|
In addition, there are some route rules (for example, `ssr`, `appMiddleware`, and `experimentalNoScripts`) that are Nuxt specific to change the behavior when rendering your pages to HTML.
|
||||||
|
|
||||||
Some route rules (`redirect` and `prerender`) also affect client-side behavior.
|
Some route rules (`appMiddleware`, `redirect` and `prerender`) also affect client-side behavior.
|
||||||
|
|
||||||
Nitro is used to build the app for server side rendering, as well as pre-rendering.
|
Nitro is used to build the app for server side rendering, as well as pre-rendering.
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: 'Layers'
|
title: 'Layers'
|
||||||
description: Nuxt provides a powerful system that allows you to extend the default files, configs, and much more.
|
description: Nuxt provides a powerful system that allows you to extend the default files, configs, and much more.
|
||||||
navigation.icon: i-ph-stack-duotone
|
navigation.icon: i-ph-stack
|
||||||
---
|
---
|
||||||
|
|
||||||
One of the core features of Nuxt 3 is the layers and extending support. You can extend a default Nuxt application to reuse components, utils, and configuration. The layers structure is almost identical to a standard Nuxt application which makes them easy to author and maintain.
|
One of the core features of Nuxt is the layers and extending support. You can extend a default Nuxt application to reuse components, utils, and configuration. The layers structure is almost identical to a standard Nuxt application which makes them easy to author and maintain.
|
||||||
|
|
||||||
## Use Cases
|
## Use Cases
|
||||||
|
|
||||||
@ -14,12 +14,19 @@ One of the core features of Nuxt 3 is the layers and extending support. You can
|
|||||||
- Create Nuxt module presets
|
- Create Nuxt module presets
|
||||||
- Share standard setup across projects
|
- Share standard setup across projects
|
||||||
- Create Nuxt themes
|
- Create Nuxt themes
|
||||||
|
- Enhance code organization by implementing a modular architecture and support Domain-Driven Design (DDD) pattern in large scale projects.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
You can extend a layer by adding the [extends](/docs/api/nuxt-config#extends) property to the [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) file.
|
By default, any layers within your project in the `~/layers` directory will be automatically registered as layers in your project
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
::note
|
||||||
|
Layer auto-registration was introduced in Nuxt v3.12.0
|
||||||
|
::
|
||||||
|
|
||||||
|
In addition, you can extend from a layer by adding the [extends](/docs/api/nuxt-config#extends) property to your [`nuxt.config`](/docs/guide/directory-structure/nuxt-config) file.
|
||||||
|
|
||||||
|
```ts [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
extends: [
|
extends: [
|
||||||
'../base', // Extend from a local layer
|
'../base', // Extend from a local layer
|
||||||
@ -29,12 +36,29 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also pass an authentication token if you are extending from a private GitHub repository:
|
||||||
|
|
||||||
|
```ts [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
extends: [
|
||||||
|
// per layer configuration
|
||||||
|
['github:my-themes/private-awesome', { auth: process.env.GITHUB_TOKEN }]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Nuxt uses [unjs/c12](https://c12.unjs.io) and [unjs/giget](https://giget.unjs.io) for extending remote layers. Check the documentation for more information and all available options.
|
||||||
|
|
||||||
::read-more{to="/docs/guide/going-further/layers"}
|
::read-more{to="/docs/guide/going-further/layers"}
|
||||||
Read more about layers in the **Layer Author Guide**.
|
Read more about layers in the **Layer Author Guide**.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=lnFCM7c9f7I" target="_blank"}
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=lnFCM7c9f7I" target="_blank"}
|
||||||
Watch Learn Vue video about Nuxt Layers.
|
Watch a video from Learn Vue about Nuxt Layers.
|
||||||
|
::
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=fr5yo3aVkfA" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about Nuxt Layers.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
193
docs/1.getting-started/9.prerendering.md
Normal file
193
docs/1.getting-started/9.prerendering.md
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
---
|
||||||
|
title: "Prerendering"
|
||||||
|
description: Nuxt allows pages to be statically rendered at build time to improve certain performance or SEO metrics
|
||||||
|
navigation.icon: i-ph-code-block
|
||||||
|
---
|
||||||
|
|
||||||
|
Nuxt allows for select pages from your application to be rendered at build time. Nuxt will serve the prebuilt pages when requested instead of generating them on the fly.
|
||||||
|
|
||||||
|
:read-more{title="Nuxt rendering modes" to="/docs/guide/concepts/rendering"}
|
||||||
|
|
||||||
|
## Crawl-based Pre-rendering
|
||||||
|
|
||||||
|
Use the [`nuxi generate` command](/docs/api/commands/generate) to build and pre-render your application using the [Nitro](/docs/guide/concepts/server-engine) crawler. This command is similar to `nuxt build` with the `nitro.static` option set to `true`, or running `nuxt build --prerender`.
|
||||||
|
|
||||||
|
This will build your site, stand up a nuxt instance, and, by default, prerender the root page `/` along with any of your site's pages it links to, any of your site's pages they link to, and so on.
|
||||||
|
|
||||||
|
::package-managers
|
||||||
|
|
||||||
|
```bash [npm]
|
||||||
|
npx nuxi generate
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn dlx nuxi generate
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm dlx nuxi generate
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [bun]
|
||||||
|
bun x nuxi generate
|
||||||
|
```
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
You can now deploy the `.output/public` directory to any static hosting service or preview it locally with `npx serve .output/public`.
|
||||||
|
|
||||||
|
Working of the Nitro crawler:
|
||||||
|
|
||||||
|
1. Load the HTML of your application's root route (`/`), any non-dynamic pages in your `~/pages` directory, and any other routes in the `nitro.prerender.routes` array.
|
||||||
|
2. Save the HTML and `payload.json` to the `~/.output/public/` directory to be served statically.
|
||||||
|
3. Find all anchor tags (`<a href="...">`) in the HTML to navigate to other routes.
|
||||||
|
4. Repeat steps 1-3 for each anchor tag found until there are no more anchor tags to crawl.
|
||||||
|
|
||||||
|
This is important to understand since pages that are not linked to a discoverable page can't be pre-rendered automatically.
|
||||||
|
|
||||||
|
::read-more{to="/docs/api/commands/generate#nuxi-generate"}
|
||||||
|
Read more about the `nuxi generate` command.
|
||||||
|
::
|
||||||
|
|
||||||
|
### Selective Pre-rendering
|
||||||
|
|
||||||
|
You can manually specify routes that [Nitro](/docs/guide/concepts/server-engine) will fetch and pre-render during the build or ignore routes that you don't want to pre-render like `/dynamic` in the `nuxt.config` file:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
nitro: {
|
||||||
|
prerender: {
|
||||||
|
routes: ["/user/1", "/user/2"],
|
||||||
|
ignore: ["/dynamic"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can combine this with the `crawlLinks` option to pre-render a set of routes that the crawler can't discover like your `/sitemap.xml` or `/robots.txt`:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
nitro: {
|
||||||
|
prerender: {
|
||||||
|
crawlLinks: true,
|
||||||
|
routes: ["/sitemap.xml", "/robots.txt"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Setting `nitro.prerender` to `true` is similar to `nitro.prerender.crawlLinks` to `true`.
|
||||||
|
|
||||||
|
::read-more{to="https://nitro.unjs.io/config#prerender"}
|
||||||
|
Read more about pre-rendering in the Nitro documentation.
|
||||||
|
::
|
||||||
|
|
||||||
|
Lastly, you can manually configure this using routeRules.
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
routeRules: {
|
||||||
|
// Set prerender to true to configure it to be prerendered
|
||||||
|
"/rss.xml": { prerender: true },
|
||||||
|
// Set it to false to configure it to be skipped for prerendering
|
||||||
|
"/this-DOES-NOT-get-prerendered": { prerender: false },
|
||||||
|
// Everything under /blog gets prerendered as long as it
|
||||||
|
// is linked to from another page
|
||||||
|
"/blog/**": { prerender: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
::read-more{to="https://nitro.unjs.io/config/#routerules"}
|
||||||
|
Read more about Nitro's `routeRules` configuration.
|
||||||
|
::
|
||||||
|
|
||||||
|
As a shorthand, you can also configure this in a page file using [`defineRouteRules`](/docs/api/utils/define-route-rules).
|
||||||
|
|
||||||
|
::read-more{to="/docs/guide/going-further/experimental-features#inlinerouterules" icon="i-ph-star"}
|
||||||
|
This feature is experimental and in order to use it you must enable the `experimental.inlineRouteRules` option in your `nuxt.config`.
|
||||||
|
::
|
||||||
|
|
||||||
|
```vue [pages/index.vue]
|
||||||
|
<script setup>
|
||||||
|
// Or set at the page level
|
||||||
|
defineRouteRules({
|
||||||
|
prerender: true,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Homepage</h1>
|
||||||
|
<p>Pre-rendered at build time</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
This will be translated to:
|
||||||
|
|
||||||
|
```ts [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
routeRules: {
|
||||||
|
"/": { prerender: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Runtime prerender configuration
|
||||||
|
|
||||||
|
### `prerenderRoutes`
|
||||||
|
|
||||||
|
You can use this at runtime within a [Nuxt context](/docs/guide/going-further/nuxt-app#the-nuxt-context) to add more routes for Nitro to prerender.
|
||||||
|
|
||||||
|
```vue [pages/index.vue]
|
||||||
|
<script setup>
|
||||||
|
prerenderRoutes(["/some/other/url"]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>This will register other routes for prerendering when prerendered</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
:read-more{title="prerenderRoutes" to="/docs/api/utils/prerender-routes"}
|
||||||
|
|
||||||
|
### `prerender:routes` Nuxt hook
|
||||||
|
|
||||||
|
This is called before prerendering for additional routes to be registered.
|
||||||
|
|
||||||
|
```ts [nitro.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
hooks: {
|
||||||
|
async "prerender:routes"(ctx) {
|
||||||
|
const { pages } = await fetch("https://api.some-cms.com/pages").then(
|
||||||
|
(res) => res.json(),
|
||||||
|
);
|
||||||
|
for (const page of pages) {
|
||||||
|
ctx.routes.add(`/${page.name}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### `prerender:generate` Nitro hook
|
||||||
|
|
||||||
|
This is called for each route during prerendering. You can use this for fine grained handling of each route that gets prerendered.
|
||||||
|
|
||||||
|
```ts [nitro.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
nitro: {
|
||||||
|
hooks: {
|
||||||
|
"prerender:generate"(route) {
|
||||||
|
if (route.route?.includes("private")) {
|
||||||
|
route.skip = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
@ -1,3 +1,3 @@
|
|||||||
title: Get Started
|
title: Get Started
|
||||||
titleTemplate: '%s · Get Started with Nuxt'
|
titleTemplate: '%s · Get Started with Nuxt'
|
||||||
icon: i-ph-rocket-launch-duotone
|
icon: i-ph-rocket-launch
|
||||||
|
@ -7,13 +7,16 @@ surround: false
|
|||||||
---
|
---
|
||||||
|
|
||||||
::card-group{class="sm:grid-cols-1"}
|
::card-group{class="sm:grid-cols-1"}
|
||||||
::card{icon="i-ph-medal-duotone" title="Key Concepts" to="/docs/guide/concepts"}
|
::card{icon="i-ph-medal" title="Key Concepts" to="/docs/guide/concepts"}
|
||||||
Discover the main concepts behind Nuxt, from auto-import, hybrid rendering to its TypeScript support.
|
Discover the main concepts behind Nuxt, from auto-import, hybrid rendering to its TypeScript support.
|
||||||
::
|
::
|
||||||
::card{icon="i-ph-folders-duotone" title="Directory Structure" to="/docs/guide/directory-structure"}
|
::card{icon="i-ph-folders" title="Directory Structure" to="/docs/guide/directory-structure"}
|
||||||
Learn about Nuxt directory structure and what benefits each directory or file offers.
|
Learn about Nuxt directory structure and what benefits each directory or file offers.
|
||||||
::
|
::
|
||||||
::card{icon="i-ph-star-duotone" title="Going Further" to="/docs/guide/going-further"}
|
::card{icon="i-ph-star" title="Going Further" to="/docs/guide/going-further"}
|
||||||
Master Nuxt with advanced concepts like experimental features, hooks, modules, and more.
|
Master Nuxt with advanced concepts like experimental features, hooks, modules, and more.
|
||||||
::
|
::
|
||||||
|
::card{icon="i-ph-book-open" title="Recipes" to="/docs/guide/recipes"}
|
||||||
|
Find solutions to common problems and learn how to implement them in your Nuxt project.
|
||||||
|
::
|
||||||
::
|
::
|
||||||
|
@ -15,15 +15,15 @@ Thanks to its opinionated directory structure, Nuxt can auto-import your [`compo
|
|||||||
|
|
||||||
Contrary to a classic global declaration, Nuxt preserves typings, IDEs completions and hints, and **only includes what is used in your production code**.
|
Contrary to a classic global declaration, Nuxt preserves typings, IDEs completions and hints, and **only includes what is used in your production code**.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-lightbulb-duotone"}
|
::note
|
||||||
In the docs, every function that is not explicitly imported is auto-imported by Nuxt and can be used as-is in your code. You can find a reference for auto-imported components, composables and utilities in the [API section](/docs/api).
|
In the docs, every function that is not explicitly imported is auto-imported by Nuxt and can be used as-is in your code. You can find a reference for auto-imported components, composables and utilities in the [API section](/docs/api).
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
In the [`server`](/docs/guide/directory-structure/server) directory, Nuxt auto-imports exported functions and variables from `server/utils/`.
|
In the [`server`](/docs/guide/directory-structure/server) directory, Nuxt auto-imports exported functions and variables from `server/utils/`.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
You can also auto-import functions exported from custom folders or third-party packages by configuring the [`imports`](/docs/api/nuxt-config#imports) section of your `nuxt.config` file.
|
You can also auto-import functions exported from custom folders or third-party packages by configuring the [`imports`](/docs/api/nuxt-config#imports) section of your `nuxt.config` file.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ Nuxt auto-imports functions and composables to perform [data fetching](/docs/get
|
|||||||
|
|
||||||
```vue twoslash
|
```vue twoslash
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
/* useAsyncData() and $fetch() are auto-imported */
|
/* useFetch() is auto-imported */
|
||||||
const { data, refresh } = await useFetch('/api/hello')
|
const { data, refresh, status } = await useFetch('/api/hello')
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -60,7 +60,15 @@ That means that (with very few exceptions) you cannot use them outside a Nuxt pl
|
|||||||
|
|
||||||
If you get an error message like `Nuxt instance is unavailable` then it probably means you are calling a Nuxt composable in the wrong place in the Vue or Nuxt lifecycle.
|
If you get an error message like `Nuxt instance is unavailable` then it probably means you are calling a Nuxt composable in the wrong place in the Vue or Nuxt lifecycle.
|
||||||
|
|
||||||
::read-more{to="/docs/guide/going-further/experimental-features#asynccontext" icon="i-ph-star-duotone"}
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=ofuKRZLtOdY" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about handling async code in composables and fixing `Nuxt instance is unavailable` in your app.
|
||||||
|
::
|
||||||
|
|
||||||
|
::tip
|
||||||
|
When using a composable that requires the Nuxt context inside a non-SFC component, you need to wrap your component with `defineNuxtComponent` instead of `defineComponent`
|
||||||
|
::
|
||||||
|
|
||||||
|
::read-more{to="/docs/guide/going-further/experimental-features#asynccontext" icon="i-ph-star"}
|
||||||
Checkout the `asyncContext` experimental feature to use Nuxt composables in async functions.
|
Checkout the `asyncContext` experimental feature to use Nuxt composables in async functions.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -84,7 +92,7 @@ export const useMyComposable = () => {
|
|||||||
```ts twoslash [composables/example.ts]
|
```ts twoslash [composables/example.ts]
|
||||||
export const useMyComposable = () => {
|
export const useMyComposable = () => {
|
||||||
// Because your composable is called in the right place in the lifecycle,
|
// Because your composable is called in the right place in the lifecycle,
|
||||||
// useRuntimeConfig will also work
|
// useRuntimeConfig will work here
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
@ -101,6 +109,11 @@ Nuxt directly auto-imports files created in defined directories:
|
|||||||
|
|
||||||
:link-example{to="/docs/examples/features/auto-imports"}
|
:link-example{to="/docs/examples/features/auto-imports"}
|
||||||
|
|
||||||
|
::warning
|
||||||
|
**Auto-imported `ref` and `computed` won't be unwrapped in a component `<template>`.** :br
|
||||||
|
This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-when-unwrapping-in-templates).
|
||||||
|
::
|
||||||
|
|
||||||
### Explicit Imports
|
### Explicit Imports
|
||||||
|
|
||||||
Nuxt exposes every auto-import with the `#imports` alias that can be used to make the import explicit if needed:
|
Nuxt exposes every auto-import with the `#imports` alias that can be used to make the import explicit if needed:
|
||||||
@ -150,7 +163,7 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
Nuxt also allows auto-importing from third-party packages.
|
Nuxt also allows auto-importing from third-party packages.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you are using the Nuxt module for that package, it is likely that the module has already configured auto-imports for that package.
|
If you are using the Nuxt module for that package, it is likely that the module has already configured auto-imports for that package.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -168,3 +181,7 @@ export default defineNuxtConfig({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=FT2LQJ2NvVI" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter on how to easily set up custom auto imports.
|
||||||
|
::
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 'Vue.js Development'
|
title: 'Vue.js Development'
|
||||||
description: "Nuxt uses Vue.js and adds features such as component auto-imports, file-based routing and composables for a SSR-friendly usage."
|
description: "Nuxt uses Vue.js and adds features such as component auto-imports, file-based routing and composables for an SSR-friendly usage."
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt integrates Vue 3, the new major release of Vue that enables new patterns for Nuxt users.
|
Nuxt integrates Vue 3, the new major release of Vue that enables new patterns for Nuxt users.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
While an in-depth knowledge of Vue is not required to use Nuxt, we recommend that you read the documentation and go through some of the examples on [vuejs.org](https://vuejs.org).
|
While an in-depth knowledge of Vue is not required to use Nuxt, we recommend that you read the documentation and go through some of the examples on [vuejs.org](https://vuejs.org).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ Most applications need multiple pages and a way to navigate between them. This i
|
|||||||
|
|
||||||
## Differences with Nuxt 2 / Vue 2
|
## Differences with Nuxt 2 / Vue 2
|
||||||
|
|
||||||
Nuxt 3 is based on Vue 3. The new major Vue version introduces several changes that Nuxt takes advantage of:
|
Nuxt 3+ is based on Vue 3. The new major Vue version introduces several changes that Nuxt takes advantage of:
|
||||||
|
|
||||||
- Better performance
|
- Better performance
|
||||||
- Composition API
|
- Composition API
|
||||||
@ -89,15 +89,15 @@ const increment = () => count.value++
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
The goal of Nuxt 3 is to provide a great developer experience around the Composition API.
|
The goal of Nuxt is to provide a great developer experience around the Composition API.
|
||||||
|
|
||||||
- Use auto-imported [Reactivity functions](https://vuejs.org/api/reactivity-core.html) from Vue and Nuxt 3 [built-in composables](/docs/api/composables/use-async-data).
|
- Use auto-imported [Reactivity functions](https://vuejs.org/api/reactivity-core.html) from Vue and Nuxt [built-in composables](/docs/api/composables/use-async-data).
|
||||||
- Write your own auto-imported reusable functions in the [`composables/` directory](/docs/guide/directory-structure/composables).
|
- Write your own auto-imported reusable functions in the [`composables/` directory](/docs/guide/directory-structure/composables).
|
||||||
|
|
||||||
### TypeScript Support
|
### TypeScript Support
|
||||||
|
|
||||||
Both Vue 3 and Nuxt 3 are written in TypeScript. A fully typed codebase prevents mistakes and documents APIs usage. This doesn’t mean that you have to write your application in TypeScript to take advantage of it. With Nuxt 3, you can opt-in by renaming your file from `.js` to `.ts` , or add `<script setup lang="ts">` in a component.
|
Both Vue 3 and Nuxt 3+ are written in TypeScript. A fully typed codebase prevents mistakes and documents APIs usage. This doesn’t mean that you have to write your application in TypeScript to take advantage of it. With Nuxt 3, you can opt-in by renaming your file from `.js` to `.ts` , or add `<script setup lang="ts">` in a component.
|
||||||
|
|
||||||
::read-more{to="/docs/guide/concepts/typescript"}
|
::read-more{to="/docs/guide/concepts/typescript"}
|
||||||
Read the details about TypeScript in Nuxt 3
|
Read the details about TypeScript in Nuxt
|
||||||
::
|
::
|
||||||
|
@ -31,11 +31,11 @@ Universal rendering allows a Nuxt application to provide quick page load times w
|
|||||||
|
|
||||||
Universal rendering is very versatile and can fit almost any use case, and is especially appropriate for any content-oriented websites: **blogs, marketing websites, portfolios, e-commerce sites, and marketplaces.**
|
Universal rendering is very versatile and can fit almost any use case, and is especially appropriate for any content-oriented websites: **blogs, marketing websites, portfolios, e-commerce sites, and marketplaces.**
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
For more examples about writing Vue code without hydration mismatch, see [the Vue docs](https://vuejs.org/guide/scaling-up/ssr.html#hydration-mismatch).
|
For more examples about writing Vue code without hydration mismatch, see [the Vue docs](https://vuejs.org/guide/scaling-up/ssr.html#hydration-mismatch).
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::important
|
||||||
When importing a library that relies on browser APIs and has side effects, make sure the component importing it is only called client-side. Bundlers do not treeshake imports of modules containing side effects.
|
When importing a library that relies on browser APIs and has side effects, make sure the component importing it is only called client-side. Bundlers do not treeshake imports of modules containing side effects.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -64,18 +64,48 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you do use `ssr: false`, you should also place an HTML file in `~/app/spa-loading-template.html` with some HTML you would like to use to render a loading screen that will be rendered until your app is hydrated.
|
If you do use `ssr: false`, you should also place an HTML file in `~/app/spa-loading-template.html` with some HTML you would like to use to render a loading screen that will be rendered until your app is hydrated.
|
||||||
:read-more{title="SPA Loading Template" to="/docs/api/configuration/nuxt-config#spaloadingtemplate"}
|
:read-more{title="SPA Loading Template" to="/docs/api/configuration/nuxt-config#spaloadingtemplate"}
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::tip{to="https://www.youtube.com/watch?v=7Lr0QTP1Ro8" icon="i-logos-youtube-icon" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about **Building a plain SPA with Nuxt!?**.
|
||||||
|
::
|
||||||
|
|
||||||
|
### Deploying a Static Client-Rendered App
|
||||||
|
|
||||||
|
If you deploy your app to [static hosting](/docs/getting-started/deployment#static-hosting) with the `nuxi generate` or `nuxi build --prerender` commands, then by default, Nuxt will render every page as a separate static HTML file.
|
||||||
|
|
||||||
|
If you are using purely client-side rendering, then this might be unnecessary. You might only need a single `index.html` file, plus `200.html` and `404.html` fallbacks, which you can tell your static web host to serve up for all requests.
|
||||||
|
|
||||||
|
In order to achieve this we can change how the routes are prerendered. Just add this to [your hooks](/docs/api/advanced/hooks#nuxt-hooks-build-time) in your `nuxt.config.ts`:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
hooks: {
|
||||||
|
'prerender:routes' ({ routes }) {
|
||||||
|
routes.clear() // Do not generate any routes (except the defaults)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
This will produce three files:
|
||||||
|
|
||||||
|
- `index.html`
|
||||||
|
- `200.html`
|
||||||
|
- `404.html`
|
||||||
|
|
||||||
|
The `200.html` and `404.html` might be useful for the hosting provider you are using.
|
||||||
|
|
||||||
## Hybrid Rendering
|
## Hybrid Rendering
|
||||||
|
|
||||||
Hybrid rendering allows different caching rules per route using **Route Rules** and decides how the server should respond to a new request on a given URL.
|
Hybrid rendering allows different caching rules per route using **Route Rules** and decides how the server should respond to a new request on a given URL.
|
||||||
|
|
||||||
Previously every route/page of a Nuxt application and server must use the same rendering mode, universal or client-side. In various cases, some pages could be generated at build time, while others should be client-side rendered. For example, think of a content website with an admin section. Every content page should be primarily static and generated once, but the admin section requires registration and behaves more like a dynamic application.
|
Previously every route/page of a Nuxt application and server must use the same rendering mode, universal or client-side. In various cases, some pages could be generated at build time, while others should be client-side rendered. For example, think of a content website with an admin section. Every content page should be primarily static and generated once, but the admin section requires registration and behaves more like a dynamic application.
|
||||||
|
|
||||||
Nuxt 3 includes route rules and hybrid rendering support. Using route rules you can define rules for a group of nuxt routes, change rendering mode or assign a cache strategy based on route!
|
Nuxt includes route rules and hybrid rendering support. Using route rules you can define rules for a group of nuxt routes, change rendering mode or assign a cache strategy based on route!
|
||||||
|
|
||||||
Nuxt server will automatically register corresponding middleware and wrap routes with cache handlers using [Nitro caching layer](https://nitro.unjs.io/guide/cache).
|
Nuxt server will automatically register corresponding middleware and wrap routes with cache handlers using [Nitro caching layer](https://nitro.unjs.io/guide/cache).
|
||||||
|
|
||||||
@ -86,7 +116,7 @@ export default defineNuxtConfig({
|
|||||||
'/': { prerender: true },
|
'/': { prerender: true },
|
||||||
// Products page generated on demand, revalidates in background, cached until API response changes
|
// Products page generated on demand, revalidates in background, cached until API response changes
|
||||||
'/products': { swr: true },
|
'/products': { swr: true },
|
||||||
// Product page generated on demand, revalidates in background, cached for 1 hour (3600 seconds)
|
// Product pages generated on demand, revalidates in background, cached for 1 hour (3600 seconds)
|
||||||
'/products/**': { swr: 3600 },
|
'/products/**': { swr: 3600 },
|
||||||
// Blog posts page generated on demand, revalidates in background, cached on CDN for 1 hour (3600 seconds)
|
// Blog posts page generated on demand, revalidates in background, cached on CDN for 1 hour (3600 seconds)
|
||||||
'/blog': { isr: 3600 },
|
'/blog': { isr: 3600 },
|
||||||
@ -106,17 +136,18 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
The different properties you can use are the following:
|
The different properties you can use are the following:
|
||||||
- `redirect: string`{lang=ts} - Define server-side redirects.
|
- `redirect: string`{lang=ts} - Define server-side redirects.
|
||||||
- `ssr: boolean`{lang=ts} - Disables server-side rendering for sections of your app and make them SPA-only with `ssr: false`
|
- `ssr: boolean`{lang=ts} - Disables server-side rendering of the HTML for sections of your app and make them render only in the browser with `ssr: false`
|
||||||
- `cors: boolean`{lang=ts} - Automatically adds cors headers with `cors: true` - you can customize the output by overriding with `headers`
|
- `cors: boolean`{lang=ts} - Automatically adds cors headers with `cors: true` - you can customize the output by overriding with `headers`
|
||||||
- `headers: object`{lang=ts} - Add specific headers to sections of your site - for example, your assets
|
- `headers: object`{lang=ts} - Add specific headers to sections of your site - for example, your assets
|
||||||
- `swr: number|boolean`{lang=ts} - Add cache headers to the server response and cache it on the server or reverse proxy for a configurable TTL (time to live). The `node-server` preset of Nitro is able to cache the full response. When the TTL expired, the cached response will be sent while the page will be regenerated in the background. If true is used, a `stale-while-revalidate` header is added without a MaxAge.
|
- `swr: number | boolean`{lang=ts} - Add cache headers to the server response and cache it on the server or reverse proxy for a configurable TTL (time to live). The `node-server` preset of Nitro is able to cache the full response. When the TTL expired, the cached response will be sent while the page will be regenerated in the background. If true is used, a `stale-while-revalidate` header is added without a MaxAge.
|
||||||
- `isr: number|boolean`{lang=ts} - The behavior is the same as `swr` except that we are able to add the response to the CDN cache on platforms that support this (currently Netlify or Vercel). If `true` is used, the content persists until the next deploy inside the CDN.
|
- `isr: number | boolean`{lang=ts} - The behavior is the same as `swr` except that we are able to add the response to the CDN cache on platforms that support this (currently Netlify or Vercel). If `true` is used, the content persists until the next deploy inside the CDN.
|
||||||
- `prerender:boolean`{lang=ts} - Prerenders routes at build time and includes them in your build as static assets
|
- `prerender: boolean`{lang=ts} - Prerenders routes at build time and includes them in your build as static assets
|
||||||
- `experimentalNoScripts: boolean`{lang=ts} - Disables rendering of Nuxt scripts and JS resource hints for sections of your site.
|
- `experimentalNoScripts: boolean`{lang=ts} - Disables rendering of Nuxt scripts and JS resource hints for sections of your site.
|
||||||
|
- `appMiddleware: string | string[] | Record<string, boolean>`{lang=ts} - Allows you to define middleware that should or should not run for page paths within the Vue app part of your application (that is, not your Nitro routes)
|
||||||
|
|
||||||
Whenever possible, route rules will be automatically applied to the deployment platform's native rules for optimal performances (Netlify and Vercel are currently supported).
|
Whenever possible, route rules will be automatically applied to the deployment platform's native rules for optimal performances (Netlify and Vercel are currently supported).
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::important
|
||||||
Note that Hybrid Rendering is not available when using [`nuxt generate`](/docs/api/commands/generate).
|
Note that Hybrid Rendering is not available when using [`nuxt generate`](/docs/api/commands/generate).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -137,7 +168,7 @@ Note that Hybrid Rendering is not available when using [`nuxt generate`](/docs/a
|
|||||||
|
|
||||||
## Edge-Side Rendering
|
## Edge-Side Rendering
|
||||||
|
|
||||||
Edge-Side Rendering (ESR) is a powerful feature introduced in Nuxt 3 that allows the rendering of your Nuxt application closer to your users via edge servers of a Content Delivery Network (CDN). By leveraging ESR, you can ensure improved performance and reduced latency, thereby providing an enhanced user experience.
|
Edge-Side Rendering (ESR) is a powerful feature introduced in Nuxt that allows the rendering of your Nuxt application closer to your users via edge servers of a Content Delivery Network (CDN). By leveraging ESR, you can ensure improved performance and reduced latency, thereby providing an enhanced user experience.
|
||||||
|
|
||||||
With ESR, the rendering process is pushed to the 'edge' of the network - the CDN's edge servers. Note that ESR is more a deployment target than an actual rendering mode.
|
With ESR, the rendering process is pushed to the 'edge' of the network - the CDN's edge servers. Note that ESR is more a deployment target than an actual rendering mode.
|
||||||
|
|
||||||
@ -172,7 +203,7 @@ You can explore open source examples deployed on some of the platform mentioned
|
|||||||
target: _blank
|
target: _blank
|
||||||
ui.icon.base: text-black dark:text-white
|
ui.icon.base: text-black dark:text-white
|
||||||
---
|
---
|
||||||
An editable website with universal rendering based on CloudFlare KV.
|
An editable website with universal rendering based on Cloudflare KV.
|
||||||
::
|
::
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: Server Engine
|
title: Server Engine
|
||||||
description: 'Nuxt 3 is powered by a new server engine: Nitro.'
|
description: 'Nuxt is powered by a new server engine: Nitro.'
|
||||||
---
|
---
|
||||||
|
|
||||||
While building Nuxt 3, we created a new server engine: [Nitro](https://nitro.unjs.io).
|
While building Nuxt 3, we created a new server engine: [Nitro](https://nitro.unjs.io).
|
||||||
|
|
||||||
It is shipped with many features:
|
It is shipped with many features:
|
||||||
|
|
||||||
- Cross-platform support for Node.js, Browsers, service-workers and more.
|
- Cross-platform support for Node.js, browsers, service workers and more.
|
||||||
- Serverless support out-of-the-box.
|
- Serverless support out-of-the-box.
|
||||||
- API routes support.
|
- API routes support.
|
||||||
- Automatic code-splitting and async-loaded chunks.
|
- Automatic code-splitting and async-loaded chunks.
|
||||||
@ -51,9 +51,9 @@ You can access these types when using [`$fetch()`](/docs/api/utils/dollarfetch)
|
|||||||
|
|
||||||
Nitro produces a standalone server dist that is independent of `node_modules`.
|
Nitro produces a standalone server dist that is independent of `node_modules`.
|
||||||
|
|
||||||
The server in Nuxt 2 is not standalone and requires part of Nuxt core to be involved by running `nuxt start` (with the [`nuxt-start`](https://www.npmjs.com/package/nuxt-start) or [`nuxt`](https://www.npmjs.com/package/nuxt) distributions) or custom programmatic usage, which is fragile and prone to breakage and not suitable for serverless and service-worker environments.
|
The server in Nuxt 2 is not standalone and requires part of Nuxt core to be involved by running `nuxt start` (with the [`nuxt-start`](https://www.npmjs.com/package/nuxt-start) or [`nuxt`](https://www.npmjs.com/package/nuxt) distributions) or custom programmatic usage, which is fragile and prone to breakage and not suitable for serverless and service worker environments.
|
||||||
|
|
||||||
Nuxt 3 generates this dist when running `nuxt build` into a [`.output`](/docs/guide/directory-structure/output) directory.
|
Nuxt generates this dist when running `nuxt build` into a [`.output`](/docs/guide/directory-structure/output) directory.
|
||||||
|
|
||||||
The output contains runtime code to run your Nuxt server in any environment (including experimental browser service workers!) and serve your static files, making it a true hybrid framework for the JAMstack. In addition, Nuxt implements a native storage layer, supporting multi-source drivers and local assets.
|
The output contains runtime code to run your Nuxt server in any environment (including experimental browser service workers!) and serve your static files, making it a true hybrid framework for the JAMstack. In addition, Nuxt implements a native storage layer, supporting multi-source drivers and local assets.
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Nuxt modules are now build-time-only, and the `buildModules` property used in Nuxt 2 is deprecated in favor of `modules`.
|
Nuxt modules are now build-time-only, and the `buildModules` property used in Nuxt 2 is deprecated in favor of `modules`.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: 'ES Modules'
|
title: 'ES Modules'
|
||||||
description: "Nuxt 3 (and Bridge) uses Native ES Modules."
|
description: "Nuxt uses native ES modules."
|
||||||
---
|
---
|
||||||
|
|
||||||
This guide helps explain what ES Modules are and how to make a Nuxt app (or upstream library) compatible with ESM.
|
This guide helps explain what ES Modules are and how to make a Nuxt app (or upstream library) compatible with ESM.
|
||||||
@ -190,7 +190,7 @@ import { default as pkg } from 'cjs-pkg'
|
|||||||
import('cjs-pkg').then(m => m.default || m).then(console.log)
|
import('cjs-pkg').then(m => m.default || m).then(console.log)
|
||||||
```
|
```
|
||||||
|
|
||||||
For handling more complex situations and more safety, we recommend and internally use [mlly](https://github.com/unjs/mlly) in Nuxt 3 that can preserve named exports.
|
For handling more complex situations and more safety, we recommend and internally use [mlly](https://github.com/unjs/mlly) in Nuxt that can preserve named exports.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { interopDefault } from 'mlly'
|
import { interopDefault } from 'mlly'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: 'TypeScript'
|
title: 'TypeScript'
|
||||||
description: "Nuxt 3 is fully typed and provides helpful shortcuts to ensure you have access to accurate type information when you are coding."
|
description: "Nuxt is fully typed and provides helpful shortcuts to ensure you have access to accurate type information when you are coding."
|
||||||
---
|
---
|
||||||
|
|
||||||
## Type-checking
|
## Type-checking
|
||||||
@ -9,16 +9,16 @@ By default, Nuxt doesn't check types when you run [`nuxi dev`](/docs/api/command
|
|||||||
|
|
||||||
To enable type-checking at build or development time, install `vue-tsc` and `typescript` as development dependency:
|
To enable type-checking at build or development time, install `vue-tsc` and `typescript` as development dependency:
|
||||||
|
|
||||||
::code-group
|
::package-managers
|
||||||
|
|
||||||
```bash [yarn]
|
|
||||||
yarn add --dev vue-tsc typescript
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [npm]
|
```bash [npm]
|
||||||
npm install --save-dev vue-tsc typescript
|
npm install --save-dev vue-tsc typescript
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add --dev vue-tsc typescript
|
||||||
|
```
|
||||||
|
|
||||||
```bash [pnpm]
|
```bash [pnpm]
|
||||||
pnpm add -D vue-tsc typescript
|
pnpm add -D vue-tsc typescript
|
||||||
```
|
```
|
||||||
@ -51,7 +51,7 @@ When you run `nuxi dev` or `nuxi build`, Nuxt generates the following files for
|
|||||||
|
|
||||||
### `.nuxt/nuxt.d.ts`
|
### `.nuxt/nuxt.d.ts`
|
||||||
|
|
||||||
This file contains the types of any modules you are using, as well as the key types that Nuxt 3 requires. Your IDE should recognize these types automatically.
|
This file contains the types of any modules you are using, as well as the key types that Nuxt requires. Your IDE should recognize these types automatically.
|
||||||
|
|
||||||
Some of the references in the file are to files that are only generated within your `buildDir` (`.nuxt`) and therefore for full typings, you will need to run `nuxi dev` or `nuxi build`.
|
Some of the references in the file are to files that are only generated within your `buildDir` (`.nuxt`) and therefore for full typings, you will need to run `nuxi dev` or `nuxi build`.
|
||||||
|
|
||||||
@ -61,29 +61,33 @@ This file contains the recommended basic TypeScript configuration for your proje
|
|||||||
|
|
||||||
[Read more about how to extend this configuration](/docs/guide/directory-structure/tsconfig).
|
[Read more about how to extend this configuration](/docs/guide/directory-structure/tsconfig).
|
||||||
|
|
||||||
::callout
|
::tip{icon="i-ph-video" to="https://youtu.be/umLI7SlPygY" target="_blank"}
|
||||||
|
Watch a video from Daniel Roe explaining built-in Nuxt aliases.
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
Nitro also [auto-generates types](/docs/guide/concepts/server-engine#typed-api-routes) for API routes. Plus, Nuxt also generates types for globally available components and [auto-imports from your composables](/docs/guide/directory-structure/composables), plus other core functionality.
|
Nitro also [auto-generates types](/docs/guide/concepts/server-engine#typed-api-routes) for API routes. Plus, Nuxt also generates types for globally available components and [auto-imports from your composables](/docs/guide/directory-structure/composables), plus other core functionality.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Keep in mind that all options extended from `./.nuxt/tsconfig.json` will be overwritten by the options defined in your `tsconfig.json`.
|
Keep in mind that all options extended from `./.nuxt/tsconfig.json` will be overwritten by the options defined in your `tsconfig.json`.
|
||||||
Overwriting options such as `"compilerOptions.paths"` with your own configuration will lead TypeScript to not factor in the module resolutions from `./.nuxt/tsconfig.json`. This can lead to module resolutions such as `#imports` not being recognized.
|
Overwriting options such as `"compilerOptions.paths"` with your own configuration will lead TypeScript to not factor in the module resolutions from `./.nuxt/tsconfig.json`. This can lead to module resolutions such as `#imports` not being recognized.
|
||||||
:br :br
|
:br :br
|
||||||
In case you need to extend options provided by `./.nuxt/tsconfig.json` further, you can use the [`alias` property](/docs/api/nuxt-config#alias) within your `nuxt.config`. `nuxi` will pick them up and extend `./.nuxt/tsconfig.json` accordingly.
|
In case you need to extend options provided by `./.nuxt/tsconfig.json` further, you can use the [`alias` property](/docs/api/nuxt-config#alias) within your `nuxt.config`. `nuxi` will pick them up and extend `./.nuxt/tsconfig.json` accordingly.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Stricter Checks
|
## Strict Checks
|
||||||
|
|
||||||
TypeScript comes with certain checks to give you more safety and analysis of your program.
|
TypeScript comes with certain checks to give you more safety and analysis of your program.
|
||||||
|
|
||||||
Once you’ve converted your codebase to TypeScript and felt familiar with it, you can start enabling these checks for greater safety ([read more](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks)).
|
[Strict checks](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks) are enabled by default in Nuxt to give you greater type safety.
|
||||||
|
|
||||||
In order to enable strict type checking, you have to update `nuxt.config`:
|
If you are currently converting your codebase to TypeScript, you may want to temporarily disable strict checks by setting `strict` to `false` in your `nuxt.config`:
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
```ts twoslash [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
typescript: {
|
typescript: {
|
||||||
strict: true
|
strict: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
@ -5,76 +5,20 @@ description: "Nuxt supports ESLint out of the box"
|
|||||||
|
|
||||||
## ESLint
|
## ESLint
|
||||||
|
|
||||||
The recommended approach for Nuxt is to enable ESLint support using [`@nuxt/eslint-config`](https://github.com/nuxt/eslint-config).
|
The recommended approach for Nuxt is to enable ESLint support using the [`@nuxt/eslint`](https://eslint.nuxt.com/packages/module) module, that will setup project-aware ESLint configuration for you.
|
||||||
|
|
||||||
At the moment, this configuration will not format your files; you can set up Prettier or another tool to do so.
|
:::callout{icon="i-ph-lightbulb"}
|
||||||
|
The module is designed for the [new ESLint flat config format](https://eslint.org/docs/latest/use/configure/configuration-files-new) with is the [default format since ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/).
|
||||||
|
|
||||||
::alert{type=info}
|
If you are using the legacy `.eslintrc` config, you will need to [configure manually with `@nuxt/eslint-config`](https://eslint.nuxt.com/packages/config#legacy-config-format). We highly recommend you to migrate over the flat config to be future-proof.
|
||||||
We're currently working to refactor the Nuxt ESLint configuration. Subscribe to the [Nuxt ESLint roadmap](https://github.com/nuxt/eslint-config/issues/303) to follow updates.
|
:::
|
||||||
::
|
|
||||||
|
|
||||||
### Install Dependencies
|
## Quick Setup
|
||||||
|
|
||||||
Install both ESLint and the Nuxt configuration as development dependencies.
|
```bash
|
||||||
|
npx nuxi module add eslint
|
||||||
::code-group
|
|
||||||
|
|
||||||
```bash [yarn]
|
|
||||||
yarn add --dev eslint @nuxt/eslint-config
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash [npm]
|
Start your Nuxt app, a `eslint.config.mjs` file will be generated under your project root. You can customize it as needed.
|
||||||
npm install --save-dev eslint @nuxt/eslint-config
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [pnpm]
|
You can learn more about the module and customizations in [Nuxt ESLint's documentation](https://eslint.nuxt.com/packages/module).
|
||||||
pnpm add -D eslint @nuxt/eslint-config
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [bun]
|
|
||||||
bun add -D eslint @nuxt/eslint-config
|
|
||||||
```
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
Add `.eslintrc.cjs` to the root folder of your Nuxt app.
|
|
||||||
|
|
||||||
```js
|
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
extends: ['@nuxt/eslint-config'],
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Modify package.json
|
|
||||||
|
|
||||||
Add the below to lint commands to your `package.json` script section:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"scripts": {
|
|
||||||
...
|
|
||||||
"lint": "eslint .",
|
|
||||||
"lint:fix": "eslint . --fix",
|
|
||||||
...
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the `lint` command to check if the code style is correct or run `lint:fix` to automatically fix issues.
|
|
||||||
|
|
||||||
### Configuring VS Code
|
|
||||||
|
|
||||||
Install the [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).
|
|
||||||
|
|
||||||
In VS Code press `ctrl+shift+p` (`cmd+shift+p` on Mac) to open the command prompt, find `Open Workspace Settings (JSON)`, add the below lines to the JSON and save:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll.eslint": "explicit"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You're good to go! On save, your files will be linted and auto-fixed.
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
title: Key Concepts
|
title: Key Concepts
|
||||||
titleTemplate: '%s · Nuxt Concepts'
|
titleTemplate: '%s · Nuxt Concepts'
|
||||||
icon: i-ph-medal-duotone
|
icon: i-ph-medal
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
title: ".nuxt"
|
title: ".nuxt"
|
||||||
description: "Nuxt uses the .nuxt/ directory in development to generate your Vue application."
|
description: "Nuxt uses the .nuxt/ directory in development to generate your Vue application."
|
||||||
head.title: ".nuxt/"
|
head.title: ".nuxt/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::important
|
||||||
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the dev build output to your repository.
|
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the dev build output to your repository.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -15,6 +15,6 @@ Nuxt also provides a Virtual File System (VFS) for modules to add templates to t
|
|||||||
|
|
||||||
You can explore the generated files by opening the [Nuxt DevTools](https://devtools.nuxt.com) in development mode and navigating to the **Virtual Files** tab.
|
You can explore the generated files by opening the [Nuxt DevTools](https://devtools.nuxt.com) in development mode and navigating to the **Virtual Files** tab.
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::warning
|
||||||
You should not touch any files inside since the whole directory will be re-created when running [`nuxt dev`](/docs/api/commands/dev).
|
You should not touch any files inside since the whole directory will be re-created when running [`nuxt dev`](/docs/api/commands/dev).
|
||||||
::
|
::
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
title: ".output"
|
title: ".output"
|
||||||
description: "Nuxt creates the .output/ directory when building your application for production."
|
description: "Nuxt creates the .output/ directory when building your application for production."
|
||||||
head.title: ".output/"
|
head.title: ".output/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::important
|
||||||
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the build output to your repository.
|
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the build output to your repository.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -13,6 +13,6 @@ Use this directory to deploy your Nuxt application to production.
|
|||||||
|
|
||||||
:read-more{to="/docs/getting-started/deployment"}
|
:read-more{to="/docs/getting-started/deployment"}
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::warning
|
||||||
You should not touch any files inside since the whole directory will be re-created when running [`nuxt build`](/docs/api/commands/build).
|
You should not touch any files inside since the whole directory will be re-created when running [`nuxt build`](/docs/api/commands/build).
|
||||||
::
|
::
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "assets"
|
title: "assets"
|
||||||
description: "The assets/ directory is used to add all the website's assets that the build tool will process."
|
description: "The assets/ directory is used to add all the website's assets that the build tool will process."
|
||||||
head.title: "assets/"
|
head.title: "assets/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
The directory usually contains the following types of files:
|
The directory usually contains the following types of files:
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
title: "components"
|
title: "components"
|
||||||
head.title: "components/"
|
head.title: "components/"
|
||||||
description: "The components/ directory is where you put all your Vue components."
|
description: "The components/ directory is where you put all your Vue components."
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt automatically imports any components in this directory (along with components that are registered by any modules you may be using).
|
Nuxt automatically imports any components in this directory (along with components that are registered by any modules you may be using).
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| components/
|
-| components/
|
||||||
--| AppHeader.vue
|
---| AppHeader.vue
|
||||||
--| AppFooter.vue
|
---| AppFooter.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```html [app.vue]
|
```html [app.vue]
|
||||||
@ -28,10 +28,10 @@ Nuxt automatically imports any components in this directory (along with componen
|
|||||||
If you have a component in nested directories such as:
|
If you have a component in nested directories such as:
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| components/
|
-| components/
|
||||||
--| base/
|
---| base/
|
||||||
----| foo/
|
-----| foo/
|
||||||
------| Button.vue
|
-------| Button.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
... then the component's name will be based on its own path directory and filename, with duplicate segments being removed. Therefore, the component's name will be:
|
... then the component's name will be based on its own path directory and filename, with duplicate segments being removed. Therefore, the component's name will be:
|
||||||
@ -40,7 +40,7 @@ If you have a component in nested directories such as:
|
|||||||
<BaseFooButton />
|
<BaseFooButton />
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
For clarity, we recommend that the component's filename matches its name. So, in the example above, you could rename `Button.vue` to be `BaseFooButton.vue`.
|
For clarity, we recommend that the component's filename matches its name. So, in the example above, you could rename `Button.vue` to be `BaseFooButton.vue`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -78,10 +78,14 @@ const MyButton = resolveComponent('MyButton')
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
If you are using `resolveComponent` to handle dynamic components, make sure not to insert anything but the name of the component, which must be a string and not a variable.
|
If you are using `resolveComponent` to handle dynamic components, make sure not to insert anything but the name of the component, which must be a string and not a variable.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=4kq8E5IUM2U" target="\_blank"}
|
||||||
|
Watch Daniel Roe's short video about `resolveComponent`.
|
||||||
|
::
|
||||||
|
|
||||||
Alternatively, though not recommended, you can register all your components globally, which will create async chunks for all your components and make them available throughout your application.
|
Alternatively, though not recommended, you can register all your components globally, which will create async chunks for all your components and make them available throughout your application.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
@ -95,7 +99,7 @@ Alternatively, though not recommended, you can register all your components glob
|
|||||||
|
|
||||||
You can also selectively register some components globally by placing them in a `~/components/global` directory, or by using a `.global.vue` suffix in the filename. As noted above, each global component is rendered in a separate chunk, so be careful not to overuse this feature.
|
You can also selectively register some components globally by placing them in a `~/components/global` directory, or by using a `.global.vue` suffix in the filename. As noted above, each global component is rendered in a separate chunk, so be careful not to overuse this feature.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
The `global` option can also be set per component directory.
|
The `global` option can also be set per component directory.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -166,6 +170,10 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::note
|
||||||
|
Any nested directories need to be added first as they are scanned in order.
|
||||||
|
::
|
||||||
|
|
||||||
## npm Packages
|
## npm Packages
|
||||||
|
|
||||||
If you want to auto-import components from an npm package, you can use [`addComponent`](/docs/api/kit/components#addcomponent) in a [local module](/docs/guide/directory-structure/modules) to register them.
|
If you want to auto-import components from an npm package, you can use [`addComponent`](/docs/api/kit/components#addcomponent) in a [local module](/docs/guide/directory-structure/modules) to register them.
|
||||||
@ -198,10 +206,6 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
|
||||||
Any nested directories need to be added first as they are scanned in order.
|
|
||||||
::
|
|
||||||
|
|
||||||
## Component Extensions
|
## Component Extensions
|
||||||
|
|
||||||
By default, any file with an extension specified in the [extensions key of `nuxt.config.ts`](/docs/api/nuxt-config#extensions) is treated as a component.
|
By default, any file with an extension specified in the [extensions key of `nuxt.config.ts`](/docs/api/nuxt-config#extensions) is treated as a component.
|
||||||
@ -236,26 +240,30 @@ If a component is meant to be rendered only client-side, you can add the `.clien
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
This feature only works with Nuxt auto-imports and `#components` imports. Explicitly importing these components from their real paths does not convert them into client-only components.
|
This feature only works with Nuxt auto-imports and `#components` imports. Explicitly importing these components from their real paths does not convert them into client-only components.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
`.client` components are rendered only after being mounted. To access the rendered template using `onMounted()`, add `await nextTick()` in the callback of the `onMounted()` hook.
|
`.client` components are rendered only after being mounted. To access the rendered template using `onMounted()`, add `await nextTick()` in the callback of the `onMounted()` hook.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::read-more{to="/docs/api/components/client-only"}
|
||||||
|
You can also achieve a similar result with the `<ClientOnly>` component.
|
||||||
|
::
|
||||||
|
|
||||||
## Server Components
|
## Server Components
|
||||||
|
|
||||||
Server components allow server-rendering individual components within your client-side apps. It's possible to use server components within Nuxt, even if you are generating a static site. That makes it possible to build complex sites that mix dynamic components, server-rendered HTML and even static chunks of markup.
|
Server components allow server-rendering individual components within your client-side apps. It's possible to use server components within Nuxt, even if you are generating a static site. That makes it possible to build complex sites that mix dynamic components, server-rendered HTML and even static chunks of markup.
|
||||||
|
|
||||||
Server components can either be used on their own or paired with a [client component](#paired-with-a-client-component).
|
Server components can either be used on their own or paired with a [client component](#paired-with-a-client-component).
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=u1yyXe86xJM" target="_blank"}
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=u1yyXe86xJM" target="_blank"}
|
||||||
Watch Learn Vue video about Nuxt Server Components.
|
Watch Learn Vue video about Nuxt Server Components.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-article-duotone" to="https://roe.dev/blog/nuxt-server-components" target="_blank"}
|
::tip{icon="i-ph-article" to="https://roe.dev/blog/nuxt-server-components" target="_blank"}
|
||||||
Read Daniel Roe's guide to Nuxt server components
|
Read Daniel Roe's guide to Nuxt Server Components.
|
||||||
::
|
::
|
||||||
|
|
||||||
### Standalone server components
|
### Standalone server components
|
||||||
@ -277,8 +285,8 @@ export default defineNuxtConfig({
|
|||||||
Now you can register server-only components with the `.server` suffix and use them anywhere in your application automatically.
|
Now you can register server-only components with the `.server` suffix and use them anywhere in your application automatically.
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| components/
|
-| components/
|
||||||
--| HighlightedMarkdown.server.vue
|
---| HighlightedMarkdown.server.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
```vue [pages/example.vue]
|
||||||
@ -295,6 +303,18 @@ Now you can register server-only components with the `.server` suffix and use th
|
|||||||
|
|
||||||
Server-only components use [`<NuxtIsland>`](/docs/api/components/nuxt-island) under the hood, meaning that `lazy` prop and `#fallback` slot are both passed down to it.
|
Server-only components use [`<NuxtIsland>`](/docs/api/components/nuxt-island) under the hood, meaning that `lazy` prop and `#fallback` slot are both passed down to it.
|
||||||
|
|
||||||
|
::alert{type=warning}
|
||||||
|
Server components (and islands) must have a single root element. (HTML comments are considered elements as well.)
|
||||||
|
::
|
||||||
|
|
||||||
|
::alert{type=warning}
|
||||||
|
Be careful when nesting islands within other islands as each island adds some extra overhead.
|
||||||
|
::
|
||||||
|
|
||||||
|
::alert{type=warning}
|
||||||
|
Most features for server-only components and island components, such as slots and client components, are only available for single file components.
|
||||||
|
::
|
||||||
|
|
||||||
#### Client components within server components
|
#### Client components within server components
|
||||||
|
|
||||||
::alert{type=info}
|
::alert{type=info}
|
||||||
@ -314,7 +334,7 @@ You can partially hydrate a component by setting a `nuxt-client` attribute on th
|
|||||||
```
|
```
|
||||||
|
|
||||||
::alert{type=info}
|
::alert{type=info}
|
||||||
This only works within a server component. Slots for client components are not available yet.
|
This only works within a server component. Slots for client components are working only with `experimental.componentIsland.selectiveClient` set to `'deep'` and since they are rendered server-side, they are not interactive once client-side.
|
||||||
::
|
::
|
||||||
|
|
||||||
#### Server Component Context
|
#### Server Component Context
|
||||||
@ -330,7 +350,7 @@ This means:
|
|||||||
|
|
||||||
Within an island component, you can access its island context through `nuxtApp.ssrContext.islandContext`. Note that while island components are still marked as experimental, the format of this context may change.
|
Within an island component, you can access its island context through `nuxtApp.ssrContext.islandContext`. Note that while island components are still marked as experimental, the format of this context may change.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Slots can be interactive and are wrapped within a `<div>` with `display: contents;`
|
Slots can be interactive and are wrapped within a `<div>` with `display: contents;`
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -339,9 +359,9 @@ Slots can be interactive and are wrapped within a `<div>` with `display: content
|
|||||||
In this case, the `.server` + `.client` components are two 'halves' of a component and can be used in advanced use cases for separate implementations of a component on server and client side.
|
In this case, the `.server` + `.client` components are two 'halves' of a component and can be used in advanced use cases for separate implementations of a component on server and client side.
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| components/
|
-| components/
|
||||||
--| Comments.client.vue
|
---| Comments.client.vue
|
||||||
--| Comments.server.vue
|
---| Comments.server.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
```vue [pages/example.vue]
|
||||||
@ -353,89 +373,12 @@ In this case, the `.server` + `.client` components are two 'halves' of a compone
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
## `<ClientOnly>` Component
|
## Built-In Nuxt Components
|
||||||
|
|
||||||
Nuxt provides the [`<ClientOnly>`](/docs/api/components/client-only) component for purposely rendering a component only on client side.
|
There are a number of components that Nuxt provides, including `<ClientOnly>` and `<DevOnly>`. You can read more about them in the API documentation.
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
::read-more{to="/docs/api"}
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<Sidebar />
|
|
||||||
<ClientOnly>
|
|
||||||
<!-- this component will only be rendered on client-side -->
|
|
||||||
<Comments />
|
|
||||||
</ClientOnly>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a slot as fallback until `<ClientOnly>` is mounted on client side.
|
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<Sidebar />
|
|
||||||
<!-- This renders the "span" element on the server side -->
|
|
||||||
<ClientOnly fallbackTag="span">
|
|
||||||
<!-- this component will only be rendered on client side -->
|
|
||||||
<Comments />
|
|
||||||
<template #fallback>
|
|
||||||
<!-- this will be rendered on server side -->
|
|
||||||
<p>Loading comments...</p>
|
|
||||||
</template>
|
|
||||||
</ClientOnly>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- TODO: Add back after passing treeshakeClientOnly experiment -->
|
|
||||||
<!--
|
|
||||||
::callout
|
|
||||||
Make sure not to _nest_ `<ClientOnly>` components or other client-only components. Nuxt performs an optimization to remove the contents of these components from the server-side render, which can break in this case.
|
|
||||||
::
|
::
|
||||||
-->
|
|
||||||
|
|
||||||
## `<DevOnly>` Component
|
|
||||||
|
|
||||||
Nuxt provides the `<DevOnly>` component to render a component only during development.
|
|
||||||
|
|
||||||
The content will not be included in production builds and tree-shaken.
|
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<Sidebar />
|
|
||||||
<DevOnly>
|
|
||||||
<!-- this component will only be rendered during development -->
|
|
||||||
<LazyDebugBar />
|
|
||||||
|
|
||||||
<!-- if you ever require to have a replacement during production -->
|
|
||||||
<!-- be sure to test these using `nuxt preview` -->
|
|
||||||
<template #fallback>
|
|
||||||
<div><!-- empty div for flex.justify-between --></div>
|
|
||||||
</template>
|
|
||||||
</DevOnly>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
## `<NuxtClientFallback>` Component
|
|
||||||
|
|
||||||
Nuxt provides the `<NuxtClientFallback>` component to render its content on the client if any of its children trigger an error in SSR.
|
|
||||||
You can specify a `fallbackTag` to make it render a specific tag if it fails to render on the server.
|
|
||||||
|
|
||||||
```vue [pages/example.vue]
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<Sidebar />
|
|
||||||
<!-- this component will be rendered on client-side -->
|
|
||||||
<NuxtClientFallback fallback-tag="span">
|
|
||||||
<Comments />
|
|
||||||
<BrokeInSSR />
|
|
||||||
</NuxtClientFallback>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Library Authors
|
## Library Authors
|
||||||
|
|
||||||
@ -446,15 +389,15 @@ You can use the `components:dirs` hook to extend the directory list without requ
|
|||||||
Imagine a directory structure like this:
|
Imagine a directory structure like this:
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| node_modules/
|
-| node_modules/
|
||||||
---| awesome-ui/
|
---| awesome-ui/
|
||||||
------| components/
|
-----| components/
|
||||||
---------| Alert.vue
|
-------| Alert.vue
|
||||||
---------| Button.vue
|
-------| Button.vue
|
||||||
------| nuxt.js
|
-----| nuxt.js
|
||||||
| pages/
|
-| pages/
|
||||||
---| index.vue
|
---| index.vue
|
||||||
| nuxt.config.js
|
-| nuxt.config.js
|
||||||
```
|
```
|
||||||
|
|
||||||
Then in `awesome-ui/nuxt.js` you can use the `components:dirs` hook:
|
Then in `awesome-ui/nuxt.js` you can use the `components:dirs` hook:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: 'composables'
|
title: 'composables'
|
||||||
head.title: 'composables/'
|
head.title: 'composables/'
|
||||||
description: Use the composables/ directory to auto-import your Vue composables into your application.
|
description: Use the composables/ directory to auto-import your Vue composables into your application.
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -52,7 +52,7 @@ Under the hood, Nuxt auto generates the file `.nuxt/imports.d.ts` to declare the
|
|||||||
|
|
||||||
Be aware that you have to run [`nuxi prepare`](/docs/api/commands/prepare), [`nuxi dev`](/docs/api/commands/dev) or [`nuxi build`](/docs/api/commands/build) in order to let Nuxt generate the types.
|
Be aware that you have to run [`nuxi prepare`](/docs/api/commands/prepare), [`nuxi dev`](/docs/api/commands/dev) or [`nuxi build`](/docs/api/commands/build) in order to let Nuxt generate the types.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you create a composable without having the dev server running, TypeScript will throw an error, such as `Cannot find name 'useBar'.`
|
If you create a composable without having the dev server running, TypeScript will throw an error, such as `Cannot find name 'useBar'.`
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -85,11 +85,11 @@ export const useHello = () => {
|
|||||||
Nuxt only scans files at the top level of the [`composables/` directory](/docs/guide/directory-structure/composables), e.g.:
|
Nuxt only scans files at the top level of the [`composables/` directory](/docs/guide/directory-structure/composables), e.g.:
|
||||||
|
|
||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
| composables/
|
-| composables/
|
||||||
---| index.ts // scanned
|
---| index.ts // scanned
|
||||||
---| useFoo.ts // scanned
|
---| useFoo.ts // scanned
|
||||||
-----| nested/
|
---| nested/
|
||||||
-------| utils.ts // not scanned
|
-----| utils.ts // not scanned
|
||||||
```
|
```
|
||||||
|
|
||||||
Only `composables/index.ts` and `composables/useFoo.ts` would be searched for imports.
|
Only `composables/index.ts` and `composables/useFoo.ts` would be searched for imports.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: 'content'
|
title: 'content'
|
||||||
head.title: 'content/'
|
head.title: 'content/'
|
||||||
description: Use the content/ directory to create a file-based CMS for your application.
|
description: Use the content/ directory to create a file-based CMS for your application.
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
[Nuxt Content](https://content.nuxt.com) reads the [`content/` directory](/docs/guide/directory-structure/content) in your project and parses `.md`, `.yml`, `.csv` and `.json` files to create a file-based CMS for your application.
|
[Nuxt Content](https://content.nuxt.com) reads the [`content/` directory](/docs/guide/directory-structure/content) in your project and parses `.md`, `.yml`, `.csv` and `.json` files to create a file-based CMS for your application.
|
||||||
@ -49,6 +49,6 @@ To render content pages, add a [catch-all route](/docs/guide/directory-structure
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
::callout
|
::tip{ icon="i-ph-book" }
|
||||||
Head over to <https://content.nuxt.com> to learn more about the Content module features, such as how to build queries and use Vue components in your Markdown files with the MDC syntax.
|
Head over to <https://content.nuxt.com> to learn more about the Content module features, such as how to build queries and use Vue components in your Markdown files with the MDC syntax.
|
||||||
::
|
::
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
title: "layouts"
|
title: "layouts"
|
||||||
head.title: "layouts/"
|
head.title: "layouts/"
|
||||||
description: "Nuxt provides a layouts framework to extract common UI patterns into reusable layouts."
|
description: "Nuxt provides a layouts framework to extract common UI patterns into reusable layouts."
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout{icon="i-ph-rocket-launch-duotone"}
|
::tip{icon="i-ph-rocket-launch" color="gray" }
|
||||||
For best performance, components placed in this directory will be automatically loaded via asynchronous import when used.
|
For best performance, components placed in this directory will be automatically loaded via asynchronous import when used.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -25,19 +25,19 @@ To use a layout:
|
|||||||
- Set a `layout` property in your page with [definePageMeta](/docs/api/utils/define-page-meta).
|
- Set a `layout` property in your page with [definePageMeta](/docs/api/utils/define-page-meta).
|
||||||
- Set the `name` prop of `<NuxtLayout>`.
|
- Set the `name` prop of `<NuxtLayout>`.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout`.
|
The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout`.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
If no layout is specified, `layouts/default.vue` will be used.
|
If no layout is specified, `layouts/default.vue` will be used.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-ph-lightbulb-duotone"}
|
::important
|
||||||
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/guide/directory-structure/app) instead.
|
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/guide/directory-structure/app) instead.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Unlike other components, your layouts must have a single root element to allow Nuxt to apply transitions between layout changes - and this root element cannot be a `<slot />`.
|
Unlike other components, your layouts must have a single root element to allow Nuxt to apply transitions between layout changes - and this root element cannot be a `<slot />`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -175,6 +175,6 @@ definePageMeta({
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or [disable layout/page transitions](/docs/getting-started/transitions#disable-transitions)).
|
If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or [disable layout/page transitions](/docs/getting-started/transitions#disable-transitions)).
|
||||||
::
|
::
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "middleware"
|
title: "middleware"
|
||||||
description: "Nuxt provides middleware to run code before navigating to a particular route."
|
description: "Nuxt provides middleware to run code before navigating to a particular route."
|
||||||
head.title: "middleware/"
|
head.title: "middleware/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt provides a customizable **route middleware** framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
|
Nuxt provides a customizable **route middleware** framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
|
||||||
@ -15,11 +15,11 @@ There are three kinds of route middleware:
|
|||||||
|
|
||||||
The first two kinds of route middleware can be defined in [`definePageMeta`](/docs/api/utils/define-page-meta).
|
The first two kinds of route middleware can be defined in [`definePageMeta`](/docs/api/utils/define-page-meta).
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Name of middleware are normalized to kebab-case: `myMiddleware` becomes `my-middleware`.
|
Name of middleware are normalized to kebab-case: `myMiddleware` becomes `my-middleware`.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Route middleware run within the Vue part of your Nuxt app. Despite the similar name, they are completely different from [server middleware](/docs/guide/directory-structure/server#server-middleware), which are run in the Nitro server part of your app.
|
Route middleware run within the Vue part of your Nuxt app. Despite the similar name, they are completely different from [server middleware](/docs/guide/directory-structure/server#server-middleware), which are run in the Nitro server part of your app.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ Possible return values are:
|
|||||||
:read-more{to="/docs/api/utils/navigate-to"}
|
:read-more{to="/docs/api/utils/navigate-to"}
|
||||||
:read-more{to="/docs/api/utils/abort-navigation"}
|
:read-more{to="/docs/api/utils/abort-navigation"}
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
We recommend using the helper functions above for performing redirects or stopping navigation. Other possible return values described in [the vue-router docs](https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards) may work but there may be breaking changes in future.
|
We recommend using the helper functions above for performing redirects or stopping navigation. Other possible return values described in [the vue-router docs](https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards) may work but there may be breaking changes in future.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -72,11 +72,11 @@ Middleware runs in the following order:
|
|||||||
|
|
||||||
For example, assuming you have the following middleware and component:
|
For example, assuming you have the following middleware and component:
|
||||||
|
|
||||||
```text [middleware/ directory]
|
```bash [middleware/ directory]
|
||||||
middleware/
|
-| middleware/
|
||||||
--| analytics.global.ts
|
---| analytics.global.ts
|
||||||
--| setup.global.ts
|
---| setup.global.ts
|
||||||
--| auth.ts
|
---| auth.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
```vue twoslash [pages/profile.vue]
|
```vue twoslash [pages/profile.vue]
|
||||||
@ -105,14 +105,14 @@ By default, global middleware is executed alphabetically based on the filename.
|
|||||||
|
|
||||||
However, there may be times you want to define a specific order. For example, in the last scenario, `setup.global.ts` may need to run before `analytics.global.ts`. In that case, we recommend prefixing global middleware with 'alphabetical' numbering.
|
However, there may be times you want to define a specific order. For example, in the last scenario, `setup.global.ts` may need to run before `analytics.global.ts`. In that case, we recommend prefixing global middleware with 'alphabetical' numbering.
|
||||||
|
|
||||||
```text [Directory structure]
|
```bash [Directory structure]
|
||||||
middleware/
|
-| middleware/
|
||||||
--| 01.setup.global.ts
|
---| 01.setup.global.ts
|
||||||
--| 02.analytics.global.ts
|
---| 02.analytics.global.ts
|
||||||
--| auth.ts
|
---| auth.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.new.global.ts` would come before `2.new.global.ts`. This is why the example prefixes single digit numbers with `0`.
|
In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.new.global.ts` would come before `2.new.global.ts`. This is why the example prefixes single digit numbers with `0`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -125,15 +125,19 @@ However, if you want to avoid this behaviour you can do so:
|
|||||||
```ts twoslash [middleware/example.ts]
|
```ts twoslash [middleware/example.ts]
|
||||||
export default defineNuxtRouteMiddleware(to => {
|
export default defineNuxtRouteMiddleware(to => {
|
||||||
// skip middleware on server
|
// skip middleware on server
|
||||||
if (process.server) return
|
if (import.meta.server) return
|
||||||
// skip middleware on client side entirely
|
// skip middleware on client side entirely
|
||||||
if (process.client) return
|
if (import.meta.client) return
|
||||||
// or only skip middleware on initial client load
|
// or only skip middleware on initial client load
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
if (process.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
|
if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::note
|
||||||
|
Rendering an error page is an entirely separate page load, meaning any registered middleware will run again. You can use [`useError`](/docs/getting-started/error-handling#useerror) in middleware to check if an error is being handled.
|
||||||
|
::
|
||||||
|
|
||||||
## Adding Middleware Dynamically
|
## Adding Middleware Dynamically
|
||||||
|
|
||||||
It is possible to add global or named route middleware manually using the [`addRouteMiddleware()`](/docs/api/utils/add-route-middleware) helper function, such as from within a plugin.
|
It is possible to add global or named route middleware manually using the [`addRouteMiddleware()`](/docs/api/utils/add-route-middleware) helper function, such as from within a plugin.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: 'modules'
|
title: 'modules'
|
||||||
head.title: 'modules/'
|
head.title: 'modules/'
|
||||||
description: Use the modules/ directory to automatically register local modules within your application.
|
description: Use the modules/ directory to automatically register local modules within your application.
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
It is a good place to place any local modules you develop while building your application.
|
It is a good place to place any local modules you develop while building your application.
|
||||||
@ -46,7 +46,11 @@ export default defineEventHandler(() => {
|
|||||||
|
|
||||||
When starting Nuxt, the `hello` module will be registered and the `/api/hello` route will be available.
|
When starting Nuxt, the `hello` module will be registered and the `/api/hello` route will be available.
|
||||||
|
|
||||||
Local modules are registered in alphabetical order. You can change the order by adding a number to the front of each directory name:
|
Modules are executed in the following sequence:
|
||||||
|
- First, the modules defined in [`nuxt.config.ts`](/docs/api/nuxt-config#modules-1) are loaded.
|
||||||
|
- Then, modules found in the `modules/` directory are executed, and they load in alphabetical order.
|
||||||
|
|
||||||
|
You can change the order of local module by adding a number to the front of each directory name:
|
||||||
|
|
||||||
```bash [Directory structure]
|
```bash [Directory structure]
|
||||||
modules/
|
modules/
|
||||||
@ -56,3 +60,7 @@ modules/
|
|||||||
```
|
```
|
||||||
|
|
||||||
:read-more{to="/docs/guide/going-further/modules"}
|
:read-more{to="/docs/guide/going-further/modules"}
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/creating-your-first-module-from-scratch?friend=nuxt" target="_blank"}
|
||||||
|
Watch Vue School video about Nuxt private modules.
|
||||||
|
::
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
title: "node_modules"
|
title: "node_modules"
|
||||||
description: "The package manager stores the dependencies of your project in the node_modules/ directory."
|
description: "The package manager stores the dependencies of your project in the node_modules/ directory."
|
||||||
head.title: "node_modules/"
|
head.title: "node_modules/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
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 this directory to store the dependencies of your project.
|
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 this directory to store the dependencies of your project.
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the dependencies to your repository.
|
This directory should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing the dependencies to your repository.
|
||||||
::
|
::
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
title: "pages"
|
title: "pages"
|
||||||
description: "Nuxt provides file-based routing to create routes within your web application."
|
description: "Nuxt provides file-based routing to create routes within your web application."
|
||||||
head.title: "pages/"
|
head.title: "pages/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
To reduce your application's bundle size, this directory is **optional**, meaning that [`vue-router`](https://router.vuejs.org) won't be included if you only use [`app.vue`](/docs/guide/directory-structure/app). To force the pages system, set `pages: true` in `nuxt.config` or have a [`app/router.options.ts`](/docs/guide/directory-structure/pages#router-options).
|
To reduce your application's bundle size, this directory is **optional**, meaning that [`vue-router`](https://router.vuejs.org) won't be included if you only use [`app.vue`](/docs/guide/directory-structure/app). To force the pages system, set `pages: true` in `nuxt.config` or have a [`app/router.options.ts`](/docs/guide/recipes/custom-routing#using-approuteroptions).
|
||||||
::
|
::
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -57,7 +57,7 @@ If you are using [`app.vue`](/docs/guide/directory-structure/app), make sure to
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
Pages **must have a single root element** to allow [route transitions](/docs/getting-started/transitions) between pages, HTML comments are considered elements as well.
|
Pages **must have a single root element** to allow [route transitions](/docs/getting-started/transitions) between pages. HTML comments are considered elements as well.
|
||||||
|
|
||||||
This means that when the route is server-rendered, or statically generated, you will be able to see its contents correctly, but when you navigate towards that route during client-side navigation the transition between routes will fail and you'll see that the route will not be rendered.
|
This means that when the route is server-rendered, or statically generated, you will be able to see its contents correctly, but when you navigate towards that route during client-side navigation the transition between routes will fail and you'll see that the route will not be rendered.
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ if (route.params.group === 'admins' && !route.params.id) {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Named parent routes will take priority over nested dynamic routes. For the `/foo/hello` route, `~/pages/foo.vue` will take priority over `~/pages/foo/[slug].vue`. :br Use `~/pages/foo/index.vue` and `~/pages/foo/[slug].vue` to match `/foo` and `/foo/hello` with different pages,.
|
Named parent routes will take priority over nested dynamic routes. For the `/foo/hello` route, `~/pages/foo.vue` will take priority over `~/pages/foo/[slug].vue`. :br Use `~/pages/foo/index.vue` and `~/pages/foo/[slug].vue` to match `/foo` and `/foo/hello` with different pages,.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ Example:
|
|||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
-| pages/
|
-| pages/
|
||||||
---| parent/
|
---| parent/
|
||||||
------| child.vue
|
-----| child.vue
|
||||||
---| parent.vue
|
---| parent.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -193,6 +193,14 @@ To display the `child.vue` component, you have to insert the `<NuxtPage>` compon
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```vue {}[pages/parent/child.vue]
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps(['foobar'])
|
||||||
|
|
||||||
|
console.log(props.foobar)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
### Child Route Keys
|
### Child Route Keys
|
||||||
|
|
||||||
If you want more control over when the `<NuxtPage>` component is re-rendered (for example, for transitions), you can either pass a string or function via the `pageKey` prop, or you can define a `key` value via `definePageMeta`:
|
If you want more control over when the `<NuxtPage>` component is re-rendered (for example, for transitions), you can either pass a string or function via the `pageKey` prop, or you can define a `key` value via `definePageMeta`:
|
||||||
@ -208,7 +216,7 @@ If you want more control over when the `<NuxtPage>` component is re-rendered (fo
|
|||||||
|
|
||||||
Or alternatively:
|
Or alternatively:
|
||||||
|
|
||||||
```vue twoslash {}[pages/child.vue]
|
```vue twoslash {}[pages/parent/child.vue]
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
key: route => route.fullPath
|
key: route => route.fullPath
|
||||||
@ -218,6 +226,22 @@ definePageMeta({
|
|||||||
|
|
||||||
:link-example{to="/docs/examples/routing/pages"}
|
:link-example{to="/docs/examples/routing/pages"}
|
||||||
|
|
||||||
|
## Route Groups
|
||||||
|
|
||||||
|
In some cases, you may want to group a set of routes together in a way which doesn't affect file-based routing. For this purpose, you can put files in a folder which is wrapped in parentheses - `(` and `)`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
-| pages/
|
||||||
|
---| index.vue
|
||||||
|
---| (marketing)/
|
||||||
|
-----| about.vue
|
||||||
|
-----| contact.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
This will produce `/`, `/about` and `/contact` pages in your app. The `marketing` group is ignored for purposes of your URL structure.
|
||||||
|
|
||||||
## Page Metadata
|
## Page Metadata
|
||||||
|
|
||||||
You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`:
|
You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`:
|
||||||
@ -334,9 +358,9 @@ Learn more about `<NuxtLink>` usage.
|
|||||||
|
|
||||||
## Programmatic Navigation
|
## Programmatic Navigation
|
||||||
|
|
||||||
Nuxt 3 allows programmatic navigation through the `navigateTo()` utility method. Using this utility method, you will be able to programmatically navigate the user in your app. This is great for taking input from the user and navigating them dynamically throughout your application. In this example, we have a simple method called `navigate()` that gets called when the user submits a search form.
|
Nuxt allows programmatic navigation through the `navigateTo()` utility method. Using this utility method, you will be able to programmatically navigate the user in your app. This is great for taking input from the user and navigating them dynamically throughout your application. In this example, we have a simple method called `navigate()` that gets called when the user submits a search form.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
Ensure to always `await` on `navigateTo` or chain its result by returning from functions.
|
Ensure to always `await` on `navigateTo` or chain its result by returning from functions.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -357,13 +381,25 @@ function navigate(){
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Custom routing
|
## Client-Only Pages
|
||||||
|
|
||||||
|
You can define a page as [client only](/docs/guide/directory-structure/components#client-components) by giving it a `.client.vue` suffix. None of the content of this page will be rendered on the server.
|
||||||
|
|
||||||
|
## Server-Only Pages
|
||||||
|
|
||||||
|
You can define a page as [server only](/docs/guide/directory-structure/components#server-components) by giving it a `.server.vue` suffix. While you will be able to navigate to the page using client-side navigation, controlled by `vue-router`, it will be rendered with a server component automatically, meaning the code required to render the page will not be in your client-side bundle.
|
||||||
|
|
||||||
|
::alert{type=warning}
|
||||||
|
Server-only pages must have a single root element. (HTML comments are considered elements as well.)
|
||||||
|
::
|
||||||
|
|
||||||
|
## Custom Routing
|
||||||
|
|
||||||
As your app gets bigger and more complex, your routing might require more flexibility. For this reason, Nuxt directly exposes the router, routes and router options for customization in different ways.
|
As your app gets bigger and more complex, your routing might require more flexibility. For this reason, Nuxt directly exposes the router, routes and router options for customization in different ways.
|
||||||
|
|
||||||
:read-more{to="/docs/guide/going-further/custom-routing"}
|
:read-more{to="/docs/guide/recipes/custom-routing"}
|
||||||
|
|
||||||
## Multiple pages directories
|
## Multiple Pages Directories
|
||||||
|
|
||||||
By default, all your pages should be in one `pages` directory at the root of your project.
|
By default, all your pages should be in one `pages` directory at the root of your project.
|
||||||
|
|
||||||
@ -372,7 +408,7 @@ However, you can use [Nuxt Layers](/docs/getting-started/layers) to create group
|
|||||||
```bash [Directory Structure]
|
```bash [Directory Structure]
|
||||||
-| some-app/
|
-| some-app/
|
||||||
---| nuxt.config.ts
|
---| nuxt.config.ts
|
||||||
---| pages
|
---| pages/
|
||||||
-----| app-page.vue
|
-----| app-page.vue
|
||||||
-| nuxt.config.ts
|
-| nuxt.config.ts
|
||||||
```
|
```
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
title: "plugins"
|
title: "plugins"
|
||||||
description: "Nuxt has a plugins system to use Vue plugins and more at the creation of your Vue application."
|
description: "Nuxt has a plugins system to use Vue plugins and more at the creation of your Vue application."
|
||||||
head.title: "plugins/"
|
head.title: "plugins/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt automatically reads the files in the `plugins/` directory and loads them at the creation of the Vue application.
|
Nuxt automatically reads the files in the `plugins/` directory and loads them at the creation of the Vue application.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
All plugins inside are auto-registered, you don't need not add them to your `nuxt.config` separately.
|
All plugins inside are auto-registered, you don't need to add them to your `nuxt.config` separately.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="yellow" icon="i-ph-lightbulb-duotone"}
|
::note
|
||||||
You can use `.server` or `.client` suffix in the file name to load a plugin only on the server or client side.
|
You can use `.server` or `.client` suffix in the file name to load a plugin only on the server or client side.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -76,9 +76,14 @@ export default defineNuxtPlugin({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=2aXZyXB1QGQ" target="_blank"}
|
||||||
If you are using the object-syntax, the properties may be statically analyzed in future to produce a more optimized build. So you should not define them at runtime. :br
|
Watch a video from Alexander Lichter about the Object Syntax for Nuxt plugins.
|
||||||
For example, setting `enforce: process.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
|
If you are using the object-syntax, the properties are statically analyzed to produce a more optimized build. So you should not define them at runtime. :br
|
||||||
|
For example, setting `enforce: import.meta.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
|
||||||
|
Nuxt does statically pre-load any hook listeners when using object-syntax, allowing you to define hooks without needing to worry about order of plugin registration.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Registration Order
|
## Registration Order
|
||||||
@ -95,7 +100,7 @@ In this example, `02.myOtherPlugin.ts` will be able to access anything that was
|
|||||||
|
|
||||||
This is useful in situations where you have a plugin that depends on another plugin.
|
This is useful in situations where you have a plugin that depends on another plugin.
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.myPlugin.ts` would come before `2.myOtherPlugin.ts`. This is why the example prefixes single digit numbers with `0`.
|
In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.myPlugin.ts` would come before `2.myOtherPlugin.ts`. This is why the example prefixes single digit numbers with `0`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -103,7 +108,7 @@ In case you're new to 'alphabetical' numbering, remember that filenames are sort
|
|||||||
|
|
||||||
### Parallel Plugins
|
### Parallel Plugins
|
||||||
|
|
||||||
By default, Nuxt loads plugins sequentially. You can define a plugin as `parallel` so Nuxt won't wait the end of the plugin's execution before loading the next plugin.
|
By default, Nuxt loads plugins sequentially. You can define a plugin as `parallel` so Nuxt won't wait until the end of the plugin's execution before loading the next plugin.
|
||||||
|
|
||||||
```ts twoslash [plugins/my-plugin.ts]
|
```ts twoslash [plugins/my-plugin.ts]
|
||||||
export default defineNuxtPlugin({
|
export default defineNuxtPlugin({
|
||||||
@ -117,7 +122,7 @@ export default defineNuxtPlugin({
|
|||||||
|
|
||||||
### Plugins With Dependencies
|
### Plugins With Dependencies
|
||||||
|
|
||||||
If a plugin needs to await a parallel plugin before it runs, you can add the plugin's name to the `dependsOn` array.
|
If a plugin needs to wait for another plugin before it runs, you can add the plugin's name to the `dependsOn` array.
|
||||||
|
|
||||||
```ts twoslash [plugins/depending-on-my-plugin.ts]
|
```ts twoslash [plugins/depending-on-my-plugin.ts]
|
||||||
export default defineNuxtPlugin({
|
export default defineNuxtPlugin({
|
||||||
@ -141,13 +146,13 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
|
|
||||||
However, keep in mind there are some limitations and differences:
|
However, keep in mind there are some limitations and differences:
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
**If a composable depends on another plugin registered later, it might not work.** :br
|
**If a composable depends on another plugin registered later, it might not work.** :br
|
||||||
|
|
||||||
Plugins are called in order sequentially and before everything else. You might use a composable that depends on another plugin which has not been called yet.
|
Plugins are called in order sequentially and before everything else. You might use a composable that depends on another plugin which has not been called yet.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
**If a composable depends on the Vue.js lifecycle, it won't work.** :br
|
**If a composable depends on the Vue.js lifecycle, it won't work.** :br
|
||||||
|
|
||||||
Normally, Vue.js composables are bound to the current component instance while plugins are only bound to [`nuxtApp`](/docs/api/composables/use-nuxt-app) instance.
|
Normally, Vue.js composables are bound to the current component instance while plugins are only bound to [`nuxtApp`](/docs/api/composables/use-nuxt-app) instance.
|
||||||
@ -196,11 +201,11 @@ const { $hello } = useNuxtApp()
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Note that we highly recommend using [`composables`](/docs/guide/directory-structure/composables) instead of providing helpers to avoid polluting the global namespace and keep your main bundle entry small.
|
Note that we highly recommend using [`composables`](/docs/guide/directory-structure/composables) instead of providing helpers to avoid polluting the global namespace and keep your main bundle entry small.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
**If your plugin provides a `ref` or `computed`, it will not be unwrapped in a component `<template>`.** :br
|
**If your plugin provides a `ref` or `computed`, it will not be unwrapped in a component `<template>`.** :br
|
||||||
This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-when-unwrapping-in-templates).
|
This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-when-unwrapping-in-templates).
|
||||||
::
|
::
|
||||||
@ -209,7 +214,7 @@ This is due to how Vue works with refs that aren't top-level to the template. Yo
|
|||||||
|
|
||||||
If you return your helpers from the plugin, they will be typed automatically; you'll find them typed for the return of `useNuxtApp()` and within your templates.
|
If you return your helpers from the plugin, they will be typed automatically; you'll find them typed for the return of `useNuxtApp()` and within your templates.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you need to use a provided helper _within_ another plugin, you can call [`useNuxtApp()`](/docs/api/composables/use-nuxt-app) to get the typed version. But in general, this should be avoided unless you are certain of the plugins' order.
|
If you need to use a provided helper _within_ another plugin, you can call [`useNuxtApp()`](/docs/api/composables/use-nuxt-app) to get the typed version. But in general, this should be avoided unless you are certain of the plugins' order.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -231,7 +236,7 @@ declare module 'vue' {
|
|||||||
export {}
|
export {}
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you are using WebStorm, you may need to augment `@vue/runtime-core` until [this issue](https://youtrack.jetbrains.com/issue/WEB-59818/VUE-TypeScript-WS-PS-does-not-correctly-display-type-of-globally-injected-properties) is resolved.
|
If you are using WebStorm, you may need to augment `@vue/runtime-core` until [this issue](https://youtrack.jetbrains.com/issue/WEB-59818/VUE-TypeScript-WS-PS-does-not-correctly-display-type-of-globally-injected-properties) is resolved.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -241,13 +246,13 @@ If you want to use Vue plugins, like [vue-gtag](https://github.com/MatteoGabriel
|
|||||||
|
|
||||||
First, install the Vue plugin dependency:
|
First, install the Vue plugin dependency:
|
||||||
|
|
||||||
::code-group
|
::package-managers
|
||||||
```bash [yarn]
|
|
||||||
yarn add --dev vue-gtag-next
|
|
||||||
```
|
|
||||||
```bash [npm]
|
```bash [npm]
|
||||||
npm install --save-dev vue-gtag-next
|
npm install --save-dev vue-gtag-next
|
||||||
```
|
```
|
||||||
|
```bash [yarn]
|
||||||
|
yarn add --dev vue-gtag-next
|
||||||
|
```
|
||||||
```bash [pnpm]
|
```bash [pnpm]
|
||||||
pnpm add -D vue-gtag-next
|
pnpm add -D vue-gtag-next
|
||||||
```
|
```
|
||||||
@ -289,7 +294,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
If you register a Vue directive, you _must_ register it on both client and server side unless you are only using it when rendering one side. If the directive only makes sense from a client side, you can always move it to `~/plugins/my-directive.client.ts` and provide a 'stub' directive for the server in `~/plugins/my-directive.server.ts`.
|
If you register a Vue directive, you _must_ register it on both client and server side unless you are only using it when rendering one side. If the directive only makes sense from a client side, you can always move it to `~/plugins/my-directive.client.ts` and provide a 'stub' directive for the server in `~/plugins/my-directive.server.ts`.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "public"
|
title: "public"
|
||||||
description: "The public/ directory is used to serve your website's static assets."
|
description: "The public/ directory is used to serve your website's static assets."
|
||||||
head.title: "public/"
|
head.title: "public/"
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
Files contained within the `public/` directory are served at the root and are not modified by the build process. This is suitable for files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. `favicon.ico`).
|
Files contained within the `public/` directory are served at the root and are not modified by the build process. This is suitable for files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. `favicon.ico`).
|
||||||
@ -22,6 +22,6 @@ useSeoMeta({
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{to="https://v2.nuxt.com/docs/directory-structure/static" target="_blank"}
|
::tip{to="https://v2.nuxt.com/docs/directory-structure/static" target="_blank"}
|
||||||
This is known as the [`static/`] directory in Nuxt 2.
|
This is known as the [`static/`] directory in Nuxt 2.
|
||||||
::
|
::
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: server
|
title: server
|
||||||
head.title: 'server/'
|
head.title: 'server/'
|
||||||
description: The server/ directory is used to register API and server handlers to your application.
|
description: The server/ directory is used to register API and server handlers to your application.
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt automatically scans files inside these directories to register API and server handlers with Hot Module Replacement (HMR) support.
|
Nuxt automatically scans files inside these directories to register API and server handlers with Hot Module Replacement (HMR) support.
|
||||||
@ -55,7 +55,7 @@ export default defineEventHandler(() => 'Hello World!')
|
|||||||
|
|
||||||
Given the example above, the `/hello` route will be accessible at <http://localhost:3000/hello>.
|
Given the example above, the `/hello` route will be accessible at <http://localhost:3000/hello>.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Note that currently server routes do not support the full functionality of dynamic routes as [pages](/docs/guide/directory-structure/pages#dynamic-routes) do.
|
Note that currently server routes do not support the full functionality of dynamic routes as [pages](/docs/guide/directory-structure/pages#dynamic-routes) do.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ Nuxt will automatically read in any file in the `~/server/middleware` to create
|
|||||||
|
|
||||||
Middleware handlers will run on every request before any other server route to add or check headers, log requests, or extend the event's request object.
|
Middleware handlers will run on every request before any other server route to add or check headers, log requests, or extend the event's request object.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Middleware handlers should not return anything (nor close or respond to the request) and only inspect or extend the request context or throw an error.
|
Middleware handlers should not return anything (nor close or respond to the request) and only inspect or extend the request context or throw an error.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ export const defineWrappedResponseHandler = <T extends EventHandlerRequest, D> (
|
|||||||
|
|
||||||
## Server Types
|
## Server Types
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
This feature is available from Nuxt >= 3.5
|
This feature is available from Nuxt >= 3.5
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ export default defineEventHandler((event) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{icon="i-ph-lightbulb" color="green"}
|
::tip
|
||||||
Alternatively, use `getValidatedRouterParams` with a schema validator such as Zod for runtime and type safety.
|
Alternatively, use `getValidatedRouterParams` with a schema validator such as Zod for runtime and type safety.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{icon="i-ph-lightbulb" color="green" to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web#runtime-type-safe-request-utils"}
|
::tip{to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web#runtime-type-safe-request-utils"}
|
||||||
Alternatively, use `readValidatedBody` with a schema validator such as Zod for runtime and type safety.
|
Alternatively, use `readValidatedBody` with a schema validator such as Zod for runtime and type safety.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ async function submit() {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
We are using `submit.post.ts` in the filename only to match requests with `POST` method that can accept the request body. When using `readBody` within a GET request, `readBody` will throw a `405 Method Not Allowed` HTTP error.
|
We are using `submit.post.ts` in the filename only to match requests with `POST` method that can accept the request body. When using `readBody` within a GET request, `readBody` will throw a `405 Method Not Allowed` HTTP error.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ export default defineEventHandler((event) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{icon="i-ph-lightbulb" color="green" to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web#runtime-type-safe-request-utils"}
|
::tip{to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web#runtime-type-safe-request-utils"}
|
||||||
Alternatively, use `getValidatedQuery` with a schema validator such as Zod for runtime and type safety.
|
Alternatively, use `getValidatedQuery` with a schema validator such as Zod for runtime and type safety.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ NUXT_GITHUB_TOKEN='<my-super-token>'
|
|||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Giving the `event` as argument to `useRuntimeConfig` is optional, but it is recommended to pass it to get the runtime config overwritten by [environment variables](/docs/guide/going-further/runtime-config#environment-variables) at runtime for server routes.
|
Giving the `event` as argument to `useRuntimeConfig` is optional, but it is recommended to pass it to get the runtime config overwritten by [environment variables](/docs/guide/going-further/runtime-config#environment-variables) at runtime for server routes.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -347,13 +347,29 @@ export default defineEventHandler((event) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Forwarding Context & Headers
|
||||||
|
|
||||||
|
By default, neither the headers from the incoming request nor the request context are forwarded when
|
||||||
|
making fetch requests in server routes. You can use `event.$fetch` to forward the request context and headers when making fetch requests in server routes.
|
||||||
|
|
||||||
|
```ts [server/api/forward.ts]
|
||||||
|
export default defineEventHandler((event) => {
|
||||||
|
return event.$fetch('/api/forwarded')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
::note
|
||||||
|
Headers that are **not meant to be forwarded** will **not be included** in the request. These headers include, for example:
|
||||||
|
`transfer-encoding`, `connection`, `keep-alive`, `upgrade`, `expect`, `host`, `accept`
|
||||||
|
::
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
### Nitro Config
|
### Nitro Config
|
||||||
|
|
||||||
You can use `nitro` key in `nuxt.config` to directly set [Nitro configuration](https://nitro.unjs.io/config).
|
You can use `nitro` key in `nuxt.config` to directly set [Nitro configuration](https://nitro.unjs.io/config).
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
This is an advanced option. Custom config can affect production deployments, as the configuration interface might change over time when Nitro is upgraded in semver-minor versions of Nuxt.
|
This is an advanced option. Custom config can affect production deployments, as the configuration interface might change over time when Nitro is upgraded in semver-minor versions of Nuxt.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -380,7 +396,7 @@ export default useBase('/api/hello', router.handler)
|
|||||||
|
|
||||||
### Sending Streams
|
### Sending Streams
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
This is an experimental feature and is available in all environments.
|
This is an experimental feature and is available in all environments.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -409,7 +425,7 @@ export default fromNodeMiddleware((req, res) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Legacy support is possible using [unjs/h3](https://github.com/unjs/h3), but it is advised to avoid legacy handlers as much as you can.
|
Legacy support is possible using [unjs/h3](https://github.com/unjs/h3), but it is advised to avoid legacy handlers as much as you can.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -420,7 +436,7 @@ export default fromNodeMiddleware((req, res, next) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Never combine `next()` callback with a legacy middleware that is `async` or returns a `Promise`.
|
Never combine `next()` callback with a legacy middleware that is `async` or returns a `Promise`.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: 'utils'
|
title: 'utils'
|
||||||
head.title: 'utils/'
|
head.title: 'utils/'
|
||||||
description: Use the utils/ directory to auto-import your utility functions throughout your application.
|
description: Use the utils/ directory to auto-import your utility functions throughout your application.
|
||||||
navigation.icon: i-ph-folder-duotone
|
navigation.icon: i-ph-folder
|
||||||
---
|
---
|
||||||
|
|
||||||
The main purpose of the [`utils/` directory](/docs/guide/directory-structure/utils) is to allow a semantic distinction between your Vue composables and other auto-imported utility functions.
|
The main purpose of the [`utils/` directory](/docs/guide/directory-structure/utils) is to allow a semantic distinction between your Vue composables and other auto-imported utility functions.
|
||||||
@ -39,11 +39,11 @@ You can now use auto imported utility functions in `.js`, `.ts` and `.vue` files
|
|||||||
|
|
||||||
:link-example{to="/docs/examples/features/auto-imports"}
|
:link-example{to="/docs/examples/features/auto-imports"}
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
The way `utils/` auto-imports work and are scanned is identical to the [`composables/`](/docs/guide/directory-structure/composables) directory.
|
The way `utils/` auto-imports work and are scanned is identical to the [`composables/`](/docs/guide/directory-structure/composables) directory.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
These utils are only available within the Vue part of your app. :br
|
These utils are only available within the Vue part of your app. :br
|
||||||
Only `server/utils` are auto-imported in the [`server/`](/docs/guide/directory-structure/server#server-utilities) directory.
|
Only `server/utils` are auto-imported in the [`server/`](/docs/guide/directory-structure/server#server-utilities) directory.
|
||||||
::
|
::
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
title: ".env"
|
title: ".env"
|
||||||
description: "A .env file specifies your build/dev-time environment variables."
|
description: "A .env file specifies your build/dev-time environment variables."
|
||||||
head.title: ".env"
|
head.title: ".env"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout{icon="i-ph-warning-duotone" color="amber"}
|
::important
|
||||||
This file should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing secrets to your repository.
|
This file should be added to your [`.gitignore`](/docs/guide/directory-structure/gitignore) file to avoid pushing secrets to your repository.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ In addition to any process environment variables, if you have a `.env` file in y
|
|||||||
MY_ENV_VARIABLE=hello
|
MY_ENV_VARIABLE=hello
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Note that removing a variable from `.env` or removing the `.env` file entirely will not unset values that have already been set.
|
Note that removing a variable from `.env` or removing the `.env` file entirely will not unset values that have already been set.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -33,11 +33,29 @@ npx nuxi dev --dotenv .env.local
|
|||||||
|
|
||||||
When updating `.env` in development mode, the Nuxt instance is automatically restarted to apply new values to the `process.env`.
|
When updating `.env` in development mode, the Nuxt instance is automatically restarted to apply new values to the `process.env`.
|
||||||
|
|
||||||
## Production Preview
|
::important
|
||||||
|
In your application code, you should use [Runtime Config](/docs/guide/going-further/runtime-config) instead of plain env variables.
|
||||||
|
::
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
**After your server is built**, you are responsible for setting environment variables when you run the server.
|
**After your server is built**, you are responsible for setting environment variables when you run the server.
|
||||||
|
|
||||||
Your `.env` file will not be read at this point. How you do this is different for every environment.
|
Your `.env` files will not be read at this point. How you do this is different for every environment.
|
||||||
|
|
||||||
|
This design decision was made to ensure compatibility across various deployment environments, some of which may not have a traditional file system available, such as serverless platforms or edge networks like Cloudflare Workers.
|
||||||
|
|
||||||
|
Since `.env` files are not used in production, you must explicitly set environment variables using the tools and methods provided by your hosting environment. Here are some common approaches:
|
||||||
|
|
||||||
|
* You can pass the environment variables as arguments using the terminal:
|
||||||
|
|
||||||
|
`$ DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs`
|
||||||
|
|
||||||
|
* You can set environment variables in shell configuration files like `.bashrc` or `.profile`.
|
||||||
|
|
||||||
|
* Many cloud service providers, such as Vercel, Netlify, and AWS, provide interfaces for setting environment variables via their dashboards, CLI tools or configuration files.
|
||||||
|
|
||||||
|
## Production Preview
|
||||||
|
|
||||||
For local production preview purpose, we recommend using [`nuxi preview`](/docs/api/commands/preview) since using this command, the `.env` file will be loaded into `process.env` for convenience. Note that this command requires dependencies to be installed in the package directory.
|
For local production preview purpose, we recommend using [`nuxi preview`](/docs/api/commands/preview) since using this command, the `.env` file will be loaded into `process.env` for convenience. Note that this command requires dependencies to be installed in the package directory.
|
||||||
|
|
||||||
@ -51,7 +69,7 @@ Note that for a purely static site, it is not possible to set runtime configurat
|
|||||||
|
|
||||||
:read-more{to="/docs/guide/going-further/runtime-config"}
|
:read-more{to="/docs/guide/going-further/runtime-config"}
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you want to use environment variables set at build time but do not care about updating these down the line (or only need to update them reactively _within_ your app) then `appConfig` may be a better choice. You can define `appConfig` both within your `nuxt.config` (using environment variables) and also within an `~/app.config.ts` file in your project.
|
If you want to use environment variables set at build time but do not care about updating these down the line (or only need to update them reactively _within_ your app) then `appConfig` may be a better choice. You can define `appConfig` both within your `nuxt.config` (using environment variables) and also within an `~/app.config.ts` file in your project.
|
||||||
:read-more{to="/docs/guide/directory-structure/app-config"}
|
:read-more{to="/docs/guide/directory-structure/app-config"}
|
||||||
::
|
::
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: ".gitignore"
|
title: ".gitignore"
|
||||||
description: "A .gitignore file specifies intentionally untracked files that git should ignore."
|
description: "A .gitignore file specifies intentionally untracked files that git should ignore."
|
||||||
head.title: ".gitignore"
|
head.title: ".gitignore"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
A `.gitignore` file specifies intentionally untracked files that git should ignore.
|
A `.gitignore` file specifies intentionally untracked files that git should ignore.
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
title: .nuxtignore
|
title: .nuxtignore
|
||||||
head.title: '.nuxtignore'
|
head.title: '.nuxtignore'
|
||||||
description: The .nuxtignore file lets Nuxt ignore files in your project’s root directory during the build phase.
|
description: The .nuxtignore file lets Nuxt ignore files in your project’s root directory during the build phase.
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
The `.nuxtignore` file tells Nuxt to ignore files in your project’s root directory ([`rootDir`](/docs/api/nuxt-config#rootdir)) during the build phase.
|
The `.nuxtignore` file tells Nuxt to ignore files in your project’s root directory ([`rootDir`](/docs/api/nuxt-config#rootdir)) during the build phase.
|
||||||
|
|
||||||
It is subject to the same specification as [`.gitignore`](/docs/guide/directory-structure/gitignore) and `.eslintignore` files, in which each line is a glob pattern indicating which files should be ignored.
|
It is subject to the same specification as [`.gitignore`](/docs/guide/directory-structure/gitignore) and `.eslintignore` files, in which each line is a glob pattern indicating which files should be ignored.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
You can also configure [`ignoreOptions`](/docs/api/nuxt-config#ignoreoptions), [`ignorePrefix`](/docs/api/nuxt-config#ignoreprefix) and [`ignore`](/docs/api/nuxt-config#ignore) in your `nuxt.config` file.
|
You can also configure [`ignoreOptions`](/docs/api/nuxt-config#ignoreoptions), [`ignorePrefix`](/docs/api/nuxt-config#ignoreprefix) and [`ignore`](/docs/api/nuxt-config#ignore) in your `nuxt.config` file.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
title: app.config.ts
|
title: app.config.ts
|
||||||
head.title: 'app.config.ts'
|
head.title: 'app.config.ts'
|
||||||
description: Expose reactive configuration within your application with the App Config file.
|
description: Expose reactive configuration within your application with the App Config file.
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt 3 provides an `app.config` config file to expose reactive configuration within your application with the ability to update it at runtime within lifecycle or using a nuxt plugin and editing it with HMR (hot-module-replacement).
|
Nuxt provides an `app.config` config file to expose reactive configuration within your application with the ability to update it at runtime within lifecycle or using a nuxt plugin and editing it with HMR (hot-module-replacement).
|
||||||
|
|
||||||
You can easily provide runtime app configuration using `app.config.ts` file. It can have either of `.ts`, `.js`, or `.mjs` extensions.
|
You can easily provide runtime app configuration using `app.config.ts` file. It can have either of `.ts`, `.js`, or `.mjs` extensions.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ export default defineAppConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::caution
|
||||||
Do not put any secret values inside `app.config` file. It is exposed to the user client bundle.
|
Do not put any secret values inside `app.config` file. It is exposed to the user client bundle.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ export {}
|
|||||||
|
|
||||||
If you want to type the result of calling [`useAppConfig()`](/docs/api/composables/use-app-config), then you will want to extend `AppConfig`.
|
If you want to type the result of calling [`useAppConfig()`](/docs/api/composables/use-app-config), then you will want to extend `AppConfig`.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Be careful when typing `AppConfig` as you will overwrite the types Nuxt infers from your actually defined app config.
|
Be careful when typing `AppConfig` as you will overwrite the types Nuxt infers from your actually defined app config.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -98,8 +98,8 @@ Nuxt uses a custom merging strategy for the `AppConfig` within [the layers](/doc
|
|||||||
|
|
||||||
This strategy is implemented using a [Function Merger](https://github.com/unjs/defu#function-merger), which allows defining a custom merging strategy for every key in `app.config` that has an array as value.
|
This strategy is implemented using a [Function Merger](https://github.com/unjs/defu#function-merger), which allows defining a custom merging strategy for every key in `app.config` that has an array as value.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
The Function Merger should only be used in the base `app.config` of your application.
|
The function merger can only be used in the extended layers and not the main `app.config` in project.
|
||||||
::
|
::
|
||||||
|
|
||||||
Here's an example of how you can use:
|
Here's an example of how you can use:
|
||||||
@ -121,3 +121,37 @@ export default defineAppConfig({
|
|||||||
```
|
```
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
## Known Limitations
|
||||||
|
|
||||||
|
As of Nuxt v3.3, the `app.config.ts` file is shared with Nitro, which results in the following limitations:
|
||||||
|
|
||||||
|
1. You cannot import Vue components directly in `app.config.ts`.
|
||||||
|
2. Some auto-imports are not available in the Nitro context.
|
||||||
|
|
||||||
|
These limitations occur because Nitro processes the app config without full Vue component support.
|
||||||
|
|
||||||
|
While it's possible to use Vite plugins in the Nitro config as a workaround, this approach is not recommended:
|
||||||
|
|
||||||
|
```ts [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
nitro: {
|
||||||
|
vite: {
|
||||||
|
plugins: [vue()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
::warning
|
||||||
|
Using this workaround may lead to unexpected behavior and bugs. The Vue plugin is one of many that are not available in the Nitro context.
|
||||||
|
::
|
||||||
|
|
||||||
|
Related issues:
|
||||||
|
- [Issue #19858](https://github.com/nuxt/nuxt/issues/19858)
|
||||||
|
- [Issue #19854](https://github.com/nuxt/nuxt/issues/19854)
|
||||||
|
|
||||||
|
::info
|
||||||
|
Nitro v3 will resolve these limitations by removing support for the app config.
|
||||||
|
You can track the progress in [this pull request](https://github.com/unjs/nitro/pull/2521).
|
||||||
|
::
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "app.vue"
|
title: "app.vue"
|
||||||
description: "The app.vue file is the main component of your Nuxt application."
|
description: "The app.vue file is the main component of your Nuxt application."
|
||||||
head.title: "app.vue"
|
head.title: "app.vue"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
## Minimal Usage
|
## Minimal Usage
|
||||||
@ -31,11 +31,11 @@ If you have a [`pages/`](/docs/guide/directory-structure/pages) directory, to di
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Since [`<NuxtPage>`](/docs/api/components/nuxt-page) internally uses Vue's [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense.html#suspense) component, it cannot be set as a root element.
|
Since [`<NuxtPage>`](/docs/api/components/nuxt-page) internally uses Vue's [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense.html#suspense) component, it cannot be set as a root element.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
Remember that `app.vue` acts as the main component of your Nuxt application. Anything you add to it (JS and CSS) will be global and included in every page.
|
Remember that `app.vue` acts as the main component of your Nuxt application. Anything you add to it (JS and CSS) will be global and included in every page.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "error.vue"
|
title: "error.vue"
|
||||||
description: "The error.vue file is the error page in your Nuxt application."
|
description: "The error.vue file is the error page in your Nuxt application."
|
||||||
head.title: "error.vue"
|
head.title: "error.vue"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
During the lifespan of your application, some errors may appear unexpectedly at runtime. In such case, we can use the `error.vue` file to override the default error files and display the error nicely.
|
During the lifespan of your application, some errors may appear unexpectedly at runtime. In such case, we can use the `error.vue` file to override the default error files and display the error nicely.
|
||||||
@ -24,7 +24,7 @@ const props = defineProps({
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Although it is called an 'error page' it's not a route and shouldn't be placed in your `~/pages` directory. For the same reason, you shouldn't use `definePageMeta` within this page. That being said, you can still use layouts in the error file, by utilizing the [`NuxtLayout`](/docs/api/components/nuxt-layout) component and specifying the name of the layout.
|
Although it is called an 'error page' it's not a route and shouldn't be placed in your `~/pages` directory. For the same reason, you shouldn't use `definePageMeta` within this page. That being said, you can still use layouts in the error file, by utilizing the [`NuxtLayout`](/docs/api/components/nuxt-layout) component and specifying the name of the layout.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "nuxt.config.ts"
|
title: "nuxt.config.ts"
|
||||||
description: "Nuxt can be easily configured with a single nuxt.config file."
|
description: "Nuxt can be easily configured with a single nuxt.config file."
|
||||||
head.title: "nuxt.config.ts"
|
head.title: "nuxt.config.ts"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
The `nuxt.config` file extension can either be `.js`, `.ts` or `.mjs`.
|
The `nuxt.config` file extension can either be `.js`, `.ts` or `.mjs`.
|
||||||
@ -13,7 +13,7 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
`defineNuxtConfig` helper is globally available without import.
|
`defineNuxtConfig` helper is globally available without import.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ Discover all the available options in the **Nuxt configuration** documentation.
|
|||||||
|
|
||||||
To ensure your configuration is up to date, Nuxt will make a full restart when detecting changes in the main configuration file, the [`.env`](/docs/guide/directory-structure/env), [`.nuxtignore`](/docs/guide/directory-structure/nuxtignore) and `.nuxtrc` dotfiles.
|
To ensure your configuration is up to date, Nuxt will make a full restart when detecting changes in the main configuration file, the [`.env`](/docs/guide/directory-structure/env), [`.nuxtignore`](/docs/guide/directory-structure/nuxtignore) and `.nuxtrc` dotfiles.
|
||||||
|
|
||||||
The `.nuxtrc` file is a file that can be used to configure Nuxt with a fla syntax, it is based on [`unjs/rc9`](https://github.com/unjs/rc9).
|
The `.nuxtrc` file can be used to configure Nuxt with a flat syntax. It is based on [`unjs/rc9`](https://github.com/unjs/rc9).
|
||||||
|
|
||||||
``` [.nuxtrc]
|
``` [.nuxtrc]
|
||||||
ssr=false
|
ssr=false
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: package.json
|
title: package.json
|
||||||
head.title: package.json
|
head.title: package.json
|
||||||
description: The package.json file contains all the dependencies and scripts for your application.
|
description: The package.json file contains all the dependencies and scripts for your application.
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
The minimal `package.json` of your Nuxt application should looks like:
|
The minimal `package.json` of your Nuxt application should looks like:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title: "tsconfig.json"
|
title: "tsconfig.json"
|
||||||
description: "Nuxt generates a .nuxt/tsconfig.json file with sensible defaults and your aliases."
|
description: "Nuxt generates a .nuxt/tsconfig.json file with sensible defaults and your aliases."
|
||||||
head.title: "tsconfig.json"
|
head.title: "tsconfig.json"
|
||||||
navigation.icon: i-ph-file-duotone
|
navigation.icon: i-ph-file
|
||||||
---
|
---
|
||||||
|
|
||||||
Nuxt [automatically generates](/docs/guide/concepts/typescript) a `.nuxt/tsconfig.json` file with the resolved aliases you are using in your Nuxt project, as well as with other sensible defaults.
|
Nuxt [automatically generates](/docs/guide/concepts/typescript) a `.nuxt/tsconfig.json` file with the resolved aliases you are using in your Nuxt project, as well as with other sensible defaults.
|
||||||
@ -15,10 +15,10 @@ You can benefit from this by creating a `tsconfig.json` in the root of your proj
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
As you need to, you can customize the contents of this file. However, it is recommended that you don't overwrite `target`, `module` and `moduleResolution`.
|
As you need to, you can customize the contents of this file. However, it is recommended that you don't overwrite `target`, `module` and `moduleResolution`.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
If you need to customize your `paths`, this will override the auto-generated path aliases. Instead, we recommend that you add any path aliases you need to the [`alias`](/docs/api/nuxt-config#alias) property within your `nuxt.config`, where they will get picked up and added to the auto-generated `tsconfig`.
|
If you need to customize your `paths`, this will override the auto-generated path aliases. Instead, we recommend that you add any path aliases you need to the [`alias`](/docs/api/nuxt-config#alias) property within your `nuxt.config`, where they will get picked up and added to the auto-generated `tsconfig`.
|
||||||
::
|
::
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
title: Directory Structure
|
title: Directory Structure
|
||||||
titleTemplate: '%s · Nuxt Directory Structure'
|
titleTemplate: '%s · Nuxt Directory Structure'
|
||||||
icon: i-ph-folders-duotone
|
icon: i-ph-folders
|
||||||
|
@ -7,7 +7,7 @@ The Nuxt experimental features can be enabled in the Nuxt configuration file.
|
|||||||
|
|
||||||
Internally, Nuxt uses `@nuxt/schema` to define these experimental features. You can refer to the [API documentation](/docs/api/configuration/nuxt-config#experimental) or the [source code](https://github.com/nuxt/nuxt/blob/main/packages/schema/src/config/experimental.ts) for more information.
|
Internally, Nuxt uses `@nuxt/schema` to define these experimental features. You can refer to the [API documentation](/docs/api/configuration/nuxt-config#experimental) or the [source code](https://github.com/nuxt/nuxt/blob/main/packages/schema/src/config/experimental.ts) for more information.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Note that these features are experimental and could be removed or modified in the future.
|
Note that these features are experimental and could be removed or modified in the future.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -53,24 +53,10 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
This feature will likely be removed in a near future.
|
This feature will likely be removed in a near future.
|
||||||
::
|
::
|
||||||
|
|
||||||
## treeshakeClientOnly
|
|
||||||
|
|
||||||
Tree shakes contents of client-only components from server bundle.
|
|
||||||
|
|
||||||
*Enabled by default.*
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
experimental: {
|
|
||||||
treeshakeClientOnly: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## emitRouteChunkError
|
## emitRouteChunkError
|
||||||
|
|
||||||
Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a hard reload of the new route when a chunk fails to load.
|
Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a hard reload of the new route when a chunk fails to load.
|
||||||
@ -91,7 +77,7 @@ Allows Nuxt app state to be restored from `sessionStorage` when reloading the pa
|
|||||||
|
|
||||||
To avoid hydration errors, it will be applied only after the Vue app has been mounted, meaning there may be a flicker on initial load.
|
To avoid hydration errors, it will be applied only after the Vue app has been mounted, meaning there may be a flicker on initial load.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Consider carefully before enabling this as it can cause unexpected behavior,
|
Consider carefully before enabling this as it can cause unexpected behavior,
|
||||||
and consider providing explicit keys to [`useState`](/docs/api/composables/use-state) as auto-generated keys may not match across builds.
|
and consider providing explicit keys to [`useState`](/docs/api/composables/use-state) as auto-generated keys may not match across builds.
|
||||||
::
|
::
|
||||||
@ -118,11 +104,11 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
Matching route rules will be created, based on the page's `path`.
|
Matching route rules will be created, based on the page's `path`.
|
||||||
|
|
||||||
::read-more{to="/docs/api/utils/define-route-rules" icon="i-ph-function-duotone"}
|
::read-more{to="/docs/api/utils/define-route-rules" icon="i-ph-function"}
|
||||||
Read more in `defineRouteRules` utility.
|
Read more in `defineRouteRules` utility.
|
||||||
::
|
::
|
||||||
|
|
||||||
:read-more{to="/docs/guide/concepts/rendering#hybrid-rendering" icon="i-ph-medal-duotone"}
|
:read-more{to="/docs/guide/concepts/rendering#hybrid-rendering" icon="i-ph-medal"}
|
||||||
|
|
||||||
## renderJsonPayloads
|
## renderJsonPayloads
|
||||||
|
|
||||||
@ -238,44 +224,6 @@ export default defineNuxtConfig({
|
|||||||
You can follow the server components roadmap on GitHub.
|
You can follow the server components roadmap on GitHub.
|
||||||
::
|
::
|
||||||
|
|
||||||
## configSchema
|
|
||||||
|
|
||||||
Enables config schema support.
|
|
||||||
|
|
||||||
*Enabled by default.*
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
experimental: {
|
|
||||||
configSchema: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## polyfillVueUseHead
|
|
||||||
|
|
||||||
Adds a compatibility layer for modules, plugins, or user code relying on the old `@vueuse/head` API.
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
experimental: {
|
|
||||||
polyfillVueUseHead: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## respectNoSSRHeader
|
|
||||||
|
|
||||||
Allow disabling Nuxt SSR responses by setting the `x-nuxt-no-ssr` header.
|
|
||||||
|
|
||||||
```ts twoslash [nuxt.config.ts]
|
|
||||||
export default defineNuxtConfig({
|
|
||||||
experimental: {
|
|
||||||
respectNoSSRHeader: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## localLayerAliases
|
## localLayerAliases
|
||||||
|
|
||||||
Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories.
|
Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories.
|
||||||
@ -306,6 +254,10 @@ Out of the box, this will enable typed usage of [`navigateTo`](/docs/api/utils/n
|
|||||||
|
|
||||||
You can even get typed params within a page by using `const route = useRoute('route-name')`.
|
You can even get typed params within a page by using `const route = useRoute('route-name')`.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=SXk-L19gTZk" target="_blank"}
|
||||||
|
Watch a video from Daniel Roe explaining type-safe routing in Nuxt.
|
||||||
|
::
|
||||||
|
|
||||||
## watcher
|
## watcher
|
||||||
|
|
||||||
Set an alternative watcher that will be used as the watching service for Nuxt.
|
Set an alternative watcher that will be used as the watching service for Nuxt.
|
||||||
@ -340,6 +292,10 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=1jUupYHVvrU" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter about the experimental `sharedPrerenderData` setting.
|
||||||
|
::
|
||||||
|
|
||||||
It is particularly important when enabling this feature to make sure that any unique key of your data
|
It is particularly important when enabling this feature to make sure that any unique key of your data
|
||||||
is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch
|
is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch
|
||||||
data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch`
|
data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch`
|
||||||
@ -378,6 +334,16 @@ This option allows exposing some route metadata defined in `definePageMeta` at b
|
|||||||
|
|
||||||
This only works with static or strings/arrays rather than variables or conditional assignment. See [original issue](https://github.com/nuxt/nuxt/issues/24770) for more information and context.
|
This only works with static or strings/arrays rather than variables or conditional assignment. See [original issue](https://github.com/nuxt/nuxt/issues/24770) for more information and context.
|
||||||
|
|
||||||
|
You can disable this feature if it causes issues in your project.
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
scanPageMeta: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## cookieStore
|
## cookieStore
|
||||||
|
|
||||||
Enables CookieStore support to listen for cookie updates (if supported by the browser) and refresh `useCookie` ref values.
|
Enables CookieStore support to listen for cookie updates (if supported by the browser) and refresh `useCookie` ref values.
|
||||||
@ -393,3 +359,62 @@ export default defineNuxtConfig({
|
|||||||
::read-more{icon="i-simple-icons-mdnwebdocs" color="gray" to="https://developer.mozilla.org/en-US/docs/Web/API/CookieStore" target="_blank"}
|
::read-more{icon="i-simple-icons-mdnwebdocs" color="gray" to="https://developer.mozilla.org/en-US/docs/Web/API/CookieStore" target="_blank"}
|
||||||
Read more about the **CookieStore**.
|
Read more about the **CookieStore**.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
## buildCache
|
||||||
|
|
||||||
|
Caches Nuxt build artifacts based on a hash of the configuration and source files.
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
buildCache: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
When enabled, changes to the following files will trigger a full rebuild:
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
.nuxtrc
|
||||||
|
.npmrc
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
tsconfig.json
|
||||||
|
bun.lockb
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition, any changes to files within `srcDir` will trigger a rebuild of the Vue client/server bundle. Nitro will always be rebuilt (though work is in progress to allow Nitro to announce its cacheable artifacts and their hashes).
|
||||||
|
|
||||||
|
::note
|
||||||
|
A maximum of 10 cache tarballs are kept.
|
||||||
|
::
|
||||||
|
|
||||||
|
## normalizeComponentNames
|
||||||
|
|
||||||
|
Ensure that auto-generated Vue component names match the full component name
|
||||||
|
you would use to auto-import the component.
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
normalizeComponentNames: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, if you haven't set it manually, Vue will assign a component name that matches
|
||||||
|
the filename of the component.
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
├─ components/
|
||||||
|
├─── SomeFolder/
|
||||||
|
├───── MyComponent.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `<KeepAlive>` with it, or identify it in the Vue DevTools, you would need to use this component.
|
||||||
|
|
||||||
|
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
|
||||||
|
|
||||||
|
By setting `experimental.normalizeComponentNames`, these two values match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
|
||||||
|
@ -37,6 +37,50 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
There is also a `future` namespace for early opting-in to new features that will become default in a future (possibly major) version of the framework.
|
There is also a `future` namespace for early opting-in to new features that will become default in a future (possibly major) version of the framework.
|
||||||
|
|
||||||
|
### compatibilityVersion
|
||||||
|
|
||||||
|
::important
|
||||||
|
This configuration option is available in Nuxt v3.12+.
|
||||||
|
::
|
||||||
|
|
||||||
|
This enables early access to Nuxt features or flags.
|
||||||
|
|
||||||
|
Setting `compatibilityVersion` to `4` changes defaults throughout your
|
||||||
|
Nuxt configuration to opt-in to Nuxt v4 behaviour, but you can granularly re-enable Nuxt v3 behaviour
|
||||||
|
when testing (see example). Please file issues if so, so that we can
|
||||||
|
address in Nuxt or in the ecosystem.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
future: {
|
||||||
|
compatibilityVersion: 4,
|
||||||
|
},
|
||||||
|
// To re-enable _all_ Nuxt v3 behaviour, set the following options:
|
||||||
|
srcDir: '.',
|
||||||
|
dir: {
|
||||||
|
app: 'app'
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
sharedPrerenderData: false,
|
||||||
|
compileTemplate: true,
|
||||||
|
resetAsyncDataToUndefined: true,
|
||||||
|
templateUtils: true,
|
||||||
|
relativeWatchPaths: true,
|
||||||
|
normalizeComponentNames: false
|
||||||
|
defaults: {
|
||||||
|
useAsyncData: {
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unhead: {
|
||||||
|
renderSSRHeadOptions: {
|
||||||
|
omitLineBreaks: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
### typescriptBundlerResolution
|
### typescriptBundlerResolution
|
||||||
|
|
||||||
This enables 'Bundler' module resolution mode for TypeScript, which is the recommended setting
|
This enables 'Bundler' module resolution mode for TypeScript, which is the recommended setting
|
||||||
|
@ -29,7 +29,7 @@ console.log(runtimeConfig.apiSecret)
|
|||||||
console.log(runtimeConfig.public.apiBase)
|
console.log(runtimeConfig.public.apiBase)
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
Public runtime config is accessible in Vue templates with `$config.public`.
|
Public runtime config is accessible in Vue templates with `$config.public`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ Instead of passing non-serializable objects or functions into your application f
|
|||||||
|
|
||||||
The most common way to provide configuration is by using [Environment Variables](https://medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa).
|
The most common way to provide configuration is by using [Environment Variables](https://medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa).
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Nuxi CLI has built-in support for reading your `.env` file in development, build and generate. But when you run your built server, **your `.env` file will not be read**.
|
Nuxi CLI has built-in support for reading your `.env` file in development, build and generate. But when you run your built server, **your `.env` file will not be read**.
|
||||||
:read-more{to="/docs/guide/directory-structure/env"}
|
:read-more{to="/docs/guide/directory-structure/env"}
|
||||||
::
|
::
|
||||||
@ -56,11 +56,15 @@ There are two key requirements:
|
|||||||
|
|
||||||
1. Only a specially-named environment variable can override a runtime config property. That is, an uppercase environment variable starting with `NUXT_` which uses `_` to separate keys and case changes.
|
1. Only a specially-named environment variable can override a runtime config property. That is, an uppercase environment variable starting with `NUXT_` which uses `_` to separate keys and case changes.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Setting the default of `runtimeConfig` values to *differently named environment variables* (for example setting `myVar` to `process.env.OTHER_VARIABLE`) will only work during build-time and will break on runtime.
|
Setting the default of `runtimeConfig` values to *differently named environment variables* (for example setting `myVar` to `process.env.OTHER_VARIABLE`) will only work during build-time and will break on runtime.
|
||||||
It is advised to use environment variables that match the structure of your `runtimeConfig` object.
|
It is advised to use environment variables that match the structure of your `runtimeConfig` object.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://youtu.be/_FYV5WfiWvs" target="_blank"}
|
||||||
|
Watch a video from Alexander Lichter showcasing the top mistake developers make using runtimeConfig.
|
||||||
|
::
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
```sh [.env]
|
```sh [.env]
|
||||||
@ -85,12 +89,12 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
Within the Vue part of your Nuxt app, you will need to call [`useRuntimeConfig()`](/docs/api/composables/use-runtime-config) to access the runtime config.
|
Within the Vue part of your Nuxt app, you will need to call [`useRuntimeConfig()`](/docs/api/composables/use-runtime-config) to access the runtime config.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
The behavior is different between the client-side and server-side:
|
The behavior is different between the client-side and server-side:
|
||||||
|
|
||||||
- On client-side, only keys in `runtimeConfig.public` are available, and the object is both writable and reactive.
|
- On client-side, only keys in `runtimeConfig.public` are available, and the object is both writable and reactive.
|
||||||
|
|
||||||
- On server-side, the entire runtime config is available on the server-side, but it is read-only to avoid context sharing.
|
- On server-side, the entire runtime config is available, but it is read-only to avoid context sharing.
|
||||||
::
|
::
|
||||||
|
|
||||||
```vue [pages/index.vue]
|
```vue [pages/index.vue]
|
||||||
@ -98,7 +102,7 @@ The behavior is different between the client-side and server-side:
|
|||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
console.log('Runtime config:', config)
|
console.log('Runtime config:', config)
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
console.log('API secret:', config.apiSecret)
|
console.log('API secret:', config.apiSecret)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -110,7 +114,7 @@ if (process.server) {
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{icon="i-ph-flag-duotone" color="red"}
|
::caution
|
||||||
**Security note:** Be careful not to expose runtime config keys to the client-side by either rendering them or passing them to `useState`.
|
**Security note:** Be careful not to expose runtime config keys to the client-side by either rendering them or passing them to `useState`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -142,7 +146,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Giving the `event` as argument to `useRuntimeConfig` is optional, but it is recommended to pass it to get the runtime config overwritten by [environment variables](/docs/guide/going-further/runtime-config#environment-variables) at runtime for server routes.
|
Giving the `event` as argument to `useRuntimeConfig` is optional, but it is recommended to pass it to get the runtime config overwritten by [environment variables](/docs/guide/going-further/runtime-config#environment-variables) at runtime for server routes.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -164,3 +168,7 @@ declare module 'nuxt/schema' {
|
|||||||
// It is always important to ensure you import/export something when augmenting a type
|
// It is always important to ensure you import/export something when augmenting a type
|
||||||
export {}
|
export {}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
::note
|
||||||
|
`nuxt/schema` is provided as a convenience for end-users to access the version of the schema used by Nuxt in their project. Module authors should instead augment `@nuxt/schema`.
|
||||||
|
::
|
||||||
|
@ -11,10 +11,16 @@ You can use these 'nightly' releases to beta test new features and changes.
|
|||||||
|
|
||||||
The build and publishing method and quality of these 'nightly' releases are the same as stable ones. The only difference is that you should often check the GitHub repository for updates. There is a slight chance of regressions not being caught during the review process and by the automated tests. Therefore, we internally use this channel to double-check everything before each release.
|
The build and publishing method and quality of these 'nightly' releases are the same as stable ones. The only difference is that you should often check the GitHub repository for updates. There is a slight chance of regressions not being caught during the review process and by the automated tests. Therefore, we internally use this channel to double-check everything before each release.
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Features that are only available on the nightly release channel are marked with an alert in the documentation.
|
Features that are only available on the nightly release channel are marked with an alert in the documentation.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
The `latest` nightly release channel is currently tracking the Nuxt v4 branch, meaning that it is particularly likely to have breaking changes right now - be careful!
|
||||||
|
|
||||||
|
You can opt in to the 3.x branch nightly releases with `"nuxt": "npm:nuxt-nightly@3x"`.
|
||||||
|
::
|
||||||
|
|
||||||
## Opting In
|
## Opting In
|
||||||
|
|
||||||
Update `nuxt` dependency inside `package.json`:
|
Update `nuxt` dependency inside `package.json`:
|
||||||
@ -47,7 +53,7 @@ Remove lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, or `bun.loc
|
|||||||
|
|
||||||
## Using Nightly `nuxi`
|
## Using Nightly `nuxi`
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
All cli dependencies are bundled because of the building method for reducing `nuxi` package size. :br You can get dependency updates and CLI improvements using the nightly release channel.
|
All cli dependencies are bundled because of the building method for reducing `nuxi` package size. :br You can get dependency updates and CLI improvements using the nightly release channel.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ title: "Lifecycle Hooks"
|
|||||||
description: "Nuxt provides a powerful hooking system to expand almost every aspect using hooks."
|
description: "Nuxt provides a powerful hooking system to expand almost every aspect using hooks."
|
||||||
---
|
---
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
The hooking system is powered by [unjs/hookable](https://github.com/unjs/hookable).
|
The hooking system is powered by [unjs/hookable](https://github.com/unjs/hookable).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ declare module '#app' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'nitropack' {
|
declare module 'nitro/types' {
|
||||||
interface NitroRuntimeHooks {
|
interface NitroRuntimeHooks {
|
||||||
'your-nitro-hook': () => void;
|
'your-nitro-hook': () => void;
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,25 @@ With modules, you can encapsulate, properly test, and share custom solutions as
|
|||||||
|
|
||||||
We recommend you get started with Nuxt Modules using our [starter template](https://github.com/nuxt/starter/tree/module):
|
We recommend you get started with Nuxt Modules using our [starter template](https://github.com/nuxt/starter/tree/module):
|
||||||
|
|
||||||
```bash [Terminal]
|
::package-managers
|
||||||
|
|
||||||
|
```bash [npm]
|
||||||
npx nuxi init -t module my-module
|
npx nuxi init -t module my-module
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash [yarn]
|
||||||
|
yarn dlx nuxi init -t module my-module
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm dlx nuxi init -t module my-module
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [bun]
|
||||||
|
bun x nuxi init -t module my-module
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
This will create a `my-module` project with all the boilerplate necessary to develop and publish your module.
|
This will create a `my-module` project with all the boilerplate necessary to develop and publish your module.
|
||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
@ -30,6 +45,10 @@ This will create a `my-module` project with all the boilerplate necessary to dev
|
|||||||
|
|
||||||
Learn how to perform basic tasks with the module starter.
|
Learn how to perform basic tasks with the module starter.
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/navigating-the-official-starter-template?friend=nuxt" target="_blank"}
|
||||||
|
Watch Vue School video about Nuxt module starter template.
|
||||||
|
::
|
||||||
|
|
||||||
#### How to Develop
|
#### How to Develop
|
||||||
|
|
||||||
While your module source code lives inside the `src` directory, in most cases, to develop a module, you need a Nuxt application. That's what the `playground` directory is about. It's a Nuxt application you can tinker with that is already configured to run with your module.
|
While your module source code lives inside the `src` directory, in most cases, to develop a module, you need a Nuxt application. That's what the `playground` directory is about. It's a Nuxt application you can tinker with that is already configured to run with your module.
|
||||||
@ -39,7 +58,7 @@ You can interact with the playground like with any Nuxt application.
|
|||||||
- Launch its development server with `npm run dev`, it should reload itself as you make changes to your module in the `src` directory
|
- Launch its development server with `npm run dev`, it should reload itself as you make changes to your module in the `src` directory
|
||||||
- Build it with `npm run dev:build`
|
- Build it with `npm run dev:build`
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::note
|
||||||
All other `nuxi` commands can be used against the `playground` directory (e.g. `nuxi <COMMAND> playground`). Feel free to declare additional `dev:*` scripts within your `package.json` referencing them for convenience.
|
All other `nuxi` commands can be used against the `playground` directory (e.g. `nuxi <COMMAND> playground`). Feel free to declare additional `dev:*` scripts within your `package.json` referencing them for convenience.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -50,7 +69,7 @@ The module starter comes with a basic test suite:
|
|||||||
- A linter powered by [ESLint](https://eslint.org), run it with `npm run lint`
|
- A linter powered by [ESLint](https://eslint.org), run it with `npm run lint`
|
||||||
- A test runner powered by [Vitest](https://vitest.dev), run it with `npm run test` or `npm run test:watch`
|
- A test runner powered by [Vitest](https://vitest.dev), run it with `npm run test` or `npm run test:watch`
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
Feel free to augment this default test strategy to better suit your needs.
|
Feel free to augment this default test strategy to better suit your needs.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -60,19 +79,19 @@ Nuxt Modules come with their own builder provided by [`@nuxt/module-builder`](ht
|
|||||||
|
|
||||||
You can build your module by running `npm run prepack`.
|
You can build your module by running `npm run prepack`.
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
While building your module can be useful in some cases, most of the time you won't need to build it on your own: the `playground` takes care of it while developing, and the release script also has you covered when publishing.
|
While building your module can be useful in some cases, most of the time you won't need to build it on your own: the `playground` takes care of it while developing, and the release script also has you covered when publishing.
|
||||||
::
|
::
|
||||||
|
|
||||||
#### How to Publish
|
#### How to Publish
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Before publishing your module to npm, makes sure you have an [npmjs.com](https://www.npmjs.com) account and that you're authenticated to it locally with `npm login`.
|
Before publishing your module to npm, makes sure you have an [npmjs.com](https://www.npmjs.com) account and that you're authenticated to it locally with `npm login`.
|
||||||
::
|
::
|
||||||
|
|
||||||
While you can publish your module by bumping its version and using the `npm publish` command, the module starter comes with a release script that helps you make sure you publish a working version of your module to npm and more.
|
While you can publish your module by bumping its version and using the `npm publish` command, the module starter comes with a release script that helps you make sure you publish a working version of your module to npm and more.
|
||||||
|
|
||||||
To use the release script, first, commit all your changes (we recommend you follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) to also take advantage of automatic version bump and changelog update), then run the release script with `npm run release`.
|
To use the release script, first, commit all your changes (we recommend you follow [Conventional Commits](https://www.conventionalcommits.org) to also take advantage of automatic version bump and changelog update), then run the release script with `npm run release`.
|
||||||
|
|
||||||
When running the release script, the following will happen:
|
When running the release script, the following will happen:
|
||||||
|
|
||||||
@ -85,7 +104,7 @@ When running the release script, the following will happen:
|
|||||||
- Publishing the module to npm (for that purpose, the module will be built again to ensure its updated version number is taken into account in the published artifact)
|
- Publishing the module to npm (for that purpose, the module will be built again to ensure its updated version number is taken into account in the published artifact)
|
||||||
- Pushing a git tag representing the newly published version to your git remote origin
|
- Pushing a git tag representing the newly published version to your git remote origin
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
As with other scripts, feel free to fine-tune the default `release` script in your `package.json` to better suit your needs.
|
As with other scripts, feel free to fine-tune the default `release` script in your `package.json` to better suit your needs.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -104,7 +123,7 @@ In either case, their anatomy is similar.
|
|||||||
|
|
||||||
#### Module Definition
|
#### Module Definition
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
When using the starter, your module definition is available at `src/module.ts`.
|
When using the starter, your module definition is available at `src/module.ts`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -151,7 +170,7 @@ export default defineNuxtModule({
|
|||||||
// Compatibility constraints
|
// Compatibility constraints
|
||||||
compatibility: {
|
compatibility: {
|
||||||
// Semver version of supported nuxt versions
|
// Semver version of supported nuxt versions
|
||||||
nuxt: '^3.0.0'
|
nuxt: '>=3.0.0'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Default configuration options for your module, can also be a function returning those
|
// Default configuration options for your module, can also be a function returning those
|
||||||
@ -179,7 +198,7 @@ Ultimately `defineNuxtModule` returns a wrapper function with the lower level `(
|
|||||||
|
|
||||||
#### Runtime Directory
|
#### Runtime Directory
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
When using the starter, the runtime directory is available at `src/runtime`.
|
When using the starter, the runtime directory is available at `src/runtime`.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -203,15 +222,15 @@ Or any other kind of asset you want to inject in users' Nuxt applications:
|
|||||||
|
|
||||||
You'll then be able to inject all those assets inside the application from your [module definition](#module-definition).
|
You'll then be able to inject all those assets inside the application from your [module definition](#module-definition).
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
Learn more about asset injection in [the recipes section](#recipes).
|
Learn more about asset injection in [the recipes section](#recipes).
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Published modules cannot leverage auto-imports for assets within their runtime directory. Instead, they have to import them explicitly from `#imports` or alike.
|
Published modules cannot leverage auto-imports for assets within their runtime directory. Instead, they have to import them explicitly from `#imports` or alike.
|
||||||
|
:br :br
|
||||||
Indeed, auto-imports are not enabled for files within `node_modules` (the location where a published module will eventually live) for performance reasons.
|
Indeed, auto-imports are not enabled for files within `node_modules` (the location where a published module will eventually live) for performance reasons.
|
||||||
|
:br :br
|
||||||
If you are using the module starter, auto-imports will not be enabled in your playground either.
|
If you are using the module starter, auto-imports will not be enabled in your playground either.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -255,6 +274,10 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
When you need to handle more complex configuration alterations, you should consider using [defu](https://github.com/unjs/defu).
|
When you need to handle more complex configuration alterations, you should consider using [defu](https://github.com/unjs/defu).
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/extending-and-altering-nuxt-configuration-and-options?friend=nuxt" target="_blank"}
|
||||||
|
Watch Vue School video about altering Nuxt configuration.
|
||||||
|
::
|
||||||
|
|
||||||
#### Exposing Options to Runtime
|
#### Exposing Options to Runtime
|
||||||
|
|
||||||
Because modules aren't part of the application runtime, their options aren't either. However, in many cases, you might need access to some of these module options within your runtime code. We recommend exposing the needed config using Nuxt's [`runtimeConfig`](/docs/api/nuxt-config#runtimeconfig).
|
Because modules aren't part of the application runtime, their options aren't either. However, in many cases, you might need access to some of these module options within your runtime code. We recommend exposing the needed config using Nuxt's [`runtimeConfig`](/docs/api/nuxt-config#runtimeconfig).
|
||||||
@ -282,12 +305,16 @@ You can then access your module options in a plugin, component, the application
|
|||||||
const options = useRuntimeConfig().public.myModule
|
const options = useRuntimeConfig().public.myModule
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
Be careful not to expose any sensitive module configuration on the public runtime config, such as private API keys, as they will end up in the public bundle.
|
Be careful not to expose any sensitive module configuration on the public runtime config, such as private API keys, as they will end up in the public bundle.
|
||||||
::
|
::
|
||||||
|
|
||||||
:read-more{to="/docs/guide/going-further/runtime-config"}
|
:read-more{to="/docs/guide/going-further/runtime-config"}
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/passing-and-exposing-module-options?friend=nuxt" target="_blank"}
|
||||||
|
Watch Vue School video about passing and exposing Nuxt module options.
|
||||||
|
::
|
||||||
|
|
||||||
#### Injecting Plugins With `addPlugin`
|
#### Injecting Plugins With `addPlugin`
|
||||||
|
|
||||||
Plugins are a common way for a module to add runtime logic. You can use the `addPlugin` utility to register them from your module.
|
Plugins are a common way for a module to add runtime logic. You can use the `addPlugin` utility to register them from your module.
|
||||||
@ -511,9 +538,14 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
:read-more{to="/docs/api/advanced/hooks"}
|
:read-more{to="/docs/api/advanced/hooks"}
|
||||||
|
|
||||||
::callout
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/nuxt-lifecycle-hooks?friend=nuxt" target="_blank"}
|
||||||
**Module cleanup**
|
Watch Vue School video about using Nuxt lifecycle hooks in modules.
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
|
**Module cleanup**
|
||||||
|
:br
|
||||||
|
:br
|
||||||
If your module opens, handles, or starts a watcher, you should close it when the Nuxt lifecycle is done. The `close` hook is available for this.
|
If your module opens, handles, or starts a watcher, you should close it when the Nuxt lifecycle is done. The `close` hook is available for this.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@ -527,7 +559,6 @@ export default defineNuxtModule({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
#### Adding Templates/Virtual Files
|
#### Adding Templates/Virtual Files
|
||||||
@ -567,7 +598,7 @@ export default defineNuxtModule({
|
|||||||
interface MyModuleNitroRules {
|
interface MyModuleNitroRules {
|
||||||
myModule?: { foo: 'bar' }
|
myModule?: { foo: 'bar' }
|
||||||
}
|
}
|
||||||
declare module 'nitropack' {
|
declare module 'nitro/types' {
|
||||||
interface NitroRouteRules extends MyModuleNitroRules {}
|
interface NitroRouteRules extends MyModuleNitroRules {}
|
||||||
interface NitroRouteConfig extends MyModuleNitroRules {}
|
interface NitroRouteConfig extends MyModuleNitroRules {}
|
||||||
}
|
}
|
||||||
@ -605,9 +636,9 @@ Testing helps ensuring your module works as expected given various setup. Find i
|
|||||||
|
|
||||||
#### Unit and Integration
|
#### Unit and Integration
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
We're still discussing and exploring how to ease unit and integration testing on Nuxt Modules.
|
We're still discussing and exploring how to ease unit and integration testing on Nuxt Modules.
|
||||||
|
:br :br
|
||||||
[Check out this RFC to join the conversation](https://github.com/nuxt/nuxt/discussions/18399).
|
[Check out this RFC to join the conversation](https://github.com/nuxt/nuxt/discussions/18399).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -661,7 +692,7 @@ describe('ssr', async () => {
|
|||||||
describe('csr', async () => { /* ... */ })
|
describe('csr', async () => { /* ... */ })
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
An example of such a workflow is available on [the module starter](https://github.com/nuxt/starter/blob/module/test/basic.test.ts).
|
An example of such a workflow is available on [the module starter](https://github.com/nuxt/starter/blob/module/test/basic.test.ts).
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -683,7 +714,7 @@ As we've seen, Nuxt Modules can be asynchronous. For example, you may want to de
|
|||||||
|
|
||||||
However, be careful with asynchronous behaviors as Nuxt will wait for your module to setup before going to the next module and starting the development server, build process, etc. Prefer deferring time-consuming logic to Nuxt hooks.
|
However, be careful with asynchronous behaviors as Nuxt will wait for your module to setup before going to the next module and starting the development server, build process, etc. Prefer deferring time-consuming logic to Nuxt hooks.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::warning
|
||||||
If your module takes more than **1 second** to setup, Nuxt will emit a warning about it.
|
If your module takes more than **1 second** to setup, Nuxt will emit a warning about it.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -733,6 +764,10 @@ The module starter comes with a default set of tools and configurations (e.g. ES
|
|||||||
|
|
||||||
[Nuxt Module ecosystem](/modules) represents more than 15 million monthly NPM downloads and provides extended functionalities and integrations with all sort of tools. You can be part of this ecosystem!
|
[Nuxt Module ecosystem](/modules) represents more than 15 million monthly NPM downloads and provides extended functionalities and integrations with all sort of tools. You can be part of this ecosystem!
|
||||||
|
|
||||||
|
::tip{icon="i-ph-video" to="https://vueschool.io/lessons/exploring-nuxt-modules-ecosystem-and-module-types?friend=nuxt" target="_blank"}
|
||||||
|
Watch Vue School video about Nuxt module types.
|
||||||
|
::
|
||||||
|
|
||||||
### Module Types
|
### Module Types
|
||||||
|
|
||||||
**Official modules** are modules prefixed (scoped) with `@nuxt/` (e.g. [`@nuxt/content`](https://content.nuxtjs.org)). They are made and maintained actively by the Nuxt team. Like with the framework, contributions from the community are more than welcome to help make them better!
|
**Official modules** are modules prefixed (scoped) with `@nuxt/` (e.g. [`@nuxt/content`](https://content.nuxtjs.org)). They are made and maintained actively by the Nuxt team. Like with the framework, contributions from the community are more than welcome to help make them better!
|
||||||
|
@ -15,6 +15,10 @@ Discover all Nuxt Kit utilities.
|
|||||||
|
|
||||||
You can install the latest Nuxt Kit by adding it to the `dependencies` section of your `package.json`. However, please consider always explicitly installing the `@nuxt/kit` package even if it is already installed by Nuxt.
|
You can install the latest Nuxt Kit by adding it to the `dependencies` section of your `package.json`. However, please consider always explicitly installing the `@nuxt/kit` package even if it is already installed by Nuxt.
|
||||||
|
|
||||||
|
::note
|
||||||
|
`@nuxt/kit` and `@nuxt/schema` are key dependencies for Nuxt. If you are installing it separately, make sure that the versions of `@nuxt/kit` and `@nuxt/schema` are equal to or greater than your `nuxt` version to avoid any unexpected behavior.
|
||||||
|
::
|
||||||
|
|
||||||
```json [package.json]
|
```json [package.json]
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -31,7 +35,7 @@ import { useNuxt } from '@nuxt/kit'
|
|||||||
|
|
||||||
:read-more{to="/docs/api/kit"}
|
:read-more{to="/docs/api/kit"}
|
||||||
|
|
||||||
::callout
|
::note
|
||||||
Nuxt Kit utilities are only available for modules and not meant to be imported in runtime (components, Vue composables, pages, plugins, or server routes).
|
Nuxt Kit utilities are only available for modules and not meant to be imported in runtime (components, Vue composables, pages, plugins, or server routes).
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -96,11 +96,15 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::tip
|
||||||
If you want to extend a private remote source, you need to add the environment variable `GIGET_AUTH=<token>` to provide a token.
|
If you want to extend a private remote source, you need to add the environment variable `GIGET_AUTH=<token>` to provide a token.
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{color="blue" icon="i-ph-info-duotone"}
|
::tip
|
||||||
|
If you want to extend a remote source from a self-hosted GitHub or GitLab instance, you need to supply its URL with the `GIGET_GITHUB_URL=<url>` or `GIGET_GITLAB_URL=<url>` environment variable - or directly configure it with [the `auth` option](https://github.com/unjs/c12#extending-config-layer-from-remote-sources) in your `nuxt.config`.
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
When using git remote sources, if a layer has npm dependencies and you wish to install them, you can do so by specifying `install: true` in your layer options.
|
When using git remote sources, if a layer has npm dependencies and you wish to install them, you can do so by specifying `install: true` in your layer options.
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
@ -144,13 +148,13 @@ To publish a layer directory as an npm package, you want to make sure that the `
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
::callout
|
::important
|
||||||
Make sure any dependency imported in the layer is **explicitly added** to the `dependencies`. The `nuxt` dependency, and anything only used for testing the layer before publishing, should remain in the `devDependencies` field.
|
Make sure any dependency imported in the layer is **explicitly added** to the `dependencies`. The `nuxt` dependency, and anything only used for testing the layer before publishing, should remain in the `devDependencies` field.
|
||||||
::
|
::
|
||||||
|
|
||||||
Now you can proceed to publish the module to npm, either publicly or privately.
|
Now you can proceed to publish the module to npm, either publicly or privately.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
When publishing the layer as a private npm package, you need to make sure you log in, to authenticate with npm to download the node module.
|
When publishing the layer as a private npm package, you need to make sure you log in, to authenticate with npm to download the node module.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ nuxi dev --inspect
|
|||||||
```
|
```
|
||||||
This will start Nuxt in `dev` mode with debugger active. If everything is working correctly a Node.js icon will appear on your Chrome DevTools and you can attach to the debugger.
|
This will start Nuxt in `dev` mode with debugger active. If everything is working correctly a Node.js icon will appear on your Chrome DevTools and you can attach to the debugger.
|
||||||
|
|
||||||
::callout{color="amber" icon="i-ph-warning-duotone"}
|
::important
|
||||||
Note that the Node.js and Chrome processes need to be run on the same platform. This doesn't work inside of Docker.
|
Note that the Node.js and Chrome processes need to be run on the same platform. This doesn't work inside of Docker.
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -38,6 +38,10 @@ It is possible to debug your Nuxt app in your IDE while you are developing it.
|
|||||||
|
|
||||||
You may need to update the config below with a path to your web browser. For more information, visit the [VS Code documentation about debug configuration](https://go.microsoft.com/fwlink/?linkid=830387).
|
You may need to update the config below with a path to your web browser. For more information, visit the [VS Code documentation about debug configuration](https://go.microsoft.com/fwlink/?linkid=830387).
|
||||||
|
|
||||||
|
::important
|
||||||
|
If you use `pnpm`, you will need to have `nuxi` installed as a devDependency for the configuration below to work.
|
||||||
|
::
|
||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
title: Going Further
|
title: Going Further
|
||||||
titleTemplate: '%s · Nuxt Advanced'
|
titleTemplate: '%s · Nuxt Advanced'
|
||||||
icon: i-ph-star-duotone
|
icon: i-ph-star
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user