Merge remote-tracking branch 'origin/main' into feat/named_export_components

This commit is contained in:
Julien Huang 2024-09-24 22:39:28 +02:00
commit 8dde59fa7a
470 changed files with 14280 additions and 11845 deletions

View File

@ -1,4 +1,4 @@
FROM node:lts FROM node:lts@sha256:48db4f6ea21d134be744207225753a1730c4bc1b4cdf836d44511c36bf0e34d7
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 && \

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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

10
.github/codeql/codeql-config.yml vendored Normal file
View File

@ -0,0 +1,10 @@
paths:
- 'packages/*/dist/**'
- 'packages/nuxt/bin/**'
- 'packages/schema/schema/**'
paths-ignore:
- 'test/**'
- '**/*.test.js'
- '**/*.test.ts'
- '**/*.test.tsx'
- '**/__tests__/**'

View File

@ -17,9 +17,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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

View File

@ -13,9 +13,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -52,4 +52,4 @@ jobs:
- name: Lint (code) - name: Lint (code)
run: pnpm lint:fix run: pnpm lint:fix
- uses: autofix-ci/action@ea32e3a12414e6d3183163c3424a7d7a8631ad84 - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c

View File

@ -29,9 +29,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -46,7 +46,7 @@ jobs:
run: pnpm build run: pnpm build
- name: Run benchmarks - name: Run benchmarks
uses: CodSpeedHQ/action@0b631f8998f2389eb5144632b6f9f8fabd33a86e # v2.4.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 }}

View File

@ -6,6 +6,8 @@ on:
types: types:
- closed - closed
permissions: {}
jobs: jobs:
cleanup: cleanup:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -20,14 +22,14 @@ jobs:
gh extension install actions/gh-actions-cache gh extension install actions/gh-actions-cache
echo "Fetching list of cache keys" echo "Fetching list of cache keys"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 ) 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. ## Setting this to not fail the workflow while deleting cache keys.
set +e set +e
echo "Deleting caches..." echo "Deleting caches..."
for cacheKey in $cacheKeysForPR for cacheKey in $cacheKeysForPR
do do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm gh actions-cache delete "$cacheKey" -R "$REPO" -B "$BRANCH" --confirm
done done
echo "Done" echo "Done"
env: env:

View File

@ -4,11 +4,9 @@ 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 }}
@ -16,15 +14,19 @@ concurrency:
jobs: jobs:
update: 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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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"

View File

@ -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
@ -35,9 +37,9 @@ jobs:
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -55,7 +57,7 @@ jobs:
run: pnpm build run: pnpm build
- name: Cache dist - name: Cache dist
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with: with:
retention-days: 3 retention-days: 3
name: dist name: dist
@ -68,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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
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@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: dist
path: packages
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
with: with:
category: "/language:javascript" category: "/language:javascript-typescript"
typecheck: typecheck:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -111,9 +107,9 @@ jobs:
module: ["bundler", "node"] module: ["bundler", "node"]
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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,7 +118,7 @@ jobs:
run: pnpm install run: pnpm install
- name: Restore dist cache - name: Restore dist cache
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with: with:
name: dist name: dist
path: packages path: packages
@ -142,9 +138,9 @@ jobs:
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -166,9 +162,9 @@ jobs:
needs: needs:
- build - build
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -198,7 +194,6 @@ jobs:
builder: ["vite", "webpack"] builder: ["vite", "webpack"]
context: ["async", "default"] context: ["async", "default"]
manifest: ["manifest-on", "manifest-off"] manifest: ["manifest-on", "manifest-off"]
version: ["v4", "v3"]
payload: ["json", "js"] payload: ["json", "js"]
node: [18] node: [18]
exclude: exclude:
@ -218,9 +213,9 @@ jobs:
timeout-minutes: 15 timeout-minutes: 15
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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"
@ -232,7 +227,7 @@ jobs:
run: pnpm playwright-core install chromium run: pnpm playwright-core install chromium
- name: Restore dist cache - name: Restore dist cache
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with: with:
name: dist name: dist
path: packages path: packages
@ -244,16 +239,17 @@ 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 }}
TEST_V4: ${{ matrix.version == 'v4' }}
TEST_PAYLOAD: ${{ matrix.payload }} 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' }} 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@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 - uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.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: |
@ -270,11 +266,11 @@ jobs:
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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"
@ -283,18 +279,20 @@ jobs:
run: pnpm install run: pnpm install
- name: Restore dist cache - name: Restore dist cache
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 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
@ -309,11 +307,11 @@ jobs:
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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"
@ -322,7 +320,7 @@ jobs:
run: pnpm install run: pnpm install
- name: Restore dist cache - name: Restore dist cache
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with: with:
name: dist name: dist
path: packages path: packages

View File

@ -17,6 +17,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Checkout Repository' - name: 'Checkout Repository'
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: 'Dependency Review' - name: 'Dependency Review'
uses: actions/dependency-review-action@0c155c5e8556a497adf53f2c18edabf945ed8e70 # v4.3.2 uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4

View File

@ -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
@ -25,10 +26,10 @@ jobs:
restore-keys: cache-lychee- restore-keys: cache-lychee-
# check links with Lychee # check links with Lychee
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Lychee link checker - name: Lychee link checker
uses: lycheeverse/lychee-action@25a231001d1723960a301b7d4c82884dc7ef857d # for v1.8.0 uses: lycheeverse/lychee-action@5047c2a4052946424ce139fe111135f6d7c0fe0b # for v1.8.0
with: with:
# arguments with file types to check # arguments with file types to check
args: >- args: >-

View File

@ -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

View File

@ -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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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
View 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']
})
}

View File

@ -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
View 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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

View File

