ads-fe 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/dist/cli.js +545 -0
- package/dist/meta.js +93 -0
- package/package.json +43 -0
- package/skill.md +66 -0
- package/skills/core/SKILL.md +66 -0
- package/skills/core/references/app-development.md +45 -0
- package/skills/core/references/git.md +66 -0
- package/skills/core/references/monorepo.md +124 -0
- package/skills/element-plus-vue3/LICENSE.md +405 -0
- package/skills/element-plus-vue3/LICENSE.txt +202 -0
- package/skills/element-plus-vue3/SKILL.md +218 -0
- package/skills/element-plus-vue3/SYNC.md +5 -0
- package/skills/element-plus-vue3/api/component-api.md +94 -0
- package/skills/element-plus-vue3/api/global-config.md +89 -0
- package/skills/element-plus-vue3/api/props-and-events.md +101 -0
- package/skills/element-plus-vue3/examples/components/button.md +99 -0
- package/skills/element-plus-vue3/examples/components/date-picker.md +115 -0
- package/skills/element-plus-vue3/examples/components/dialog.md +106 -0
- package/skills/element-plus-vue3/examples/components/form.md +127 -0
- package/skills/element-plus-vue3/examples/components/input.md +123 -0
- package/skills/element-plus-vue3/examples/components/message.md +93 -0
- package/skills/element-plus-vue3/examples/components/overview.md +59 -0
- package/skills/element-plus-vue3/examples/components/select.md +133 -0
- package/skills/element-plus-vue3/examples/components/table.md +166 -0
- package/skills/element-plus-vue3/examples/guide/design.md +68 -0
- package/skills/element-plus-vue3/examples/guide/global-config.md +95 -0
- package/skills/element-plus-vue3/examples/guide/i18n.md +95 -0
- package/skills/element-plus-vue3/examples/guide/installation.md +110 -0
- package/skills/element-plus-vue3/examples/guide/quick-start.md +103 -0
- package/skills/element-plus-vue3/examples/guide/theme.md +78 -0
- package/skills/element-plus-vue3/templates/component-usage.md +92 -0
- package/skills/element-plus-vue3/templates/installation.md +82 -0
- package/skills/element-plus-vue3/templates/project-setup.md +83 -0
- package/skills/node/LICENSE.md +21 -0
- package/skills/node/SKILL.md +94 -0
- package/skills/node/SYNC.md +5 -0
- package/skills/node/rules/assets/graceful-server.test.ts +88 -0
- package/skills/node/rules/assets/graceful-server.ts +80 -0
- package/skills/node/rules/async-patterns.md +136 -0
- package/skills/node/rules/caching.md +198 -0
- package/skills/node/rules/environment.md +253 -0
- package/skills/node/rules/error-handling.md +164 -0
- package/skills/node/rules/flaky-tests.md +439 -0
- package/skills/node/rules/graceful-shutdown.md +204 -0
- package/skills/node/rules/logging.md +205 -0
- package/skills/node/rules/modules.md +105 -0
- package/skills/node/rules/node-modules-exploration.md +172 -0
- package/skills/node/rules/performance.md +130 -0
- package/skills/node/rules/profiling.md +183 -0
- package/skills/node/rules/streams.md +213 -0
- package/skills/node/rules/stuck-processes-and-tests.md +124 -0
- package/skills/node/rules/testing.md +218 -0
- package/skills/node/rules/typescript.md +262 -0
- package/skills/node/tile.json +11 -0
- package/skills/nuxt/GENERATION.md +5 -0
- package/skills/nuxt/LICENSE.md +21 -0
- package/skills/nuxt/SKILL.md +55 -0
- package/skills/nuxt/SYNC.md +5 -0
- package/skills/nuxt/references/advanced-hooks.md +289 -0
- package/skills/nuxt/references/advanced-layers.md +299 -0
- package/skills/nuxt/references/advanced-module-authoring.md +554 -0
- package/skills/nuxt/references/best-practices-data-fetching.md +357 -0
- package/skills/nuxt/references/best-practices-ssr.md +355 -0
- package/skills/nuxt/references/core-cli.md +263 -0
- package/skills/nuxt/references/core-config.md +162 -0
- package/skills/nuxt/references/core-data-fetching.md +236 -0
- package/skills/nuxt/references/core-deployment.md +224 -0
- package/skills/nuxt/references/core-directory-structure.md +269 -0
- package/skills/nuxt/references/core-modules.md +292 -0
- package/skills/nuxt/references/core-routing.md +226 -0
- package/skills/nuxt/references/features-components-autoimport.md +328 -0
- package/skills/nuxt/references/features-components.md +264 -0
- package/skills/nuxt/references/features-composables.md +276 -0
- package/skills/nuxt/references/features-server.md +265 -0
- package/skills/nuxt/references/features-state.md +194 -0
- package/skills/nuxt/references/rendering-modes.md +237 -0
- package/skills/pinia/GENERATION.md +5 -0
- package/skills/pinia/LICENSE.md +21 -0
- package/skills/pinia/SKILL.md +59 -0
- package/skills/pinia/SYNC.md +5 -0
- package/skills/pinia/references/advanced-hmr.md +61 -0
- package/skills/pinia/references/advanced-nuxt.md +119 -0
- package/skills/pinia/references/advanced-ssr.md +121 -0
- package/skills/pinia/references/best-practices-outside-component.md +115 -0
- package/skills/pinia/references/best-practices-testing.md +212 -0
- package/skills/pinia/references/core-stores.md +389 -0
- package/skills/pinia/references/features-composables.md +114 -0
- package/skills/pinia/references/features-composing-stores.md +134 -0
- package/skills/pinia/references/features-plugins.md +203 -0
- package/skills/pnpm/GENERATION.md +5 -0
- package/skills/pnpm/LICENSE.md +21 -0
- package/skills/pnpm/SKILL.md +42 -0
- package/skills/pnpm/SYNC.md +5 -0
- package/skills/pnpm/references/best-practices-ci.md +285 -0
- package/skills/pnpm/references/best-practices-migration.md +291 -0
- package/skills/pnpm/references/best-practices-performance.md +284 -0
- package/skills/pnpm/references/core-cli.md +229 -0
- package/skills/pnpm/references/core-config.md +188 -0
- package/skills/pnpm/references/core-store.md +179 -0
- package/skills/pnpm/references/core-workspaces.md +205 -0
- package/skills/pnpm/references/features-aliases.md +168 -0
- package/skills/pnpm/references/features-catalogs.md +159 -0
- package/skills/pnpm/references/features-hooks.md +233 -0
- package/skills/pnpm/references/features-overrides.md +184 -0
- package/skills/pnpm/references/features-patches.md +201 -0
- package/skills/pnpm/references/features-peer-deps.md +250 -0
- package/skills/slidev/LICENSE.md +21 -0
- package/skills/slidev/README.md +61 -0
- package/skills/slidev/SKILL.md +189 -0
- package/skills/slidev/SYNC.md +5 -0
- package/skills/slidev/references/animation-click-marker.md +37 -0
- package/skills/slidev/references/animation-drawing.md +68 -0
- package/skills/slidev/references/animation-rough-marker.md +53 -0
- package/skills/slidev/references/api-slide-hooks.md +37 -0
- package/skills/slidev/references/build-og-image.md +36 -0
- package/skills/slidev/references/build-pdf.md +40 -0
- package/skills/slidev/references/build-remote-assets.md +34 -0
- package/skills/slidev/references/build-seo-meta.md +43 -0
- package/skills/slidev/references/code-groups.md +64 -0
- package/skills/slidev/references/code-import-snippet.md +55 -0
- package/skills/slidev/references/code-line-highlighting.md +50 -0
- package/skills/slidev/references/code-line-numbers.md +46 -0
- package/skills/slidev/references/code-magic-move.md +57 -0
- package/skills/slidev/references/code-max-height.md +37 -0
- package/skills/slidev/references/code-twoslash.md +42 -0
- package/skills/slidev/references/core-animations.md +196 -0
- package/skills/slidev/references/core-cli.md +140 -0
- package/skills/slidev/references/core-components.md +197 -0
- package/skills/slidev/references/core-exporting.md +148 -0
- package/skills/slidev/references/core-frontmatter.md +195 -0
- package/skills/slidev/references/core-global-context.md +155 -0
- package/skills/slidev/references/core-headmatter.md +188 -0
- package/skills/slidev/references/core-hosting.md +152 -0
- package/skills/slidev/references/core-layouts.md +286 -0
- package/skills/slidev/references/core-syntax.md +155 -0
- package/skills/slidev/references/diagram-latex.md +55 -0
- package/skills/slidev/references/diagram-mermaid.md +44 -0
- package/skills/slidev/references/diagram-plantuml.md +45 -0
- package/skills/slidev/references/editor-monaco-run.md +44 -0
- package/skills/slidev/references/editor-monaco-write.md +24 -0
- package/skills/slidev/references/editor-monaco.md +50 -0
- package/skills/slidev/references/editor-prettier.md +40 -0
- package/skills/slidev/references/editor-side.md +23 -0
- package/skills/slidev/references/editor-vscode.md +55 -0
- package/skills/slidev/references/layout-canvas-size.md +25 -0
- package/skills/slidev/references/layout-draggable.md +57 -0
- package/skills/slidev/references/layout-global-layers.md +50 -0
- package/skills/slidev/references/layout-slots.md +75 -0
- package/skills/slidev/references/layout-transform.md +33 -0
- package/skills/slidev/references/layout-zoom.md +39 -0
- package/skills/slidev/references/presenter-notes-ruby.md +35 -0
- package/skills/slidev/references/presenter-recording.md +30 -0
- package/skills/slidev/references/presenter-remote.md +40 -0
- package/skills/slidev/references/presenter-timer.md +34 -0
- package/skills/slidev/references/style-direction.md +34 -0
- package/skills/slidev/references/style-icons.md +46 -0
- package/skills/slidev/references/style-scoped.md +50 -0
- package/skills/slidev/references/syntax-block-frontmatter.md +39 -0
- package/skills/slidev/references/syntax-comark.md +51 -0
- package/skills/slidev/references/syntax-frontmatter-merging.md +49 -0
- package/skills/slidev/references/syntax-importing-slides.md +60 -0
- package/skills/slidev/references/tool-eject-theme.md +27 -0
- package/skills/tsdown/LICENSE.md +22 -0
- package/skills/tsdown/README.md +77 -0
- package/skills/tsdown/SKILL.md +416 -0
- package/skills/tsdown/SYNC.md +5 -0
- package/skills/tsdown/references/README.md +139 -0
- package/skills/tsdown/references/advanced-benchmark.md +8 -0
- package/skills/tsdown/references/advanced-ci.md +89 -0
- package/skills/tsdown/references/advanced-hooks.md +363 -0
- package/skills/tsdown/references/advanced-plugins.md +381 -0
- package/skills/tsdown/references/advanced-programmatic.md +378 -0
- package/skills/tsdown/references/advanced-rolldown-options.md +117 -0
- package/skills/tsdown/references/guide-getting-started.md +183 -0
- package/skills/tsdown/references/guide-introduction.md +42 -0
- package/skills/tsdown/references/guide-migrate-from-tsup.md +199 -0
- package/skills/tsdown/references/option-cjs-default.md +98 -0
- package/skills/tsdown/references/option-cleaning.md +275 -0
- package/skills/tsdown/references/option-config-file.md +291 -0
- package/skills/tsdown/references/option-css.md +301 -0
- package/skills/tsdown/references/option-dependencies.md +385 -0
- package/skills/tsdown/references/option-dts.md +251 -0
- package/skills/tsdown/references/option-entry.md +211 -0
- package/skills/tsdown/references/option-exe.md +120 -0
- package/skills/tsdown/references/option-lint.md +127 -0
- package/skills/tsdown/references/option-log-level.md +91 -0
- package/skills/tsdown/references/option-minification.md +177 -0
- package/skills/tsdown/references/option-output-directory.md +272 -0
- package/skills/tsdown/references/option-output-format.md +183 -0
- package/skills/tsdown/references/option-package-exports.md +320 -0
- package/skills/tsdown/references/option-platform.md +256 -0
- package/skills/tsdown/references/option-root.md +88 -0
- package/skills/tsdown/references/option-shims.md +299 -0
- package/skills/tsdown/references/option-sourcemap.md +301 -0
- package/skills/tsdown/references/option-target.md +222 -0
- package/skills/tsdown/references/option-tree-shaking.md +335 -0
- package/skills/tsdown/references/option-unbundle.md +310 -0
- package/skills/tsdown/references/option-watch-mode.md +261 -0
- package/skills/tsdown/references/recipe-react.md +338 -0
- package/skills/tsdown/references/recipe-solid.md +42 -0
- package/skills/tsdown/references/recipe-svelte.md +54 -0
- package/skills/tsdown/references/recipe-vue.md +387 -0
- package/skills/tsdown/references/recipe-wasm.md +125 -0
- package/skills/tsdown/references/reference-cli.md +472 -0
- package/skills/turborepo/LICENSE.md +7 -0
- package/skills/turborepo/SKILL.md +951 -0
- package/skills/turborepo/SYNC.md +5 -0
- package/skills/turborepo/command/turborepo.md +70 -0
- package/skills/turborepo/references/best-practices/RULE.md +241 -0
- package/skills/turborepo/references/best-practices/dependencies.md +246 -0
- package/skills/turborepo/references/best-practices/packages.md +335 -0
- package/skills/turborepo/references/best-practices/structure.md +297 -0
- package/skills/turborepo/references/boundaries/RULE.md +126 -0
- package/skills/turborepo/references/caching/RULE.md +153 -0
- package/skills/turborepo/references/caching/gotchas.md +190 -0
- package/skills/turborepo/references/caching/remote-cache.md +127 -0
- package/skills/turborepo/references/ci/RULE.md +79 -0
- package/skills/turborepo/references/ci/github-actions.md +162 -0
- package/skills/turborepo/references/ci/patterns.md +145 -0
- package/skills/turborepo/references/ci/vercel.md +103 -0
- package/skills/turborepo/references/cli/RULE.md +100 -0
- package/skills/turborepo/references/cli/commands.md +297 -0
- package/skills/turborepo/references/configuration/RULE.md +235 -0
- package/skills/turborepo/references/configuration/global-options.md +239 -0
- package/skills/turborepo/references/configuration/gotchas.md +368 -0
- package/skills/turborepo/references/configuration/tasks.md +325 -0
- package/skills/turborepo/references/environment/RULE.md +123 -0
- package/skills/turborepo/references/environment/gotchas.md +175 -0
- package/skills/turborepo/references/environment/modes.md +101 -0
- package/skills/turborepo/references/filtering/RULE.md +148 -0
- package/skills/turborepo/references/filtering/patterns.md +152 -0
- package/skills/turborepo/references/watch/RULE.md +99 -0
- package/skills/vite/GENERATION.md +5 -0
- package/skills/vite/LICENSE.md +21 -0
- package/skills/vite/SKILL.md +72 -0
- package/skills/vite/SYNC.md +5 -0
- package/skills/vite/references/build-and-ssr.md +164 -0
- package/skills/vite/references/core-config.md +162 -0
- package/skills/vite/references/core-features.md +205 -0
- package/skills/vite/references/core-plugin-api.md +235 -0
- package/skills/vite/references/environment-api.md +108 -0
- package/skills/vite/references/rolldown-migration.md +157 -0
- package/skills/vitepress/GENERATION.md +5 -0
- package/skills/vitepress/LICENSE.md +21 -0
- package/skills/vitepress/SKILL.md +65 -0
- package/skills/vitepress/SYNC.md +5 -0
- package/skills/vitepress/references/advanced-i18n.md +299 -0
- package/skills/vitepress/references/advanced-ssr.md +228 -0
- package/skills/vitepress/references/core-cli.md +119 -0
- package/skills/vitepress/references/core-config.md +189 -0
- package/skills/vitepress/references/core-markdown.md +277 -0
- package/skills/vitepress/references/core-routing.md +169 -0
- package/skills/vitepress/references/features-code-blocks.md +243 -0
- package/skills/vitepress/references/features-data-loading.md +220 -0
- package/skills/vitepress/references/features-dynamic-routes.md +235 -0
- package/skills/vitepress/references/features-vue.md +224 -0
- package/skills/vitepress/references/recipes-deploy.md +240 -0
- package/skills/vitepress/references/theme-config.md +315 -0
- package/skills/vitepress/references/theme-custom.md +269 -0
- package/skills/vitepress/references/theme-customization.md +290 -0
- package/skills/vitest/GENERATION.md +5 -0
- package/skills/vitest/LICENSE.md +21 -0
- package/skills/vitest/SKILL.md +52 -0
- package/skills/vitest/SYNC.md +5 -0
- package/skills/vitest/references/advanced-environments.md +264 -0
- package/skills/vitest/references/advanced-projects.md +300 -0
- package/skills/vitest/references/advanced-type-testing.md +237 -0
- package/skills/vitest/references/advanced-vi.md +249 -0
- package/skills/vitest/references/core-cli.md +166 -0
- package/skills/vitest/references/core-config.md +174 -0
- package/skills/vitest/references/core-describe.md +193 -0
- package/skills/vitest/references/core-expect.md +219 -0
- package/skills/vitest/references/core-hooks.md +244 -0
- package/skills/vitest/references/core-test-api.md +233 -0
- package/skills/vitest/references/features-concurrency.md +250 -0
- package/skills/vitest/references/features-context.md +238 -0
- package/skills/vitest/references/features-coverage.md +207 -0
- package/skills/vitest/references/features-filtering.md +211 -0
- package/skills/vitest/references/features-mocking.md +265 -0
- package/skills/vitest/references/features-snapshots.md +207 -0
- package/skills/vue/GENERATION.md +5 -0
- package/skills/vue/LICENSE.md +21 -0
- package/skills/vue/SKILL.md +84 -0
- package/skills/vue/SYNC.md +5 -0
- package/skills/vue/references/advanced-patterns.md +314 -0
- package/skills/vue/references/core-new-apis.md +264 -0
- package/skills/vue/references/script-setup-macros.md +204 -0
- package/skills/vue-best-practices/LICENSE.md +21 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/SYNC.md +5 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-router-best-practices/LICENSE.md +21 -0
- package/skills/vue-router-best-practices/SKILL.md +23 -0
- package/skills/vue-router-best-practices/SYNC.md +5 -0
- package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
- package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
- package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
- package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
- package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
- package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
- package/skills/vue-testing-best-practices/LICENSE.md +21 -0
- package/skills/vue-testing-best-practices/SKILL.md +29 -0
- package/skills/vue-testing-best-practices/SYNC.md +5 -0
- package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
- package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
- package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
- package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
- package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
- package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
- package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
- package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
- package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
- package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
- package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
- package/skills/vueuse-functions/LICENSE.md +21 -0
- package/skills/vueuse-functions/SKILL.md +419 -0
- package/skills/vueuse-functions/SYNC.md +5 -0
- package/skills/vueuse-functions/references/computedAsync.md +195 -0
- package/skills/vueuse-functions/references/computedEager.md +62 -0
- package/skills/vueuse-functions/references/computedInject.md +137 -0
- package/skills/vueuse-functions/references/computedWithControl.md +98 -0
- package/skills/vueuse-functions/references/createEventHook.md +86 -0
- package/skills/vueuse-functions/references/createGenericProjection.md +25 -0
- package/skills/vueuse-functions/references/createGlobalState.md +95 -0
- package/skills/vueuse-functions/references/createInjectionState.md +226 -0
- package/skills/vueuse-functions/references/createProjection.md +31 -0
- package/skills/vueuse-functions/references/createRef.md +54 -0
- package/skills/vueuse-functions/references/createReusableTemplate.md +361 -0
- package/skills/vueuse-functions/references/createSharedComposable.md +42 -0
- package/skills/vueuse-functions/references/createTemplatePromise.md +306 -0
- package/skills/vueuse-functions/references/createUnrefFn.md +51 -0
- package/skills/vueuse-functions/references/extendRef.md +76 -0
- package/skills/vueuse-functions/references/from.md +80 -0
- package/skills/vueuse-functions/references/get.md +30 -0
- package/skills/vueuse-functions/references/injectLocal.md +35 -0
- package/skills/vueuse-functions/references/isDefined.md +31 -0
- package/skills/vueuse-functions/references/logicAnd.md +40 -0
- package/skills/vueuse-functions/references/logicNot.md +36 -0
- package/skills/vueuse-functions/references/logicOr.md +40 -0
- package/skills/vueuse-functions/references/makeDestructurable.md +41 -0
- package/skills/vueuse-functions/references/onClickOutside.md +228 -0
- package/skills/vueuse-functions/references/onElementRemoval.md +88 -0
- package/skills/vueuse-functions/references/onKeyStroke.md +212 -0
- package/skills/vueuse-functions/references/onLongPress.md +235 -0
- package/skills/vueuse-functions/references/onStartTyping.md +53 -0
- package/skills/vueuse-functions/references/provideLocal.md +37 -0
- package/skills/vueuse-functions/references/reactify.md +144 -0
- package/skills/vueuse-functions/references/reactifyObject.md +62 -0
- package/skills/vueuse-functions/references/reactiveComputed.md +34 -0
- package/skills/vueuse-functions/references/reactiveOmit.md +86 -0
- package/skills/vueuse-functions/references/reactivePick.md +106 -0
- package/skills/vueuse-functions/references/refAutoReset.md +46 -0
- package/skills/vueuse-functions/references/refDebounced.md +81 -0
- package/skills/vueuse-functions/references/refDefault.md +36 -0
- package/skills/vueuse-functions/references/refManualReset.md +48 -0
- package/skills/vueuse-functions/references/refThrottled.md +99 -0
- package/skills/vueuse-functions/references/refWithControl.md +146 -0
- package/skills/vueuse-functions/references/set.md +30 -0
- package/skills/vueuse-functions/references/syncRef.md +195 -0
- package/skills/vueuse-functions/references/syncRefs.md +128 -0
- package/skills/vueuse-functions/references/templateRef.md +86 -0
- package/skills/vueuse-functions/references/toObserver.md +38 -0
- package/skills/vueuse-functions/references/toReactive.md +41 -0
- package/skills/vueuse-functions/references/toRef.md +74 -0
- package/skills/vueuse-functions/references/toRefs.md +78 -0
- package/skills/vueuse-functions/references/tryOnBeforeMount.md +34 -0
- package/skills/vueuse-functions/references/tryOnBeforeUnmount.md +32 -0
- package/skills/vueuse-functions/references/tryOnMounted.md +34 -0
- package/skills/vueuse-functions/references/tryOnScopeDispose.md +31 -0
- package/skills/vueuse-functions/references/tryOnUnmounted.md +32 -0
- package/skills/vueuse-functions/references/unrefElement.md +54 -0
- package/skills/vueuse-functions/references/until.md +161 -0
- package/skills/vueuse-functions/references/useAbs.md +31 -0
- package/skills/vueuse-functions/references/useActiveElement.md +86 -0
- package/skills/vueuse-functions/references/useAnimate.md +180 -0
- package/skills/vueuse-functions/references/useArrayDifference.md +84 -0
- package/skills/vueuse-functions/references/useArrayEvery.md +59 -0
- package/skills/vueuse-functions/references/useArrayFilter.md +63 -0
- package/skills/vueuse-functions/references/useArrayFind.md +50 -0
- package/skills/vueuse-functions/references/useArrayFindIndex.md +59 -0
- package/skills/vueuse-functions/references/useArrayFindLast.md +52 -0
- package/skills/vueuse-functions/references/useArrayIncludes.md +63 -0
- package/skills/vueuse-functions/references/useArrayJoin.md +74 -0
- package/skills/vueuse-functions/references/useArrayMap.md +59 -0
- package/skills/vueuse-functions/references/useArrayReduce.md +81 -0
- package/skills/vueuse-functions/references/useArraySome.md +59 -0
- package/skills/vueuse-functions/references/useArrayUnique.md +76 -0
- package/skills/vueuse-functions/references/useAsyncQueue.md +136 -0
- package/skills/vueuse-functions/references/useAsyncState.md +185 -0
- package/skills/vueuse-functions/references/useAsyncValidator.md +70 -0
- package/skills/vueuse-functions/references/useAuth.md +123 -0
- package/skills/vueuse-functions/references/useAverage.md +36 -0
- package/skills/vueuse-functions/references/useAxios.md +325 -0
- package/skills/vueuse-functions/references/useBase64.md +136 -0
- package/skills/vueuse-functions/references/useBattery.md +80 -0
- package/skills/vueuse-functions/references/useBluetooth.md +174 -0
- package/skills/vueuse-functions/references/useBreakpoints.md +176 -0
- package/skills/vueuse-functions/references/useBroadcastChannel.md +73 -0
- package/skills/vueuse-functions/references/useBrowserLocation.md +56 -0
- package/skills/vueuse-functions/references/useCached.md +52 -0
- package/skills/vueuse-functions/references/useCeil.md +31 -0
- package/skills/vueuse-functions/references/useChangeCase.md +79 -0
- package/skills/vueuse-functions/references/useClamp.md +85 -0
- package/skills/vueuse-functions/references/useClipboard.md +122 -0
- package/skills/vueuse-functions/references/useClipboardItems.md +93 -0
- package/skills/vueuse-functions/references/useCloned.md +91 -0
- package/skills/vueuse-functions/references/useColorMode.md +172 -0
- package/skills/vueuse-functions/references/useConfirmDialog.md +159 -0
- package/skills/vueuse-functions/references/useCookies.md +162 -0
- package/skills/vueuse-functions/references/useCountdown.md +105 -0
- package/skills/vueuse-functions/references/useCounter.md +86 -0
- package/skills/vueuse-functions/references/useCssSupports.md +33 -0
- package/skills/vueuse-functions/references/useCssVar.md +50 -0
- package/skills/vueuse-functions/references/useCurrentElement.md +61 -0
- package/skills/vueuse-functions/references/useCycleList.md +75 -0
- package/skills/vueuse-functions/references/useDark.md +142 -0
- package/skills/vueuse-functions/references/useDateFormat.md +145 -0
- package/skills/vueuse-functions/references/useDebounceFn.md +100 -0
- package/skills/vueuse-functions/references/useDebouncedRefHistory.md +40 -0
- package/skills/vueuse-functions/references/useDeviceMotion.md +80 -0
- package/skills/vueuse-functions/references/useDeviceOrientation.md +64 -0
- package/skills/vueuse-functions/references/useDevicePixelRatio.md +47 -0
- package/skills/vueuse-functions/references/useDevicesList.md +89 -0
- package/skills/vueuse-functions/references/useDisplayMedia.md +67 -0
- package/skills/vueuse-functions/references/useDocumentVisibility.md +44 -0
- package/skills/vueuse-functions/references/useDraggable.md +289 -0
- package/skills/vueuse-functions/references/useDrauu.md +65 -0
- package/skills/vueuse-functions/references/useDropZone.md +83 -0
- package/skills/vueuse-functions/references/useElementBounding.md +131 -0
- package/skills/vueuse-functions/references/useElementByPoint.md +46 -0
- package/skills/vueuse-functions/references/useElementHover.md +79 -0
- package/skills/vueuse-functions/references/useElementSize.md +79 -0
- package/skills/vueuse-functions/references/useElementVisibility.md +163 -0
- package/skills/vueuse-functions/references/useEventBus.md +101 -0
- package/skills/vueuse-functions/references/useEventListener.md +226 -0
- package/skills/vueuse-functions/references/useEventSource.md +204 -0
- package/skills/vueuse-functions/references/useExtractedObservable.md +198 -0
- package/skills/vueuse-functions/references/useEyeDropper.md +72 -0
- package/skills/vueuse-functions/references/useFavicon.md +69 -0
- package/skills/vueuse-functions/references/useFetch.md +546 -0
- package/skills/vueuse-functions/references/useFileDialog.md +91 -0
- package/skills/vueuse-functions/references/useFileSystemAccess.md +161 -0
- package/skills/vueuse-functions/references/useFirestore.md +129 -0
- package/skills/vueuse-functions/references/useFloor.md +31 -0
- package/skills/vueuse-functions/references/useFocus.md +99 -0
- package/skills/vueuse-functions/references/useFocusTrap.md +245 -0
- package/skills/vueuse-functions/references/useFocusWithin.md +57 -0
- package/skills/vueuse-functions/references/useFps.md +28 -0
- package/skills/vueuse-functions/references/useFullscreen.md +74 -0
- package/skills/vueuse-functions/references/useFuse.md +75 -0
- package/skills/vueuse-functions/references/useGamepad.md +176 -0
- package/skills/vueuse-functions/references/useGeolocation.md +63 -0
- package/skills/vueuse-functions/references/useIDBKeyval.md +93 -0
- package/skills/vueuse-functions/references/useIdle.md +88 -0
- package/skills/vueuse-functions/references/useImage.md +90 -0
- package/skills/vueuse-functions/references/useInfiniteScroll.md +156 -0
- package/skills/vueuse-functions/references/useIntersectionObserver.md +117 -0
- package/skills/vueuse-functions/references/useInterval.md +112 -0
- package/skills/vueuse-functions/references/useIntervalFn.md +50 -0
- package/skills/vueuse-functions/references/useIpcRenderer.md +144 -0
- package/skills/vueuse-functions/references/useIpcRendererInvoke.md +58 -0
- package/skills/vueuse-functions/references/useIpcRendererOn.md +52 -0
- package/skills/vueuse-functions/references/useJwt.md +57 -0
- package/skills/vueuse-functions/references/useKeyModifier.md +87 -0
- package/skills/vueuse-functions/references/useLastChanged.md +63 -0
- package/skills/vueuse-functions/references/useLocalStorage.md +41 -0
- package/skills/vueuse-functions/references/useMagicKeys.md +245 -0
- package/skills/vueuse-functions/references/useManualRefHistory.md +204 -0
- package/skills/vueuse-functions/references/useMath.md +47 -0
- package/skills/vueuse-functions/references/useMax.md +36 -0
- package/skills/vueuse-functions/references/useMediaControls.md +201 -0
- package/skills/vueuse-functions/references/useMediaQuery.md +53 -0
- package/skills/vueuse-functions/references/useMemoize.md +175 -0
- package/skills/vueuse-functions/references/useMemory.md +70 -0
- package/skills/vueuse-functions/references/useMin.md +36 -0
- package/skills/vueuse-functions/references/useMounted.md +38 -0
- package/skills/vueuse-functions/references/useMouse.md +113 -0
- package/skills/vueuse-functions/references/useMouseInElement.md +132 -0
- package/skills/vueuse-functions/references/useMousePressed.md +116 -0
- package/skills/vueuse-functions/references/useMutationObserver.md +60 -0
- package/skills/vueuse-functions/references/useNProgress.md +78 -0
- package/skills/vueuse-functions/references/useNavigatorLanguage.md +57 -0
- package/skills/vueuse-functions/references/useNetwork.md +106 -0
- package/skills/vueuse-functions/references/useNow.md +83 -0
- package/skills/vueuse-functions/references/useObjectUrl.md +55 -0
- package/skills/vueuse-functions/references/useObservable.md +91 -0
- package/skills/vueuse-functions/references/useOffsetPagination.md +199 -0
- package/skills/vueuse-functions/references/useOnline.md +41 -0
- package/skills/vueuse-functions/references/usePageLeave.md +43 -0
- package/skills/vueuse-functions/references/useParallax.md +58 -0
- package/skills/vueuse-functions/references/useParentElement.md +54 -0
- package/skills/vueuse-functions/references/usePerformanceObserver.md +48 -0
- package/skills/vueuse-functions/references/usePermission.md +78 -0
- package/skills/vueuse-functions/references/usePointer.md +91 -0
- package/skills/vueuse-functions/references/usePointerLock.md +59 -0
- package/skills/vueuse-functions/references/usePointerSwipe.md +80 -0
- package/skills/vueuse-functions/references/usePrecision.md +49 -0
- package/skills/vueuse-functions/references/usePreferredColorScheme.md +42 -0
- package/skills/vueuse-functions/references/usePreferredContrast.md +42 -0
- package/skills/vueuse-functions/references/usePreferredDark.md +41 -0
- package/skills/vueuse-functions/references/usePreferredLanguages.md +41 -0
- package/skills/vueuse-functions/references/usePreferredReducedMotion.md +42 -0
- package/skills/vueuse-functions/references/usePreferredReducedTransparency.md +42 -0
- package/skills/vueuse-functions/references/usePrevious.md +40 -0
- package/skills/vueuse-functions/references/useProjection.md +38 -0
- package/skills/vueuse-functions/references/useQRCode.md +53 -0
- package/skills/vueuse-functions/references/useRTDB.md +83 -0
- package/skills/vueuse-functions/references/useRafFn.md +68 -0
- package/skills/vueuse-functions/references/useRefHistory.md +285 -0
- package/skills/vueuse-functions/references/useResizeObserver.md +108 -0
- package/skills/vueuse-functions/references/useRound.md +31 -0
- package/skills/vueuse-functions/references/useRouteHash.md +27 -0
- package/skills/vueuse-functions/references/useRouteParams.md +38 -0
- package/skills/vueuse-functions/references/useRouteQuery.md +79 -0
- package/skills/vueuse-functions/references/useSSRWidth.md +47 -0
- package/skills/vueuse-functions/references/useScreenOrientation.md +98 -0
- package/skills/vueuse-functions/references/useScreenSafeArea.md +60 -0
- package/skills/vueuse-functions/references/useScriptTag.md +116 -0
- package/skills/vueuse-functions/references/useScroll.md +238 -0
- package/skills/vueuse-functions/references/useScrollLock.md +66 -0
- package/skills/vueuse-functions/references/useSessionStorage.md +41 -0
- package/skills/vueuse-functions/references/useShare.md +67 -0
- package/skills/vueuse-functions/references/useSortable.md +276 -0
- package/skills/vueuse-functions/references/useSorted.md +90 -0
- package/skills/vueuse-functions/references/useSpeechRecognition.md +90 -0
- package/skills/vueuse-functions/references/useSpeechSynthesis.md +101 -0
- package/skills/vueuse-functions/references/useStepper.md +137 -0
- package/skills/vueuse-functions/references/useStorage.md +278 -0
- package/skills/vueuse-functions/references/useStorageAsync.md +136 -0
- package/skills/vueuse-functions/references/useStyleTag.md +131 -0
- package/skills/vueuse-functions/references/useSubject.md +77 -0
- package/skills/vueuse-functions/references/useSubscription.md +33 -0
- package/skills/vueuse-functions/references/useSum.md +36 -0
- package/skills/vueuse-functions/references/useSupported.md +29 -0
- package/skills/vueuse-functions/references/useSwipe.md +75 -0
- package/skills/vueuse-functions/references/useTemplateRefsList.md +37 -0
- package/skills/vueuse-functions/references/useTextDirection.md +75 -0
- package/skills/vueuse-functions/references/useTextSelection.md +43 -0
- package/skills/vueuse-functions/references/useTextareaAutosize.md +94 -0
- package/skills/vueuse-functions/references/useThrottleFn.md +57 -0
- package/skills/vueuse-functions/references/useThrottledRefHistory.md +47 -0
- package/skills/vueuse-functions/references/useTimeAgo.md +154 -0
- package/skills/vueuse-functions/references/useTimeAgoIntl.md +117 -0
- package/skills/vueuse-functions/references/useTimeout.md +113 -0
- package/skills/vueuse-functions/references/useTimeoutFn.md +51 -0
- package/skills/vueuse-functions/references/useTimeoutPoll.md +47 -0
- package/skills/vueuse-functions/references/useTimestamp.md +93 -0
- package/skills/vueuse-functions/references/useTitle.md +115 -0
- package/skills/vueuse-functions/references/useToNumber.md +54 -0
- package/skills/vueuse-functions/references/useToString.md +34 -0
- package/skills/vueuse-functions/references/useToggle.md +103 -0
- package/skills/vueuse-functions/references/useTransition.md +265 -0
- package/skills/vueuse-functions/references/useTrunc.md +33 -0
- package/skills/vueuse-functions/references/useUrlSearchParams.md +121 -0
- package/skills/vueuse-functions/references/useUserMedia.md +96 -0
- package/skills/vueuse-functions/references/useVModel.md +182 -0
- package/skills/vueuse-functions/references/useVModels.md +67 -0
- package/skills/vueuse-functions/references/useVibrate.md +86 -0
- package/skills/vueuse-functions/references/useVirtualList.md +182 -0
- package/skills/vueuse-functions/references/useWakeLock.md +51 -0
- package/skills/vueuse-functions/references/useWebNotification.md +175 -0
- package/skills/vueuse-functions/references/useWebSocket.md +299 -0
- package/skills/vueuse-functions/references/useWebWorker.md +60 -0
- package/skills/vueuse-functions/references/useWebWorkerFn.md +102 -0
- package/skills/vueuse-functions/references/useWindowFocus.md +46 -0
- package/skills/vueuse-functions/references/useWindowScroll.md +46 -0
- package/skills/vueuse-functions/references/useWindowSize.md +78 -0
- package/skills/vueuse-functions/references/useZoomFactor.md +53 -0
- package/skills/vueuse-functions/references/useZoomLevel.md +53 -0
- package/skills/vueuse-functions/references/watchArray.md +53 -0
- package/skills/vueuse-functions/references/watchAtMost.md +63 -0
- package/skills/vueuse-functions/references/watchDebounced.md +101 -0
- package/skills/vueuse-functions/references/watchDeep.md +54 -0
- package/skills/vueuse-functions/references/watchExtractedObservable.md +192 -0
- package/skills/vueuse-functions/references/watchIgnorable.md +120 -0
- package/skills/vueuse-functions/references/watchImmediate.md +44 -0
- package/skills/vueuse-functions/references/watchOnce.md +41 -0
- package/skills/vueuse-functions/references/watchPausable.md +86 -0
- package/skills/vueuse-functions/references/watchThrottled.md +108 -0
- package/skills/vueuse-functions/references/watchTriggerable.md +98 -0
- package/skills/vueuse-functions/references/watchWithFilter.md +54 -0
- package/skills/vueuse-functions/references/whenever.md +108 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/skills/web-design-guidelines/SYNC.md +5 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: data-fetching-best-practices
|
|
3
|
+
description: Patterns and best practices for efficient data fetching in Nuxt
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Data Fetching Best Practices
|
|
7
|
+
|
|
8
|
+
Effective data fetching patterns for SSR-friendly, performant Nuxt applications.
|
|
9
|
+
|
|
10
|
+
## Choose the Right Tool
|
|
11
|
+
|
|
12
|
+
| Scenario | Use |
|
|
13
|
+
|----------|-----|
|
|
14
|
+
| Component initial data | `useFetch` or `useAsyncData` |
|
|
15
|
+
| User interactions (clicks, forms) | `$fetch` |
|
|
16
|
+
| Third-party SDK/API | `useAsyncData` with custom function |
|
|
17
|
+
| Multiple parallel requests | `useAsyncData` with `Promise.all` |
|
|
18
|
+
|
|
19
|
+
## Await vs Non-Await Usage
|
|
20
|
+
|
|
21
|
+
The `await` keyword controls whether data fetching **blocks navigation**:
|
|
22
|
+
|
|
23
|
+
### With `await` - Blocking Navigation
|
|
24
|
+
|
|
25
|
+
```vue
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
// Navigation waits until data is fetched (uses Vue Suspense)
|
|
28
|
+
const { data } = await useFetch('/api/posts')
|
|
29
|
+
// data.value is available immediately after this line
|
|
30
|
+
</script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- **Server**: Fetches data and includes it in the payload
|
|
34
|
+
- **Client hydration**: Uses payload data, no re-fetch
|
|
35
|
+
- **Client navigation**: Blocks until data is ready
|
|
36
|
+
|
|
37
|
+
### Without `await` - Non-Blocking (Lazy)
|
|
38
|
+
|
|
39
|
+
```vue
|
|
40
|
+
<script setup lang="ts">
|
|
41
|
+
// Navigation proceeds immediately, data fetches in background
|
|
42
|
+
const { data, status } = useFetch('/api/posts', { lazy: true })
|
|
43
|
+
// data.value may be undefined initially - check status!
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<div v-if="status === 'pending'">Loading...</div>
|
|
48
|
+
<div v-else>{{ data }}</div>
|
|
49
|
+
</template>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Equivalent to using `useLazyFetch`:
|
|
53
|
+
|
|
54
|
+
```vue
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
const { data, status } = useLazyFetch('/api/posts')
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### When to Use Each
|
|
61
|
+
|
|
62
|
+
| Pattern | Use Case |
|
|
63
|
+
|---------|----------|
|
|
64
|
+
| `await useFetch()` | Critical data needed for SEO/initial render |
|
|
65
|
+
| `useFetch({ lazy: true })` | Non-critical data, better perceived performance |
|
|
66
|
+
| `await useLazyFetch()` | Same as lazy, await only ensures initialization |
|
|
67
|
+
|
|
68
|
+
## Avoid Double Fetching
|
|
69
|
+
|
|
70
|
+
### ❌ Wrong: Using $fetch Alone in Setup
|
|
71
|
+
|
|
72
|
+
```vue
|
|
73
|
+
<script setup lang="ts">
|
|
74
|
+
// This fetches TWICE: once on server, once on client
|
|
75
|
+
const data = await $fetch('/api/posts')
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### ✅ Correct: Use useFetch
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<script setup lang="ts">
|
|
83
|
+
// Fetches on server, hydrates on client (no double fetch)
|
|
84
|
+
const { data } = await useFetch('/api/posts')
|
|
85
|
+
</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Use Explicit Cache Keys
|
|
89
|
+
|
|
90
|
+
### ❌ Avoid: Auto-generated Keys
|
|
91
|
+
|
|
92
|
+
```vue
|
|
93
|
+
<script setup lang="ts">
|
|
94
|
+
// Key is auto-generated from file/line - can cause issues
|
|
95
|
+
const { data } = await useAsyncData(() => fetchPosts())
|
|
96
|
+
</script>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### ✅ Better: Explicit Keys
|
|
100
|
+
|
|
101
|
+
```vue
|
|
102
|
+
<script setup lang="ts">
|
|
103
|
+
// Explicit key for predictable caching
|
|
104
|
+
const { data } = await useAsyncData(
|
|
105
|
+
'posts',
|
|
106
|
+
() => fetchPosts(),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// Dynamic keys for parameterized data
|
|
110
|
+
const route = useRoute()
|
|
111
|
+
const { data: post } = await useAsyncData(
|
|
112
|
+
`post-${route.params.id}`,
|
|
113
|
+
() => fetchPost(route.params.id),
|
|
114
|
+
)
|
|
115
|
+
</script>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Handle Loading States Properly
|
|
119
|
+
|
|
120
|
+
```vue
|
|
121
|
+
<script setup lang="ts">
|
|
122
|
+
const { data, status, error } = await useFetch('/api/posts')
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<template>
|
|
126
|
+
<div v-if="status === 'pending'">
|
|
127
|
+
<SkeletonLoader />
|
|
128
|
+
</div>
|
|
129
|
+
<div v-else-if="error">
|
|
130
|
+
<ErrorMessage :error="error" />
|
|
131
|
+
</div>
|
|
132
|
+
<div v-else>
|
|
133
|
+
<PostList :posts="data" />
|
|
134
|
+
</div>
|
|
135
|
+
</template>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Use Lazy Fetching for Non-critical Data
|
|
139
|
+
|
|
140
|
+
```vue
|
|
141
|
+
<script setup lang="ts">
|
|
142
|
+
const id = useRoute().params.id
|
|
143
|
+
|
|
144
|
+
// Critical data - blocks navigation
|
|
145
|
+
const { data: post } = await useFetch(`/api/posts/${id}`)
|
|
146
|
+
|
|
147
|
+
// Non-critical data - doesn't block navigation
|
|
148
|
+
const { data: comments, status } = useFetch(`/api/posts/${id}/comments`, {
|
|
149
|
+
lazy: true,
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Or use useLazyFetch
|
|
153
|
+
const { data: related } = useLazyFetch(`/api/posts/${id}/related`)
|
|
154
|
+
</script>
|
|
155
|
+
|
|
156
|
+
<template>
|
|
157
|
+
<article>
|
|
158
|
+
<h1>{{ post?.title }}</h1>
|
|
159
|
+
<p>{{ post?.content }}</p>
|
|
160
|
+
</article>
|
|
161
|
+
|
|
162
|
+
<section v-if="status === 'pending'">Loading comments...</section>
|
|
163
|
+
<CommentList v-else :comments="comments" />
|
|
164
|
+
</template>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Minimize Payload Size
|
|
168
|
+
|
|
169
|
+
### Use `pick` for Simple Filtering
|
|
170
|
+
|
|
171
|
+
```vue
|
|
172
|
+
<script setup lang="ts">
|
|
173
|
+
const { data } = await useFetch('/api/users', {
|
|
174
|
+
// Only include these fields in payload
|
|
175
|
+
pick: ['id', 'name', 'avatar'],
|
|
176
|
+
})
|
|
177
|
+
</script>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Use `transform` for Complex Transformations
|
|
181
|
+
|
|
182
|
+
```vue
|
|
183
|
+
<script setup lang="ts">
|
|
184
|
+
const { data } = await useFetch('/api/posts', {
|
|
185
|
+
transform: (posts) => {
|
|
186
|
+
return posts.map(post => ({
|
|
187
|
+
id: post.id,
|
|
188
|
+
title: post.title,
|
|
189
|
+
excerpt: post.content.slice(0, 100),
|
|
190
|
+
date: new Date(post.createdAt).toLocaleDateString(),
|
|
191
|
+
}))
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
</script>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Parallel Fetching
|
|
198
|
+
|
|
199
|
+
### Fetch Independent Data with useAsyncData
|
|
200
|
+
|
|
201
|
+
```vue
|
|
202
|
+
<script setup lang="ts">
|
|
203
|
+
const { data } = await useAsyncData(
|
|
204
|
+
'dashboard',
|
|
205
|
+
async (_nuxtApp, { signal }) => {
|
|
206
|
+
const [user, posts, stats] = await Promise.all([
|
|
207
|
+
$fetch('/api/user', { signal }),
|
|
208
|
+
$fetch('/api/posts', { signal }),
|
|
209
|
+
$fetch('/api/stats', { signal }),
|
|
210
|
+
])
|
|
211
|
+
return { user, posts, stats }
|
|
212
|
+
},
|
|
213
|
+
)
|
|
214
|
+
</script>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Multiple useFetch Calls
|
|
218
|
+
|
|
219
|
+
```vue
|
|
220
|
+
<script setup lang="ts">
|
|
221
|
+
// These run in parallel automatically
|
|
222
|
+
const [{ data: user }, { data: posts }] = await Promise.all([
|
|
223
|
+
useFetch('/api/user'),
|
|
224
|
+
useFetch('/api/posts'),
|
|
225
|
+
])
|
|
226
|
+
</script>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Efficient Refresh Patterns
|
|
230
|
+
|
|
231
|
+
### Watch Reactive Dependencies
|
|
232
|
+
|
|
233
|
+
```vue
|
|
234
|
+
<script setup lang="ts">
|
|
235
|
+
const page = ref(1)
|
|
236
|
+
const category = ref('all')
|
|
237
|
+
|
|
238
|
+
const { data } = await useFetch('/api/posts', {
|
|
239
|
+
query: { page, category },
|
|
240
|
+
// Auto-refresh when these change
|
|
241
|
+
watch: [page, category],
|
|
242
|
+
})
|
|
243
|
+
</script>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Manual Refresh
|
|
247
|
+
|
|
248
|
+
```vue
|
|
249
|
+
<script setup lang="ts">
|
|
250
|
+
const { data, refresh, status } = await useFetch('/api/posts')
|
|
251
|
+
|
|
252
|
+
async function refreshPosts() {
|
|
253
|
+
await refresh()
|
|
254
|
+
}
|
|
255
|
+
</script>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Conditional Fetching
|
|
259
|
+
|
|
260
|
+
```vue
|
|
261
|
+
<script setup lang="ts">
|
|
262
|
+
const userId = ref<string | null>(null)
|
|
263
|
+
|
|
264
|
+
const { data, execute } = useFetch(() => `/api/users/${userId.value}`, {
|
|
265
|
+
immediate: false, // Don't fetch until userId is set
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// Later, when userId is available
|
|
269
|
+
function loadUser(id: string) {
|
|
270
|
+
userId.value = id
|
|
271
|
+
execute()
|
|
272
|
+
}
|
|
273
|
+
</script>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Server-only Fetching
|
|
277
|
+
|
|
278
|
+
```vue
|
|
279
|
+
<script setup lang="ts">
|
|
280
|
+
// Only fetch on server, skip on client navigation
|
|
281
|
+
const { data } = await useFetch('/api/static-content', {
|
|
282
|
+
server: true,
|
|
283
|
+
lazy: true,
|
|
284
|
+
getCachedData: (key, nuxtApp) => nuxtApp.payload.data[key],
|
|
285
|
+
})
|
|
286
|
+
</script>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Error Handling
|
|
290
|
+
|
|
291
|
+
```vue
|
|
292
|
+
<script setup lang="ts">
|
|
293
|
+
const { data, error, refresh } = await useFetch('/api/posts')
|
|
294
|
+
|
|
295
|
+
// Watch for errors if need event-like handling
|
|
296
|
+
watch(error, (err) => {
|
|
297
|
+
if (err) {
|
|
298
|
+
console.error('Fetch failed:', err)
|
|
299
|
+
// Show toast, redirect, etc.
|
|
300
|
+
}
|
|
301
|
+
}, { immediate: true })
|
|
302
|
+
</script>
|
|
303
|
+
|
|
304
|
+
<template>
|
|
305
|
+
<div v-if="error">
|
|
306
|
+
<p>Failed to load: {{ error.message }}</p>
|
|
307
|
+
<button @click="refresh()">Retry</button>
|
|
308
|
+
</div>
|
|
309
|
+
</template>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Shared Data Across Components
|
|
313
|
+
|
|
314
|
+
```vue
|
|
315
|
+
<!-- ComponentA.vue -->
|
|
316
|
+
<script setup lang="ts">
|
|
317
|
+
const { data } = await useFetch('/api/user', { key: 'current-user' })
|
|
318
|
+
</script>
|
|
319
|
+
|
|
320
|
+
<!-- ComponentB.vue -->
|
|
321
|
+
<script setup lang="ts">
|
|
322
|
+
// Access cached data without refetching
|
|
323
|
+
const { data: user } = useNuxtData('current-user')
|
|
324
|
+
|
|
325
|
+
// Or refresh it
|
|
326
|
+
const { refresh } = await useFetch('/api/user', { key: 'current-user' })
|
|
327
|
+
</script>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Avoid useAsyncData for Side Effects
|
|
331
|
+
|
|
332
|
+
### ❌ Wrong: Side Effects in useAsyncData
|
|
333
|
+
|
|
334
|
+
```vue
|
|
335
|
+
<script setup lang="ts">
|
|
336
|
+
// Don't trigger Pinia actions or side effects
|
|
337
|
+
await useAsyncData(() => store.fetchUser()) // Can cause issues
|
|
338
|
+
</script>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### ✅ Correct: Use callOnce for Side Effects
|
|
342
|
+
|
|
343
|
+
```vue
|
|
344
|
+
<script setup lang="ts">
|
|
345
|
+
await callOnce(async () => {
|
|
346
|
+
await store.fetchUser()
|
|
347
|
+
})
|
|
348
|
+
</script>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
<!--
|
|
352
|
+
Source references:
|
|
353
|
+
- https://nuxt.com/docs/getting-started/data-fetching
|
|
354
|
+
- https://nuxt.com/docs/api/composables/use-fetch
|
|
355
|
+
- https://nuxt.com/docs/api/composables/use-async-data
|
|
356
|
+
- https://nuxt.com/docs/api/composables/use-lazy-fetch
|
|
357
|
+
-->
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ssr-best-practices
|
|
3
|
+
description: Avoiding SSR context leaks, hydration mismatches, and proper composable usage
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SSR Best Practices
|
|
7
|
+
|
|
8
|
+
Patterns for avoiding common SSR pitfalls: context leaks, hydration mismatches, and composable errors.
|
|
9
|
+
|
|
10
|
+
## The "Nuxt Instance Unavailable" Error
|
|
11
|
+
|
|
12
|
+
This error occurs when calling Nuxt composables outside the proper context.
|
|
13
|
+
|
|
14
|
+
### ❌ Wrong: Composable Outside Setup
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// composables/bad.ts
|
|
18
|
+
// Called at module level - no Nuxt context!
|
|
19
|
+
const config = useRuntimeConfig()
|
|
20
|
+
|
|
21
|
+
export function useMyComposable() {
|
|
22
|
+
return config.public.apiBase
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### ✅ Correct: Composable Inside Function
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// composables/good.ts
|
|
30
|
+
export function useMyComposable() {
|
|
31
|
+
// Called inside the composable - has context
|
|
32
|
+
const config = useRuntimeConfig()
|
|
33
|
+
return config.public.apiBase
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Valid Contexts for Composables
|
|
38
|
+
|
|
39
|
+
Nuxt composables work in:
|
|
40
|
+
- `<script setup>` blocks
|
|
41
|
+
- `setup()` function
|
|
42
|
+
- `defineNuxtPlugin()` callbacks
|
|
43
|
+
- `defineNuxtRouteMiddleware()` callbacks
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// ✅ Plugin
|
|
47
|
+
export default defineNuxtPlugin(() => {
|
|
48
|
+
const config = useRuntimeConfig() // Works
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// ✅ Middleware
|
|
52
|
+
export default defineNuxtRouteMiddleware(() => {
|
|
53
|
+
const route = useRoute() // Works
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Avoid State Leaks Between Requests
|
|
58
|
+
|
|
59
|
+
### ❌ Wrong: Module-level State
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// composables/bad.ts
|
|
63
|
+
// This state is SHARED between all requests on server!
|
|
64
|
+
const globalState = ref({ user: null })
|
|
65
|
+
|
|
66
|
+
export function useUser() {
|
|
67
|
+
return globalState
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### ✅ Correct: Use useState
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// composables/good.ts
|
|
75
|
+
export function useUser() {
|
|
76
|
+
// useState creates request-isolated state
|
|
77
|
+
return useState('user', () => ({ user: null }))
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Why This Matters
|
|
82
|
+
|
|
83
|
+
On the server, module-level state persists across requests, causing:
|
|
84
|
+
- Data leaking between users
|
|
85
|
+
- Security vulnerabilities
|
|
86
|
+
- Memory leaks
|
|
87
|
+
|
|
88
|
+
## Hydration Mismatch Prevention
|
|
89
|
+
|
|
90
|
+
Hydration mismatches occur when server HTML differs from client render.
|
|
91
|
+
|
|
92
|
+
### ❌ Wrong: Browser APIs in Setup
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<script setup>
|
|
96
|
+
// localStorage doesn't exist on server!
|
|
97
|
+
const theme = localStorage.getItem('theme') || 'light'
|
|
98
|
+
</script>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### ✅ Correct: Use SSR-safe Alternatives
|
|
102
|
+
|
|
103
|
+
```vue
|
|
104
|
+
<script setup>
|
|
105
|
+
// useCookie works on both server and client
|
|
106
|
+
const theme = useCookie('theme', { default: () => 'light' })
|
|
107
|
+
</script>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### ❌ Wrong: Random/Time-based Values
|
|
111
|
+
|
|
112
|
+
```vue
|
|
113
|
+
<template>
|
|
114
|
+
<div>{{ Math.random() }}</div>
|
|
115
|
+
<div>{{ new Date().toLocaleTimeString() }}</div>
|
|
116
|
+
</template>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### ✅ Correct: Use useState for Consistency
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<script setup>
|
|
123
|
+
// Value is generated once on server, hydrated on client
|
|
124
|
+
const randomValue = useState('random', () => Math.random())
|
|
125
|
+
</script>
|
|
126
|
+
|
|
127
|
+
<template>
|
|
128
|
+
<div>{{ randomValue }}</div>
|
|
129
|
+
</template>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### ❌ Wrong: Conditional Rendering on Client State
|
|
133
|
+
|
|
134
|
+
```vue
|
|
135
|
+
<template>
|
|
136
|
+
<!-- window doesn't exist on server -->
|
|
137
|
+
<div v-if="window?.innerWidth > 768">Desktop</div>
|
|
138
|
+
</template>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### ✅ Correct: Use CSS or ClientOnly
|
|
142
|
+
|
|
143
|
+
```vue
|
|
144
|
+
<template>
|
|
145
|
+
<!-- CSS media queries work on both -->
|
|
146
|
+
<div class="hidden md:block">Desktop</div>
|
|
147
|
+
<div class="md:hidden">Mobile</div>
|
|
148
|
+
|
|
149
|
+
<!-- Or use ClientOnly for JS-dependent rendering -->
|
|
150
|
+
<ClientOnly>
|
|
151
|
+
<ResponsiveComponent />
|
|
152
|
+
<template #fallback>Loading...</template>
|
|
153
|
+
</ClientOnly>
|
|
154
|
+
</template>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Browser-only Code
|
|
158
|
+
|
|
159
|
+
### Use `import.meta.client`
|
|
160
|
+
|
|
161
|
+
```vue
|
|
162
|
+
<script setup>
|
|
163
|
+
if (import.meta.client) {
|
|
164
|
+
// Only runs in browser
|
|
165
|
+
window.addEventListener('scroll', handleScroll)
|
|
166
|
+
}
|
|
167
|
+
</script>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Use `onMounted` for DOM Access
|
|
171
|
+
|
|
172
|
+
```vue
|
|
173
|
+
<script setup>
|
|
174
|
+
const el = ref<HTMLElement>()
|
|
175
|
+
|
|
176
|
+
onMounted(() => {
|
|
177
|
+
// Safe - only runs on client after hydration
|
|
178
|
+
el.value?.focus()
|
|
179
|
+
initThirdPartyLib()
|
|
180
|
+
})
|
|
181
|
+
</script>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Dynamic Imports for Browser Libraries
|
|
185
|
+
|
|
186
|
+
```vue
|
|
187
|
+
<script setup>
|
|
188
|
+
onMounted(async () => {
|
|
189
|
+
const { Chart } = await import('chart.js')
|
|
190
|
+
new Chart(canvas.value, config)
|
|
191
|
+
})
|
|
192
|
+
</script>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Server-only Code
|
|
196
|
+
|
|
197
|
+
### Use `import.meta.server`
|
|
198
|
+
|
|
199
|
+
```vue
|
|
200
|
+
<script setup>
|
|
201
|
+
if (import.meta.server) {
|
|
202
|
+
// Only runs on server
|
|
203
|
+
const secrets = useRuntimeConfig().apiSecret
|
|
204
|
+
}
|
|
205
|
+
</script>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Server Components
|
|
209
|
+
|
|
210
|
+
```vue
|
|
211
|
+
<!-- components/ServerData.server.vue -->
|
|
212
|
+
<script setup>
|
|
213
|
+
// This entire component only runs on server
|
|
214
|
+
const data = await fetchSensitiveData()
|
|
215
|
+
</script>
|
|
216
|
+
|
|
217
|
+
<template>
|
|
218
|
+
<div>{{ data }}</div>
|
|
219
|
+
</template>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Async Composable Patterns
|
|
223
|
+
|
|
224
|
+
### ❌ Wrong: Await Before Composable
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<script setup>
|
|
228
|
+
await someAsyncOperation()
|
|
229
|
+
const route = useRoute() // May fail - context lost after await
|
|
230
|
+
</script>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### ✅ Correct: Get Context First
|
|
234
|
+
|
|
235
|
+
```vue
|
|
236
|
+
<script setup>
|
|
237
|
+
// Get all composables before any await
|
|
238
|
+
const route = useRoute()
|
|
239
|
+
const config = useRuntimeConfig()
|
|
240
|
+
|
|
241
|
+
await someAsyncOperation()
|
|
242
|
+
// Now safe to use route and config
|
|
243
|
+
</script>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Plugin Best Practices
|
|
247
|
+
|
|
248
|
+
### Client-only Plugins
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
// plugins/analytics.client.ts
|
|
252
|
+
export default defineNuxtPlugin(() => {
|
|
253
|
+
// Only runs on client
|
|
254
|
+
initAnalytics()
|
|
255
|
+
})
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Server-only Plugins
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
// plugins/server-init.server.ts
|
|
262
|
+
export default defineNuxtPlugin(() => {
|
|
263
|
+
// Only runs on server
|
|
264
|
+
initServerConnections()
|
|
265
|
+
})
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Provide/Inject Pattern
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
// plugins/api.ts
|
|
272
|
+
export default defineNuxtPlugin(() => {
|
|
273
|
+
const api = createApiClient()
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
provide: {
|
|
277
|
+
api,
|
|
278
|
+
},
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
```vue
|
|
284
|
+
<script setup>
|
|
285
|
+
const { $api } = useNuxtApp()
|
|
286
|
+
const data = await $api.get('/users')
|
|
287
|
+
</script>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Third-party Library Integration
|
|
291
|
+
|
|
292
|
+
### ❌ Wrong: Import at Top Level
|
|
293
|
+
|
|
294
|
+
```vue
|
|
295
|
+
<script setup>
|
|
296
|
+
import SomeLibrary from 'browser-only-lib' // Breaks SSR
|
|
297
|
+
</script>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### ✅ Correct: Dynamic Import
|
|
301
|
+
|
|
302
|
+
```vue
|
|
303
|
+
<script setup>
|
|
304
|
+
let library: typeof import('browser-only-lib')
|
|
305
|
+
|
|
306
|
+
onMounted(async () => {
|
|
307
|
+
library = await import('browser-only-lib')
|
|
308
|
+
library.init()
|
|
309
|
+
})
|
|
310
|
+
</script>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Use ClientOnly Component
|
|
314
|
+
|
|
315
|
+
```vue
|
|
316
|
+
<template>
|
|
317
|
+
<ClientOnly>
|
|
318
|
+
<BrowserOnlyComponent />
|
|
319
|
+
<template #fallback>
|
|
320
|
+
<div class="skeleton">Loading...</div>
|
|
321
|
+
</template>
|
|
322
|
+
</ClientOnly>
|
|
323
|
+
</template>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Debugging SSR Issues
|
|
327
|
+
|
|
328
|
+
### Check Rendering Context
|
|
329
|
+
|
|
330
|
+
```vue
|
|
331
|
+
<script setup>
|
|
332
|
+
console.log('Server:', import.meta.server)
|
|
333
|
+
console.log('Client:', import.meta.client)
|
|
334
|
+
</script>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Use Nuxt DevTools
|
|
338
|
+
|
|
339
|
+
DevTools shows payload data and hydration state.
|
|
340
|
+
|
|
341
|
+
### Common Error Messages
|
|
342
|
+
|
|
343
|
+
| Error | Cause |
|
|
344
|
+
|-------|-------|
|
|
345
|
+
| "Nuxt instance unavailable" | Composable called outside setup context |
|
|
346
|
+
| "Hydration mismatch" | Server/client HTML differs |
|
|
347
|
+
| "window is not defined" | Browser API used during SSR |
|
|
348
|
+
| "document is not defined" | DOM access during SSR |
|
|
349
|
+
|
|
350
|
+
<!--
|
|
351
|
+
Source references:
|
|
352
|
+
- https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables
|
|
353
|
+
- https://nuxt.com/docs/guide/best-practices/hydration
|
|
354
|
+
- https://nuxt.com/docs/getting-started/state-management#best-practices
|
|
355
|
+
-->
|