@ -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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
# 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.2@sha256:89d3f90f82781dee3c8724651129634b08cf2241bbd67fcd02a1c5198119fc5e
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/590d3bd9dde0c91f7a66071d40eb84716526e5a6/scripts/download-actionlint.bash) 1.6.25 with:
./actionlint -color -shellcheck="" args: -color

View File

@ -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

View File

@ -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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
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

View File

@ -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
@ -29,13 +31,30 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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"

View File

@ -11,17 +11,19 @@ permissions: {}
jobs: jobs:
release: release:
if: github.repository == 'nuxt/nuxt' && startsWith(github.event.head_commit.message, 'v3.') if: github.repository == 'nuxt/nuxt' && (startsWith(github.event.head_commit.message, 'v3.') || startsWith(github.event.head_commit.message, 'v4.'))
concurrency:
group: release
permissions: permissions:
id-token: write id-token: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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
registry-url: "https://registry.npmjs.org/" registry-url: "https://registry.npmjs.org/"

View File

@ -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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp - uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp
with: with:
label: needs reproduction label: needs reproduction

View File

@ -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
@ -32,12 +32,12 @@ jobs:
steps: steps:
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with: with:
persist-credentials: false persist-credentials: false
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
@ -59,7 +59,7 @@ 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@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
if: github.repository == 'nuxt/nuxt' && success() if: github.repository == 'nuxt/nuxt' && success()
with: with:
name: SARIF file name: SARIF file
@ -68,7 +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@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
if: github.repository == 'nuxt/nuxt' && success() if: github.repository == 'nuxt/nuxt' && success()
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@ -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,7 +20,7 @@ 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@cfb60706e18bc85e8aec535e3c577abe8f70378e # v5.5.2 uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
with: with:
scopes: | scopes: |
kit kit

17
.github/workflows/stackblitz-link.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: chore
on:
issues:
types:
opened
permissions:
issues: write
jobs:
stackblitz:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: huang-julien/reproduire-sur-stackblitz@9ceccbfbb0f2f9a9a8db2d1f0dd909cf5cfe67aa # v1.0.2
with:
reproduction-heading: '### Reproduction'

View File

@ -1,4 +1,4 @@
name: Close incomplete issues name: chore
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:

4
.npmrc
View File

@ -1,2 +1,4 @@
shamefully-hoist=true # TODO: consider resolving webpack loaders to absolute path
public-hoist-pattern[]=*-loader
public-hoist-pattern[]=webpack-*
shell-emulator=true shell-emulator=true

1
CODEOWNERS Normal file
View File

@ -0,0 +1 @@
* @danielroe

View File

@ -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>
@ -34,7 +34,7 @@ It provides a number of features that make it easy to build fast, SEO-friendly,
- 🏠 [Local Development](#local-development) - 🏠 [Local Development](#local-development)
- ⛰️ [Nuxt 2](#nuxt-2) - ⛰️ [Nuxt 2](#nuxt-2)
- 🛟 [Professional Support](#professional-support) - 🛟 [Professional Support](#professional-support)
- 🔗 [Follow us](#follow-us) - 🔗 [Follow Us](#follow-us)
- ⚖️ [License](#license) - ⚖️ [License](#license)
--- ---
@ -101,23 +101,17 @@ Here are a few ways you can get involved:
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.
## <a name="nuxt-2">⛰️ Nuxt 2</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).
If you expect to be using Nuxt 2 beyond the EOL (End of Life) date (June 30, 2024), and still need a maintained version that can satisfy security and browser compatibility requirements, make sure to check out [HeroDevs NES (Never-Ending Support) Nuxt 2](https://www.herodevs.com/support/nuxt-nes?utm_source=nuxt-github&utm_medium=nuxt-readme).
## <a name="professional-support">🛟 Professional Support</a> ## <a name="professional-support">🛟 Professional Support</a>
- Technical audit & consulting: [Nuxt Experts](https://nuxt.com/enterprise/support) - Technical audit & consulting: [Nuxt Experts](https://nuxt.com/enterprise/support)
- Custom development & more: [Nuxt Agencies Partners](https://nuxt.com/enterprise/agencies) - Custom development & more: [Nuxt Agencies Partners](https://nuxt.com/enterprise/agencies)
## <a name="follow-us">🔗 Follow us</a> ## <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>&nbsp;&nbsp;<a href="https://twitter.nuxt.dev"><img width="20px" src="./.github/assets/twitter.svg" alt="Twitter"></a>&nbsp;&nbsp;<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>&nbsp;&nbsp;<a href="https://go.nuxt.com/x"><img width="20px" src="./.github/assets/twitter.svg" alt="Twitter"></a>&nbsp;&nbsp;<a href="https://go.nuxt.com/github"><img width="20px" src="./.github/assets/github.svg" alt="GitHub"></a>
</p> </p>
## <a name="license">⚖️ License</a> ## <a name="license">⚖️ License</a>
[MIT](./LICENSE) [MIT](https://github.com/nuxt/nuxt/tree/main/LICENSE)

View File

@ -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).
@ -76,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.

View File

@ -1,7 +1,7 @@
--- ---
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.
@ -71,62 +71,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 +85,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 +117,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.
::

View File

@ -1,7 +1,7 @@
--- ---
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
--- ---
::tip ::tip
@ -10,7 +10,7 @@ If you are a module author, you can find more specific information in the [Modul
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-duotone" to="https://www.youtube.com/watch?v=yGzwk9xi9gU" target="_blank"} ::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`. Watch a video from Alexander Lichter about getting started with the `@nuxt/test-utils`.
:: ::
@ -22,13 +22,13 @@ In order to allow you to manage your other testing dependencies, `@nuxt/test-uti
- you can choose between `vitest`, `cucumber`, `jest` and `playwright` 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 (and are not using `@playwright/test` as your test runner) - `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
``` ```
@ -161,7 +161,13 @@ 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 { it, expect } from 'vitest' import { it, expect } from 'vitest'
@ -207,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>`.
@ -266,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.
@ -412,13 +421,13 @@ If you prefer to use `@vue/test-utils` on its own for unit testing in Nuxt, and
1. Install the needed dependencies 1. Install the needed dependencies
::code-group ::package-managers
```bash [yarn]
yarn add --dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
```
```bash [npm] ```bash [npm]
npm i --save-dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue 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] ```bash [pnpm]
pnpm add -D vitest @vue/test-utils happy-dom @vitejs/plugin-vue pnpm add -D vitest @vue/test-utils happy-dom @vitejs/plugin-vue
``` ```
@ -478,13 +487,13 @@ If you prefer to use `@vue/test-utils` on its own for unit testing in Nuxt, and
6. Run vitest command 6. Run vitest command
::code-group ::package-managers
```bash [yarn]
yarn test
```
```bash [npm] ```bash [npm]
npm run test npm run test
``` ```
```bash [yarn]
yarn test
```
```bash [pnpm] ```bash [pnpm]
pnpm run test pnpm run test
``` ```
@ -544,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`
@ -566,6 +580,31 @@ Please use the options below for the `setup` method.
- Type: `'vitest' | 'jest' | 'cucumber'` - 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)`
@ -619,13 +658,13 @@ const page = await createPage('/page')
We also provide first-class support for testing Nuxt within [the Playwright test runner](https://playwright.dev/docs/intro). We also provide first-class support for testing Nuxt within [the Playwright test runner](https://playwright.dev/docs/intro).
::code-group ::package-managers
```bash [yarn]
yarn add --dev @playwright/test @nuxt/test-utils
```
```bash [npm] ```bash [npm]
npm i --save-dev @playwright/test @nuxt/test-utils npm i --save-dev @playwright/test @nuxt/test-utils
``` ```
```bash [yarn]
yarn add --dev @playwright/test @nuxt/test-utils
```
```bash [pnpm] ```bash [pnpm]
pnpm add -D @playwright/test @nuxt/test-utils pnpm add -D @playwright/test @nuxt/test-utils
``` ```

View File

@ -1,7 +1,7 @@
--- ---
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
--- ---
@ -11,27 +11,49 @@ navigation.icon: i-ph-arrow-circle-up-duotone
To upgrade Nuxt 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 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.
::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 ## Testing Nuxt 4
Nuxt 4 is planned to be released **on or before June 14** (though obviously this is dependent on having enough time after Nitro's major release to be properly tested in the community, so be aware that this is not an exact date). Nuxt 4 is planned to be released **on or before June 14** (though obviously this is dependent on having enough time after Nitro's major release to be properly tested in the community, so be aware that this is not an exact date).
Until then, it is possible to test many of Nuxt 4's breaking changes on the nightly release channel. Until then, it is possible to test many of Nuxt 4's breaking changes from Nuxt version 3.12+.
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=r4wFKlcJK6c" target="_blank"} ::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. Watch a video from Alexander Lichter showing how to opt in to Nuxt 4's breaking changes already.
:: ::
### Opting in to Nuxt 4 ### Opting in to Nuxt 4
First, opt in to the nightly release channel [following these steps](/docs/guide/going-further/nightly-release-channel#opting-in). First, upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases).
Then you can set your `compatibilityVersion` to match Nuxt 4 behavior: Then you can set your `compatibilityVersion` to match Nuxt 4 behavior:
@ -75,6 +97,24 @@ Breaking or significant changes will be noted here along with migration steps fo
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`. 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 #### New Directory Structure
🚦 **Impact Level**: Significant 🚦 **Impact Level**: Significant
@ -87,7 +127,8 @@ Nuxt now defaults to a new directory structure, with backwards compatibility (so
* the new Nuxt default `srcDir` is `app/` by default, and most things are resolved from there. * 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` * `serverDir` now defaults to `<rootDir>/server` rather than `<srcDir>/server`
* `modules` and `public` are resolved relative to `<rootDir>` by default * `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>/` * 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> <details>
@ -109,6 +150,8 @@ app/
app.config.ts app.config.ts
app.vue app.vue
router.options.ts router.options.ts
content/
layers/
modules/ modules/
node_modules/ node_modules/
public/ public/
@ -134,9 +177,15 @@ nuxt.config.ts
1. Create a new directory called `app/`. 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. 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`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project. 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.
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.) You can also force a v3 folder structure with the following configuration: ::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] ```ts [nuxt.config.ts]
export default defineNuxtConfig({ export default defineNuxtConfig({
@ -204,9 +253,16 @@ Previously `data` was initialized to `null` but reset in `clearNuxtData` to `und
##### Migration Steps ##### 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: If you encounter any issues you can revert back to the previous behavior with:
```ts twoslash [nuxt.config.ts] ```ts twoslash [nuxt.config.ts]
// @errors: 2353
export default defineNuxtConfig({ export default defineNuxtConfig({
experimental: { experimental: {
defaults: { defaults: {
@ -221,6 +277,51 @@ export default defineNuxtConfig({
Please report an issue if you are doing this, as we do not plan to keep this as configurable. 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` #### Respect defaults when clearing `data` in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Minimal 🚦 **Impact Level**: Minimal
@ -238,6 +339,7 @@ Often users set an appropriately empty value, such as an empty array, to avoid t
If you encounter any issues you can revert back to the previous behavior, for now, with: If you encounter any issues you can revert back to the previous behavior, for now, with:
```ts twoslash [nuxt.config.ts] ```ts twoslash [nuxt.config.ts]
// @errors: 2353
export default defineNuxtConfig({ export default defineNuxtConfig({
experimental: { experimental: {
resetAsyncDataToUndefined: true, resetAsyncDataToUndefined: true,
@ -283,6 +385,10 @@ In most cases, no migration steps are required, but if you rely on the reactivit
}) })
``` ```
::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` #### Absolute Watch Paths in `builder:watch`
🚦 **Impact Level**: Minimal 🚦 **Impact Level**: Minimal
@ -310,6 +416,29 @@ However, if you are a module author using the `builder:watch` hook and wishing t
}) })
``` ```
::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 #### Directory index scanning
🚦 **Impact Level**: Medium 🚦 **Impact Level**: Medium
@ -398,6 +527,10 @@ const importSources = (sources: string | string[], { lazy = false } = {}) => {
const importName = genSafeVariableName const importName = genSafeVariableName
``` ```
::tip
You can automate this step by running `npx codemod@latest nuxt/4/template-compilation-changes`
::
#### Removal of Experimental Features #### Removal of Experimental Features
🚦 **Impact Level**: Minimal 🚦 **Impact Level**: Minimal
@ -406,10 +539,11 @@ const importName = genSafeVariableName
Four experimental features are no longer configurable in Nuxt 4: Four experimental features are no longer configurable in Nuxt 4:
* `treeshakeClientOnly` will be `true` (default since v3.0) * `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
* `configSchema` will be `true` (default since v3.3) * `experimental.configSchema` will be `true` (default since v3.3)
* `polyfillVueUseHead` will be `false` (default since v3.4) * `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
* `respectNoSSRHeader` 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 ##### Reasons for Change
@ -421,11 +555,11 @@ These options have been set to their current values for some time and we do not
* `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) * `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 ## 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 | 😊 Stable | 😊 Stable Stability | 😊 Stable | 😊 Stable | 😊 Stable
@ -443,9 +577,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**.
@ -453,7 +587,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**

View File

@ -1,7 +1,7 @@
--- ---
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
@ -35,12 +35,16 @@ Or follow the steps below to set up a new Nuxt project on your computer.
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>
``` ```
@ -71,16 +75,16 @@ cd <project-name>
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
``` ```
@ -90,12 +94,12 @@ bun run dev -o
``` ```
:: ::
::tip{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"}

View File

@ -1,7 +1,7 @@
--- ---
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
--- ---
@ -29,7 +29,7 @@ Every option is described in the **Configuration Reference**.
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 +46,7 @@ export default defineNuxtConfig({
}) })
``` ```
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=DFZI2iVCrNc" target="_blank"} ::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`. Watch a video from Alexander Lichter about the env-aware `nuxt.config.ts`.
:: ::

View File

@ -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`

View File

@ -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.

View File

@ -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.
@ -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]
@ -411,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': {}
} }
} }
}) })

View File

@ -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.

View File

@ -1,7 +1,7 @@
--- ---
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
@ -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]

View File

@ -1,7 +1,7 @@
--- ---
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
--- ---
::note ::note
@ -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>
@ -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.

View File

@ -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`.
@ -54,7 +54,7 @@ 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-duotone" to="https://www.youtube.com/watch?v=njsGVmcWviY" target="_blank"} ::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! Watch the video from Alexander Lichter to avoid using `useFetch` the wrong way!
:: ::
@ -97,7 +97,7 @@ The `useAsyncData` composable is responsible for wrapping async logic and return
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-duotone" to="https://www.youtube.com/watch?v=0X-aOpSGabA" target="_blank"} ::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`. Watch a video from Alexander Lichter to dig deeper into the difference between `useFetch` and `useAsyncData`.
:: ::
@ -134,7 +134,7 @@ The `useAsyncData` composable is a great way to wrap and wait for multiple `$fet
```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')
@ -156,14 +156,13 @@ 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 `pending` to `false`, set `status` to `idle`, and mark any currently pending requests as cancelled. - `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"`).
::note ::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.
@ -178,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 Vues 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 Vues 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>
@ -204,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>
``` ```
@ -227,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
}) })
@ -292,7 +291,7 @@ 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>
``` ```
@ -355,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
} }
@ -371,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>
@ -406,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>
@ -416,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>
@ -465,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)
@ -494,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>
@ -623,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)
}
```

View File

@ -1,14 +1,14 @@
--- ---
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.
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=mv0WcBABcIk" target="_blank"} ::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()`. Watch a video from Alexander Lichter about why and when to use `useState()`.
:: ::
@ -24,10 +24,10 @@ Read more about `useState` composable.
::warning ::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.
:: ::
::tip{icon="i-ph-check-circle-duotone"} ::tip{icon="i-ph-check-circle"}
Instead use `const useX = () => useState('x')` Instead use `const useX = () => useState('x')`
:: ::
@ -212,7 +212,7 @@ const color = useColor() // Same as useState('color')
</template> </template>
``` ```
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=dZSNW07sO-A" target="_blank"} ::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. Watch a video from Daniel Roe on how to deal with global state and SSR in Nuxt.
:: ::

View File

@ -1,10 +1,10 @@
--- ---
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)
- Server and client startup errors (SSR + CSR) - Server and client startup errors (SSR + CSR)
@ -55,7 +55,7 @@ This includes:
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.
@ -125,6 +125,10 @@ When you are ready to remove the error page, you can call the [`clearError`](/do
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.
:: ::
::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 ::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).

View File

@ -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,7 +20,7 @@ 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-duotone" to="https://www.youtube.com/watch?v=DkvgJa-X31k" target="_blank"} ::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. Watch a video from Alexander Lichter to understand the responsibilities of Nuxt and Nitro in your application.
:: ::

View File

@ -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
@ -18,7 +18,13 @@ One of the core features of Nuxt 3 is the layers and extending support. You can
## 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
::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] ```ts [nuxt.config.ts]
export default defineNuxtConfig({ export default defineNuxtConfig({
@ -47,11 +53,11 @@ Nuxt uses [unjs/c12](https://c12.unjs.io) and [unjs/giget](https://giget.unjs.io
Read more about layers in the **Layer Author Guide**. Read more about layers in the **Layer Author Guide**.
:: ::
::tip{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 a video from Learn Vue about Nuxt Layers. Watch a video from Learn Vue about Nuxt Layers.
:: ::
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=fr5yo3aVkfA" target="_blank"} ::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=fr5yo3aVkfA" target="_blank"}
Watch a video from Alexander Lichter about Nuxt Layers. Watch a video from Alexander Lichter about Nuxt Layers.
:: ::

View 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;
}
},
},
},
});
```

View File

@ -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

View File

@ -7,16 +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-duotone" title="Recipes" to="/docs/guide/recipes"} ::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. Find solutions to common problems and learn how to implement them in your Nuxt project.
:: ::
:: ::

View File

@ -34,7 +34,7 @@ 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 */ /* useAsyncData() and $fetch() are auto-imported */
const { data, refresh, pending } = await useFetch('/api/hello') const { data, refresh, status } = await useFetch('/api/hello')
</script> </script>
``` ```
@ -60,11 +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.
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=ofuKRZLtOdY" target="_blank"} ::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. Watch a video from Alexander Lichter about handling async code in composables and fixing `Nuxt instance is unavailable` in your app.
:: ::
::read-more{to="/docs/guide/going-further/experimental-features#asynccontext" icon="i-ph-star-duotone"} ::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.
:: ::
@ -105,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:
@ -173,6 +182,6 @@ export default defineNuxtConfig({
}) })
``` ```
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=FT2LQJ2NvVI" target="_blank"} ::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. Watch a video from Alexander Lichter on how to easily set up custom auto imports.
:: ::

View File

@ -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 doesnt 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 doesnt 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
:: ::

View File

@ -69,13 +69,43 @@ If you do use `ssr: false`, you should also place an HTML file in `~/app/spa-loa
: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,7 +136,7 @@ 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.
@ -138,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.
@ -173,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.
:: ::
:: ::

View File

@ -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.

View File

@ -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'

View File

@ -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,26 +9,22 @@ 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:
::alert{type="warning"} ::package-managers
You may experience issues with the latest `vue-tsc` and `vite-plugin-checker`, used internally when type checking. For now, you may need to stay on v1 of `vue-tsc`, and follow these upstream issues for updates: [fi3ework/vite-plugin-checker#306](https://github.com/fi3ework/vite-plugin-checker/issues/306) and [vuejs/language-tools#3969](https://github.com/vuejs/language-tools/issues/3969).
::
::code-group
```bash [yarn]
yarn add --dev vue-tsc@^1 typescript
```
```bash [npm] ```bash [npm]
npm install --save-dev vue-tsc@^1 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@^1 typescript pnpm add -D vue-tsc typescript
``` ```
```bash [bun] ```bash [bun]
bun add -D vue-tsc@^1 typescript bun add -D vue-tsc typescript
``` ```
:: ::
@ -55,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`.
@ -65,7 +61,7 @@ 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).
::tip{icon="i-ph-video-duotone" to="https://youtu.be/umLI7SlPygY" target="_blank"} ::tip{icon="i-ph-video" to="https://youtu.be/umLI7SlPygY" target="_blank"}
Watch a video from Daniel Roe explaining built-in Nuxt aliases. Watch a video from Daniel Roe explaining built-in Nuxt aliases.
:: ::
@ -84,7 +80,7 @@ In case you need to extend options provided by `./.nuxt/tsconfig.json` further,
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.
[Strict checks](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks) are enabled by default in Nuxt 3 to give you greater type safety. [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.
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`: 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`:

View File

@ -7,7 +7,7 @@ description: "Nuxt supports ESLint out of the box"
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. 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.
:::callout{icon="i-ph-lightbulb-duotone"} :::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/). 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/).
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. 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.

View File

@ -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

View File

@ -2,7 +2,7 @@
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
--- ---
::important ::important

View File

@ -2,7 +2,7 @@
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
--- ---
::important ::important

View File

@ -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:

View File

@ -2,7 +2,7 @@
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).
@ -166,6 +166,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 +202,6 @@ export default defineNuxtModule({
:: ::
::note
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.
@ -254,11 +254,11 @@ Server components allow server-rendering individual components within your clien
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).
::tip{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.
:: ::
::tip{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.
:: ::
@ -303,6 +303,10 @@ Server-only components use [`<NuxtIsland>`](/docs/api/components/nuxt-island) un
Server components (and islands) must have a single root element. (HTML comments are considered elements as well.) 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} ::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. Most features for server-only components and island components, such as slots and client components, are only available for single file components.
:: ::

View File

@ -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

View File

@ -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.

View File

@ -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
--- ---
::tip{icon="i-ph-rocket-launch-duotone" color="gray" } ::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.
:: ::

View File

@ -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.
@ -134,6 +134,10 @@ export default defineNuxtRouteMiddleware(to => {
}) })
``` ```
::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.

View File

@ -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.
@ -61,6 +61,6 @@ modules/
:read-more{to="/docs/guide/going-further/modules"} :read-more{to="/docs/guide/going-further/modules"}
::tip{icon="i-ph-video-duotone" to="https://vueschool.io/lessons/creating-your-first-module-from-scratch" target="_blank"} ::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. Watch Vue School video about Nuxt private modules.
:: ::

View File

@ -2,7 +2,7 @@
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.

View File

@ -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
--- ---
::note ::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/going-further/custom-routing#using-approuteroptions). 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
@ -226,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>`:
@ -342,7 +358,7 @@ 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.
::note ::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.
@ -381,7 +397,7 @@ Server-only pages must have a single root element. (HTML comments are considered
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

View File

@ -2,7 +2,7 @@
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.
@ -76,13 +76,14 @@ export default defineNuxtPlugin({
}) })
``` ```
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=2aXZyXB1QGQ" target="_blank"} ::tip{icon="i-ph-video" to="https://www.youtube.com/watch?v=2aXZyXB1QGQ" target="_blank"}
Watch a video from Alexander Lichter about the Object Syntax for Nuxt plugins. Watch a video from Alexander Lichter about the Object Syntax for Nuxt plugins.
:: ::
::note ::note
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 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. 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
@ -245,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
``` ```

View File

@ -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`).

View File

@ -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.
@ -347,6 +347,22 @@ 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

View File

@ -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.

View File

@ -2,7 +2,7 @@
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
--- ---
::important ::important
@ -33,6 +33,10 @@ 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`.
::important
In your application code, you should use [Runtime Config](/docs/guide/going-further/runtime-config) instead of plain env variables.
::
## Production ## 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.

View File

@ -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.

View File

@ -2,7 +2,7 @@
title: .nuxtignore title: .nuxtignore
head.title: '.nuxtignore' head.title: '.nuxtignore'
description: The .nuxtignore file lets Nuxt ignore files in your projects root directory during the build phase. description: The .nuxtignore file lets Nuxt ignore files in your projects 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 projects root directory ([`rootDir`](/docs/api/nuxt-config#rootdir)) during the build phase. The `.nuxtignore` file tells Nuxt to ignore files in your projects root directory ([`rootDir`](/docs/api/nuxt-config#rootdir)) during the build phase.

View 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.
@ -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).
::

View File

@ -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

View File

@ -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.

View File

@ -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`.

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -57,20 +57,6 @@ export default defineNuxtConfig({
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.
@ -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,7 +254,7 @@ 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-duotone" to="https://www.youtube.com/watch?v=SXk-L19gTZk" target="_blank"} ::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. Watch a video from Daniel Roe explaining type-safe routing in Nuxt.
:: ::
@ -344,7 +292,7 @@ export default defineNuxtConfig({
}) })
``` ```
::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=1jUupYHVvrU" target="_blank"} ::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. Watch a video from Alexander Lichter about the experimental `sharedPrerenderData` setting.
:: ::
@ -386,7 +334,7 @@ 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. You can disable this feature if it causes issues in your project.
```ts twoslash [nuxt.config.ts] ```ts twoslash [nuxt.config.ts]
export default defineNuxtConfig({ export default defineNuxtConfig({
@ -394,7 +342,7 @@ export default defineNuxtConfig({
scanPageMeta: false scanPageMeta: false
} }
}) })
``` --> ```
## cookieStore ## cookieStore
@ -411,3 +359,34 @@ 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.
::

View File

@ -40,7 +40,7 @@ There is also a `future` namespace for early opting-in to new features that will
### compatibilityVersion ### compatibilityVersion
::important ::important
This configuration option is available in Nuxt v3.12+ or in [the nightly release channel](/docs/guide/going-further/nightly-release-channel). This configuration option is available in Nuxt v3.12+.
:: ::
This enables early access to Nuxt features or flags. This enables early access to Nuxt features or flags.

View File

@ -61,7 +61,7 @@ Setting the default of `runtimeConfig` values to *differently named environment
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-duotone" to="https://youtu.be/_FYV5WfiWvs" target="_blank"} ::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. Watch a video from Alexander Lichter showcasing the top mistake developers make using runtimeConfig.
:: ::
@ -94,7 +94,7 @@ 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]

View File

@ -15,6 +15,12 @@ The build and publishing method and quality of these 'nightly' releases are the
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`:

View File

@ -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;
} }

View File

@ -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,7 +45,7 @@ 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-duotone" to="https://vueschool.io/lessons/navigating-the-official-starter-template" target="_blank"} ::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. Watch Vue School video about Nuxt module starter template.
:: ::
@ -155,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
@ -213,9 +228,9 @@ Learn more about asset injection in [the recipes section](#recipes).
::warning ::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.
:: ::
@ -259,7 +274,7 @@ 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-duotone" to="https://vueschool.io/lessons/extending-and-altering-nuxt-configuration-and-options" target="_blank"} ::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. Watch Vue School video about altering Nuxt configuration.
:: ::
@ -296,7 +311,7 @@ Be careful not to expose any sensitive module configuration on the public runtim
:read-more{to="/docs/guide/going-further/runtime-config"} :read-more{to="/docs/guide/going-further/runtime-config"}
::tip{icon="i-ph-video-duotone" to="https://vueschool.io/lessons/passing-and-exposing-module-options" target="_blank"} ::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. Watch Vue School video about passing and exposing Nuxt module options.
:: ::
@ -523,7 +538,7 @@ export default defineNuxtModule({
:read-more{to="/docs/api/advanced/hooks"} :read-more{to="/docs/api/advanced/hooks"}
::tip{icon="i-ph-video-duotone" to="https://vueschool.io/lessons/nuxt-lifecycle-hooks" target="_blank"} ::tip{icon="i-ph-video" to="https://vueschool.io/lessons/nuxt-lifecycle-hooks?friend=nuxt" target="_blank"}
Watch Vue School video about using Nuxt lifecycle hooks in modules. Watch Vue School video about using Nuxt lifecycle hooks in modules.
:: ::
@ -583,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 {}
} }
@ -623,7 +638,7 @@ Testing helps ensuring your module works as expected given various setup. Find i
::tip ::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).
:: ::
@ -749,7 +764,7 @@ 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-duotone" to="https://vueschool.io/lessons/exploring-nuxt-modules-ecosystem-and-module-types" target="_blank"} ::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. Watch Vue School video about Nuxt module types.
:: ::

View File

@ -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

View File

@ -9,23 +9,23 @@ In Nuxt 3, your routing is defined by the structure of your files inside the [pa
### Router Config ### Router Config
Using [router options](/docs/guide/going-further/custom-routing#router-options), you can optionally override or extend your routes using a function that accepts the scanned routes and returns customized routes. Using [router options](/docs/guide/recipes/custom-routing#router-options), you can optionally override or extend your routes using a function that accepts the scanned routes and returns customized routes.
If it returns `null` or `undefined`, Nuxt will fall back to the default routes (useful to modify input array). If it returns `null` or `undefined`, Nuxt will fall back to the default routes (useful to modify input array).
```ts [app/router.options.ts] ```ts [app/router.options.ts]
import type { RouterConfig } from '@nuxt/schema' import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> { export default {
// https://router.vuejs.org/api/interfaces/routeroptions.html#routes // https://router.vuejs.org/api/interfaces/routeroptions.html#routes
routes: (_routes) => [ routes: (_routes) => [
{ {
name: 'home', name: 'home',
path: '/', path: '/',
component: () => import('~/pages/home.vue').then(r => r.default || r) component: () => import('~/pages/home.vue')
} }
], ],
} } satisfies RouterConfig
``` ```
::note ::note
@ -39,6 +39,8 @@ You can add, change or remove pages from the scanned routes with the `pages:exte
For example, to prevent creating routes for any `.ts` files: For example, to prevent creating routes for any `.ts` files:
```ts [nuxt.config.ts] ```ts [nuxt.config.ts]
import type { NuxtPage } from '@nuxt/schema'
export default defineNuxtConfig({ export default defineNuxtConfig({
hooks: { hooks: {
'pages:extend' (pages) { 'pages:extend' (pages) {
@ -51,9 +53,9 @@ export default defineNuxtConfig({
// remove routes // remove routes
function removePagesMatching (pattern: RegExp, pages: NuxtPage[] = []) { function removePagesMatching (pattern: RegExp, pages: NuxtPage[] = []) {
const pagesToRemove = [] const pagesToRemove: NuxtPage[] = []
for (const page of pages) { for (const page of pages) {
if (pattern.test(page.file)) { if (page.file && pattern.test(page.file)) {
pagesToRemove.push(page) pagesToRemove.push(page)
} else { } else {
removePagesMatching(pattern, page.children) removePagesMatching(pattern, page.children)
@ -85,11 +87,11 @@ On top of customizing options for [`vue-router`](https://router.vuejs.org/api/in
This is the recommended way to specify [router options](/docs/api/nuxt-config#router). This is the recommended way to specify [router options](/docs/api/nuxt-config#router).
```js [app/router.options.ts] ```ts [app/router.options.ts]
import type { RouterConfig } from '@nuxt/schema' import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> { export default {
} } satisfies RouterConfig
``` ```
It is possible to add more router options files by adding files within the `pages:routerOptions` hook. Later items in the array override earlier ones. It is possible to add more router options files by adding files within the `pages:routerOptions` hook. Later items in the array override earlier ones.
@ -99,6 +101,8 @@ Adding a router options file in this hook will switch on page-based routing, unl
:: ::
```ts [nuxt.config.ts] ```ts [nuxt.config.ts]
import { createResolver } from '@nuxt/kit'
export default defineNuxtConfig({ export default defineNuxtConfig({
hooks: { hooks: {
'pages:routerOptions' ({ files }) { 'pages:routerOptions' ({ files }) {
@ -166,12 +170,12 @@ export default defineNuxtConfig({
You can optionally override history mode using a function that accepts the base URL and returns the history mode. If it returns `null` or `undefined`, Nuxt will fallback to the default history. You can optionally override history mode using a function that accepts the base URL and returns the history mode. If it returns `null` or `undefined`, Nuxt will fallback to the default history.
```js [app/router.options.ts] ```ts [app/router.options.ts]
import type { RouterConfig } from '@nuxt/schema' import type { RouterConfig } from '@nuxt/schema'
import { createMemoryHistory } from 'vue-router' import { createMemoryHistory } from 'vue-router'
export default <RouterConfig> { export default {
// https://router.vuejs.org/api/interfaces/routeroptions.html // https://router.vuejs.org/api/interfaces/routeroptions.html
history: base => import.meta.client ? createMemoryHistory(base) : null /* default */ history: base => import.meta.client ? createMemoryHistory(base) : null /* default */
} } satisfies RouterConfig
``` ```

View File

@ -8,7 +8,7 @@ While Nuxt modules offer extensive functionality, sometimes a specific Vite plug
First, we need to install the Vite plugin, for our example, we'll use `@rollup/plugin-yaml`: First, we need to install the Vite plugin, for our example, we'll use `@rollup/plugin-yaml`:
::code-group ::package-managers
```bash [npm] ```bash [npm]
npm install @rollup/plugin-yaml npm install @rollup/plugin-yaml

View File

@ -24,7 +24,7 @@ Let's pretend here that:
- If the API responds with a `401` status code, we redirect the user to the `/login` page - If the API responds with a `401` status code, we redirect the user to the `/login` page
```ts [plugins/api.ts] ```ts [plugins/api.ts]
export default defineNuxtPlugin(() => { export default defineNuxtPlugin((nuxtApp) => {
const { session } = useUserSession() const { session } = useUserSession()
const api = $fetch.create({ const api = $fetch.create({
@ -43,7 +43,7 @@ export default defineNuxtPlugin(() => {
}, },
async onResponseError({ response }) { async onResponseError({ response }) {
if (response.status === 401) { if (response.status === 401) {
await navigateTo('/login') await nuxtApp.runWithContext(() => navigateTo('/login'))
} }
} }
}) })
@ -70,7 +70,7 @@ const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
Wrapping with [`useAsyncData`](/docs/api/composables/use-async-data) **avoid double data fetching when doing server-side rendering** (server & client on hydration). Wrapping with [`useAsyncData`](/docs/api/composables/use-async-data) **avoid double data fetching when doing server-side rendering** (server & client on hydration).
:: ::
## Custom `useFetch` ## Custom `useFetch`/`useAsyncData`
Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`: Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`:
@ -79,7 +79,7 @@ import type { UseFetchOptions } from 'nuxt/app'
export function useAPI<T>( export function useAPI<T>(
url: string | (() => string), url: string | (() => string),
options: Omit<UseFetchOptions<T>, 'default'> & { default: () => T | Ref<T> }, options?: UseFetchOptions<T>,
) { ) {
return useFetch(url, { return useFetch(url, {
...options, ...options,
@ -96,6 +96,10 @@ const { data: modules } = await useAPI('/modules')
</script> </script>
``` ```
::note
This example demonstrates how to use a custom `useFetch`, but the same structure is identical for a custom `useAsyncData`.
::
::callout{icon="i-simple-icons-youtube" color="red" to="https://www.youtube.com/watch?v=jXH8Tr-exhI"} ::callout{icon="i-simple-icons-youtube" color="red" to="https://www.youtube.com/watch?v=jXH8Tr-exhI"}
Watch a video about custom `$fetch` and Repository Pattern in Nuxt. Watch a video about custom `$fetch` and Repository Pattern in Nuxt.
:: ::

View File

@ -1,3 +1,3 @@
title: Recipes title: Recipes
titleTemplate: '%s · Recipes' titleTemplate: '%s · Recipes'
icon: i-ph-cooking-pot-duotone icon: i-ph-cooking-pot

View File

@ -1,2 +1,2 @@
title: 'Guide' title: 'Guide'
icon: i-ph-book-open-duotone icon: i-ph-book-open

View File

@ -4,7 +4,7 @@ description: "Nuxt provides a <NuxtPicture> component to handle automatic image
links: links:
- label: Source - label: Source
icon: i-simple-icons-github icon: i-simple-icons-github
to: https://github.com/nuxt/image/blob/main/src/runtime/components/nuxt-picture.ts to: https://github.com/nuxt/image/blob/main/src/runtime/components/NuxtPicture.vue
size: xs size: xs
--- ---

View File

@ -4,7 +4,7 @@ description: The <Teleport> component teleports a component to a different locat
--- ---
::warning ::warning
The `to` target of [`<Teleport>`](https://vuejs.org/guide/built-ins/teleport.html) expects a CSS selector string or an actual DOM node. Nuxt currently has SSR support for teleports to `body` only, with client-side support for other targets using a `<ClientOnly>` wrapper. The `to` target of [`<Teleport>`](https://vuejs.org/guide/built-ins/teleport.html) expects a CSS selector string or an actual DOM node. Nuxt currently has SSR support for teleports to `#teleports` only, with client-side support for other targets using a `<ClientOnly>` wrapper.
:: ::
## Body Teleport ## Body Teleport
@ -14,7 +14,7 @@ The `to` target of [`<Teleport>`](https://vuejs.org/guide/built-ins/teleport.htm
<button @click="open = true"> <button @click="open = true">
Open Modal Open Modal
</button> </button>
<Teleport to="body"> <Teleport to="#teleports">
<div v-if="open" class="modal"> <div v-if="open" class="modal">
<p>Hello from the modal!</p> <p>Hello from the modal!</p>
<button @click="open = false"> <button @click="open = false">

View File

@ -1,6 +1,6 @@
--- ---
title: '<NuxtRouteAnnouncer>' title: '<NuxtRouteAnnouncer>'
description: 'Add a hidden element with the page title for assistive technologies.' description: 'The <NuxtRouteAnnouncer> component adds a hidden element with the page title to announce route changes to assistive technologies.'
navigation: navigation:
badge: New badge: New
links: links:
@ -11,12 +11,12 @@ links:
--- ---
::important ::important
This component will be available in Nuxt v3.12 or in [the nightly release channel](/docs/guide/going-further/nightly-release-channel). This component is available in Nuxt v3.12+.
:: ::
## Usage ## Usage
Add `<NuxtRouteAnnouncer/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`layouts/`](/docs/guide/directory-structure/layouts) to enhance accessibility by informing assistive technologies about page's title changes. This ensures that navigational changes are announced to users relying on screen readers. Add `<NuxtRouteAnnouncer/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`layouts/`](/docs/guide/directory-structure/layouts) to enhance accessibility by informing assistive technologies about page title changes. This ensures that navigational changes are announced to users relying on screen readers.
```vue [app.vue] ```vue [app.vue]
<template> <template>
@ -29,7 +29,7 @@ Add `<NuxtRouteAnnouncer/>` in your [`app.vue`](/docs/guide/directory-structure/
## Slots ## Slots
You can pass custom HTML or components through the route announcer default slot. You can pass custom HTML or components through the route announcer's default slot.
```vue ```vue
<template> <template>
@ -43,7 +43,7 @@ You can pass custom HTML or components through the route announcer default slot.
## Props ## Props
- `atomic`: Controls if screen readers announce only changes or the entire content. Set to true for full content readout on updates, false for changes only. (default `false`) - `atomic`: Controls if screen readers only announce changes or the entire content. Set to true for full content readouts on updates, false for changes only. (default `false`)
- `politeness`: Sets the urgency for screen reader announcements: `off` (disable the announcement), `polite` (waits for silence), or `assertive` (interrupts immediately). (default `polite`) - `politeness`: Sets the urgency for screen reader announcements: `off` (disable the announcement), `polite` (waits for silence), or `assertive` (interrupts immediately). (default `polite`)
::callout ::callout

Some files were not shown because too many files have changed in this diff Show More