cfsa-antigravity 1.0.0
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/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs
|
|
3
|
+
description: "Comprehensive Next.js App Router guide covering server/client components, data fetching, rendering strategies, middleware, optimization, and deployment. Use when building Next.js applications, choosing rendering strategies, implementing data fetching patterns, or configuring deployment."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Next.js Framework
|
|
8
|
+
|
|
9
|
+
## 1. App Router Architecture
|
|
10
|
+
|
|
11
|
+
### Directory Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
app/
|
|
15
|
+
layout.tsx # Root layout (wraps entire app)
|
|
16
|
+
page.tsx # Home page (/)
|
|
17
|
+
loading.tsx # Loading UI for the root segment
|
|
18
|
+
error.tsx # Error boundary for the root segment
|
|
19
|
+
not-found.tsx # 404 page
|
|
20
|
+
global-error.tsx # Global error boundary (catches layout errors)
|
|
21
|
+
dashboard/
|
|
22
|
+
layout.tsx # Nested layout for /dashboard/*
|
|
23
|
+
page.tsx # /dashboard
|
|
24
|
+
loading.tsx # Loading UI for dashboard segment
|
|
25
|
+
settings/
|
|
26
|
+
page.tsx # /dashboard/settings
|
|
27
|
+
blog/
|
|
28
|
+
page.tsx # /blog
|
|
29
|
+
[slug]/
|
|
30
|
+
page.tsx # /blog/:slug (dynamic segment)
|
|
31
|
+
api/
|
|
32
|
+
users/
|
|
33
|
+
route.ts # API route: /api/users
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Layouts
|
|
37
|
+
|
|
38
|
+
Layouts wrap child segments and preserve state across navigations. The root layout is required and must contain `<html>` and `<body>` tags.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// app/layout.tsx -- Root layout (required)
|
|
42
|
+
import { type Metadata } from 'next';
|
|
43
|
+
|
|
44
|
+
export const metadata: Metadata = {
|
|
45
|
+
title: { default: 'My App', template: '%s | My App' },
|
|
46
|
+
description: 'Application description',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
50
|
+
return (
|
|
51
|
+
<html lang="en">
|
|
52
|
+
<body>{children}</body>
|
|
53
|
+
</html>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// app/dashboard/layout.tsx -- Nested layout
|
|
58
|
+
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
|
|
59
|
+
return (
|
|
60
|
+
<div className="flex">
|
|
61
|
+
<nav className="w-64 border-r"><DashboardNav /></nav>
|
|
62
|
+
<main className="flex-1 p-6">{children}</main>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Loading and Error Boundaries
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
// app/dashboard/loading.tsx -- Shown while page.tsx is loading
|
|
72
|
+
export default function Loading() {
|
|
73
|
+
return <div className="animate-pulse">Loading dashboard...</div>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// app/dashboard/error.tsx -- Catches errors in dashboard segment
|
|
77
|
+
'use client'; // Error boundaries must be client components
|
|
78
|
+
|
|
79
|
+
import { useEffect } from 'react';
|
|
80
|
+
|
|
81
|
+
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
|
|
82
|
+
useEffect(() => { console.error(error); }, [error]);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div>
|
|
86
|
+
<h2>Something went wrong</h2>
|
|
87
|
+
<button onClick={() => reset()}>Try again</button>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 2. Server Components vs Client Components
|
|
96
|
+
|
|
97
|
+
**Server Components** are the default. They run only on the server, can access databases and filesystems directly, and ship zero JavaScript to the client.
|
|
98
|
+
|
|
99
|
+
**Client Components** are declared with `'use client'` at the top of the file. They run on both server (for SSR) and client. Use them when you need interactivity, browser APIs, or React hooks.
|
|
100
|
+
|
|
101
|
+
### Decision Guide
|
|
102
|
+
|
|
103
|
+
| Need | Component Type |
|
|
104
|
+
|------|---------------|
|
|
105
|
+
| Fetch data, access DB, read files | Server |
|
|
106
|
+
| Display static content | Server |
|
|
107
|
+
| Use `useState`, `useEffect`, `useRef` | Client |
|
|
108
|
+
| Event handlers (`onClick`, `onChange`) | Client |
|
|
109
|
+
| Browser APIs (`localStorage`, `window`) | Client |
|
|
110
|
+
| Third-party hooks (e.g., `useQuery`) | Client |
|
|
111
|
+
| Context providers | Client |
|
|
112
|
+
|
|
113
|
+
### The "use client" Boundary
|
|
114
|
+
|
|
115
|
+
`'use client'` marks a boundary. Everything imported into a client component file also becomes client code. Push the boundary as deep as possible.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// BAD: Entire page is client-side
|
|
119
|
+
'use client';
|
|
120
|
+
export default function ProductPage() {
|
|
121
|
+
const [count, setCount] = useState(0);
|
|
122
|
+
const products = useQuery(...); // Data fetch on client
|
|
123
|
+
return <div>{products.map(...)}<button onClick={() => setCount(c => c + 1)}>{count}</button></div>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// GOOD: Server component fetches data, only the interactive part is client
|
|
127
|
+
// app/products/page.tsx (Server Component -- no 'use client')
|
|
128
|
+
import { AddToCartButton } from './add-to-cart-button';
|
|
129
|
+
|
|
130
|
+
export default async function ProductPage() {
|
|
131
|
+
const products = await db.query.products.findMany(); // Server-side fetch
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div>
|
|
135
|
+
{products.map((p) => (
|
|
136
|
+
<div key={p.id}>
|
|
137
|
+
<h2>{p.name}</h2>
|
|
138
|
+
<p>{p.description}</p>
|
|
139
|
+
<AddToCartButton productId={p.id} /> {/* Client boundary here */}
|
|
140
|
+
</div>
|
|
141
|
+
))}
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// app/products/add-to-cart-button.tsx (Client Component)
|
|
147
|
+
'use client';
|
|
148
|
+
import { useState } from 'react';
|
|
149
|
+
|
|
150
|
+
export function AddToCartButton({ productId }: { productId: string }) {
|
|
151
|
+
const [added, setAdded] = useState(false);
|
|
152
|
+
return <button onClick={() => { addToCart(productId); setAdded(true); }}>{added ? 'Added' : 'Add to Cart'}</button>;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Passing Server Data to Client Components
|
|
157
|
+
|
|
158
|
+
Server components can pass serializable data as props to client components. You cannot pass functions, Dates (serialize them), or class instances.
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// Server Component
|
|
162
|
+
const user = await getUser(); // { id, name, createdAt: Date }
|
|
163
|
+
|
|
164
|
+
// Pass serializable data
|
|
165
|
+
<ClientProfile user={{ id: user.id, name: user.name, createdAt: user.createdAt.toISOString() }} />
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 3. Data Fetching
|
|
171
|
+
|
|
172
|
+
### Server Components (Primary Pattern)
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// Direct database/API access in server components -- no useEffect needed
|
|
176
|
+
export default async function UsersPage() {
|
|
177
|
+
const users = await db.query.users.findMany({
|
|
178
|
+
where: eq(users.active, true),
|
|
179
|
+
limit: 50,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
return <UserList users={users} />;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Server Actions
|
|
187
|
+
|
|
188
|
+
Server Actions are async functions that run on the server, callable from client components.
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
// app/actions/user.ts
|
|
192
|
+
'use server';
|
|
193
|
+
|
|
194
|
+
import { revalidatePath } from 'next/cache';
|
|
195
|
+
import { z } from 'zod';
|
|
196
|
+
|
|
197
|
+
const UpdateProfileSchema = z.object({
|
|
198
|
+
name: z.string().min(1).max(100),
|
|
199
|
+
bio: z.string().max(500).optional(),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
export async function updateProfile(formData: FormData) {
|
|
203
|
+
const parsed = UpdateProfileSchema.safeParse({
|
|
204
|
+
name: formData.get('name'),
|
|
205
|
+
bio: formData.get('bio'),
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
if (!parsed.success) {
|
|
209
|
+
return { error: parsed.error.flatten().fieldErrors };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
await db.update(users).set(parsed.data).where(eq(users.id, currentUserId));
|
|
213
|
+
revalidatePath('/profile');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Usage in client component
|
|
217
|
+
'use client';
|
|
218
|
+
import { updateProfile } from '@/app/actions/user';
|
|
219
|
+
import { useActionState } from 'react';
|
|
220
|
+
|
|
221
|
+
export function ProfileForm() {
|
|
222
|
+
const [state, action, pending] = useActionState(updateProfile, null);
|
|
223
|
+
|
|
224
|
+
return (
|
|
225
|
+
<form action={action}>
|
|
226
|
+
<input name="name" required />
|
|
227
|
+
{state?.error?.name && <p className="text-red-500">{state.error.name}</p>}
|
|
228
|
+
<button type="submit" disabled={pending}>
|
|
229
|
+
{pending ? 'Saving...' : 'Save'}
|
|
230
|
+
</button>
|
|
231
|
+
</form>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Route Handlers
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
// app/api/users/route.ts
|
|
240
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
241
|
+
import { z } from 'zod';
|
|
242
|
+
|
|
243
|
+
const CreateUserSchema = z.object({
|
|
244
|
+
email: z.string().email(),
|
|
245
|
+
name: z.string().min(1),
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
export async function GET(request: NextRequest) {
|
|
249
|
+
const { searchParams } = request.nextUrl;
|
|
250
|
+
const page = parseInt(searchParams.get('page') ?? '1', 10);
|
|
251
|
+
const users = await db.query.users.findMany({ limit: 20, offset: (page - 1) * 20 });
|
|
252
|
+
return NextResponse.json(users);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export async function POST(request: NextRequest) {
|
|
256
|
+
const body = await request.json();
|
|
257
|
+
const parsed = CreateUserSchema.safeParse(body);
|
|
258
|
+
|
|
259
|
+
if (!parsed.success) {
|
|
260
|
+
return NextResponse.json({ errors: parsed.error.flatten().fieldErrors }, { status: 422 });
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const user = await db.insert(users).values(parsed.data).returning();
|
|
264
|
+
return NextResponse.json(user, { status: 201 });
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Fetch with Caching and Revalidation
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
// Cache indefinitely (default in app router)
|
|
272
|
+
const data = await fetch('https://api.example.com/data');
|
|
273
|
+
|
|
274
|
+
// Revalidate every 60 seconds (ISR)
|
|
275
|
+
const data = await fetch('https://api.example.com/data', { next: { revalidate: 60 } });
|
|
276
|
+
|
|
277
|
+
// Never cache (dynamic data)
|
|
278
|
+
const data = await fetch('https://api.example.com/data', { cache: 'no-store' });
|
|
279
|
+
|
|
280
|
+
// Revalidate by tag
|
|
281
|
+
const data = await fetch('https://api.example.com/products', { next: { tags: ['products'] } });
|
|
282
|
+
|
|
283
|
+
// In a server action:
|
|
284
|
+
import { revalidateTag } from 'next/cache';
|
|
285
|
+
revalidateTag('products');
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 4. Rendering Strategies
|
|
291
|
+
|
|
292
|
+
| Strategy | When | How |
|
|
293
|
+
|----------|------|-----|
|
|
294
|
+
| **Static (SSG)** | Content known at build time | Default for pages with no dynamic data |
|
|
295
|
+
| **ISR** | Content changes occasionally | `fetch` with `next: { revalidate: N }` |
|
|
296
|
+
| **SSR** | Content changes per-request | `cookies()`, `headers()`, `searchParams`, `cache: 'no-store'` |
|
|
297
|
+
| **Streaming** | Large pages, progressive rendering | `loading.tsx` or `<Suspense>` boundaries |
|
|
298
|
+
|
|
299
|
+
### Force Dynamic or Static
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
// Force dynamic rendering
|
|
303
|
+
export const dynamic = 'force-dynamic';
|
|
304
|
+
|
|
305
|
+
// Force static rendering
|
|
306
|
+
export const dynamic = 'force-static';
|
|
307
|
+
|
|
308
|
+
// Set revalidation interval for the entire route
|
|
309
|
+
export const revalidate = 3600; // seconds
|
|
310
|
+
|
|
311
|
+
// Generate static params for dynamic routes
|
|
312
|
+
export async function generateStaticParams() {
|
|
313
|
+
const posts = await db.query.posts.findMany({ columns: { slug: true } });
|
|
314
|
+
return posts.map((post) => ({ slug: post.slug }));
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Streaming with Suspense
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
import { Suspense } from 'react';
|
|
322
|
+
|
|
323
|
+
export default function DashboardPage() {
|
|
324
|
+
return (
|
|
325
|
+
<div>
|
|
326
|
+
<h1>Dashboard</h1>
|
|
327
|
+
{/* Shows immediately */}
|
|
328
|
+
<Suspense fallback={<StatsSkeleton />}>
|
|
329
|
+
<DashboardStats /> {/* Streams in when ready */}
|
|
330
|
+
</Suspense>
|
|
331
|
+
<Suspense fallback={<ChartSkeleton />}>
|
|
332
|
+
<RevenueChart /> {/* Streams independently */}
|
|
333
|
+
</Suspense>
|
|
334
|
+
</div>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Each component can be an async server component
|
|
339
|
+
async function DashboardStats() {
|
|
340
|
+
const stats = await getStats(); // Slow query
|
|
341
|
+
return <StatsGrid data={stats} />;
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 5. Middleware
|
|
348
|
+
|
|
349
|
+
Middleware runs before every request. Use it for auth checks, redirects, headers, and geolocation.
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
// middleware.ts (must be at project root or src/)
|
|
353
|
+
import { NextResponse, type NextRequest } from 'next/server';
|
|
354
|
+
|
|
355
|
+
export function middleware(request: NextRequest) {
|
|
356
|
+
const { pathname } = request.nextUrl;
|
|
357
|
+
|
|
358
|
+
// Auth check
|
|
359
|
+
const token = request.cookies.get('session')?.value;
|
|
360
|
+
if (pathname.startsWith('/dashboard') && !token) {
|
|
361
|
+
return NextResponse.redirect(new URL('/login', request.url));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Add custom headers
|
|
365
|
+
const response = NextResponse.next();
|
|
366
|
+
response.headers.set('x-request-id', crypto.randomUUID());
|
|
367
|
+
|
|
368
|
+
// Geolocation-based redirect
|
|
369
|
+
const country = request.geo?.country;
|
|
370
|
+
if (pathname === '/' && country === 'DE') {
|
|
371
|
+
return NextResponse.redirect(new URL('/de', request.url));
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return response;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Only run middleware on specific paths
|
|
378
|
+
export const config = {
|
|
379
|
+
matcher: [
|
|
380
|
+
// Match all paths except static files and api routes
|
|
381
|
+
'/((?!_next/static|_next/image|favicon.ico|api).*)',
|
|
382
|
+
],
|
|
383
|
+
};
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 6. Image and Font Optimization
|
|
389
|
+
|
|
390
|
+
### Images
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
import Image from 'next/image';
|
|
394
|
+
|
|
395
|
+
// Local image (automatically optimized, dimensions inferred)
|
|
396
|
+
import heroImage from '@/public/hero.jpg';
|
|
397
|
+
<Image src={heroImage} alt="Hero" priority />
|
|
398
|
+
|
|
399
|
+
// Remote image (must configure domains in next.config)
|
|
400
|
+
<Image
|
|
401
|
+
src="https://cdn.example.com/photo.jpg"
|
|
402
|
+
alt="Photo"
|
|
403
|
+
width={800}
|
|
404
|
+
height={600}
|
|
405
|
+
sizes="(max-width: 768px) 100vw, 50vw"
|
|
406
|
+
/>
|
|
407
|
+
|
|
408
|
+
// Fill mode (for unknown dimensions)
|
|
409
|
+
<div className="relative w-full aspect-video">
|
|
410
|
+
<Image src={src} alt={alt} fill className="object-cover" sizes="100vw" />
|
|
411
|
+
</div>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Fonts
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
// app/layout.tsx
|
|
418
|
+
import { Inter, JetBrains_Mono } from 'next/font/google';
|
|
419
|
+
|
|
420
|
+
const inter = Inter({ subsets: ['latin'], variable: '--font-inter' });
|
|
421
|
+
const mono = JetBrains_Mono({ subsets: ['latin'], variable: '--font-mono' });
|
|
422
|
+
|
|
423
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
424
|
+
return (
|
|
425
|
+
<html lang="en" className={`${inter.variable} ${mono.variable}`}>
|
|
426
|
+
<body className="font-sans">{children}</body>
|
|
427
|
+
</html>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## 7. Metadata and SEO
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
// Static metadata
|
|
438
|
+
export const metadata: Metadata = {
|
|
439
|
+
title: 'About Us',
|
|
440
|
+
description: 'Learn about our company',
|
|
441
|
+
openGraph: {
|
|
442
|
+
title: 'About Us',
|
|
443
|
+
description: 'Learn about our company',
|
|
444
|
+
images: [{ url: '/og-about.png', width: 1200, height: 630 }],
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// Dynamic metadata
|
|
449
|
+
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
|
|
450
|
+
const { slug } = await params;
|
|
451
|
+
const post = await getPost(slug);
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
title: post.title,
|
|
455
|
+
description: post.excerpt,
|
|
456
|
+
openGraph: { images: [post.coverImage] },
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## 8. Parallel and Intercepting Routes
|
|
464
|
+
|
|
465
|
+
### Parallel Routes
|
|
466
|
+
|
|
467
|
+
Render multiple pages simultaneously in the same layout using named slots.
|
|
468
|
+
|
|
469
|
+
```
|
|
470
|
+
app/
|
|
471
|
+
@analytics/
|
|
472
|
+
page.tsx # Renders in the analytics slot
|
|
473
|
+
@team/
|
|
474
|
+
page.tsx # Renders in the team slot
|
|
475
|
+
layout.tsx # Receives both slots as props
|
|
476
|
+
page.tsx
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
```tsx
|
|
480
|
+
// app/layout.tsx
|
|
481
|
+
export default function Layout({
|
|
482
|
+
children,
|
|
483
|
+
analytics,
|
|
484
|
+
team,
|
|
485
|
+
}: {
|
|
486
|
+
children: React.ReactNode;
|
|
487
|
+
analytics: React.ReactNode;
|
|
488
|
+
team: React.ReactNode;
|
|
489
|
+
}) {
|
|
490
|
+
return (
|
|
491
|
+
<div>
|
|
492
|
+
{children}
|
|
493
|
+
<div className="grid grid-cols-2 gap-4">
|
|
494
|
+
{analytics}
|
|
495
|
+
{team}
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Intercepting Routes
|
|
503
|
+
|
|
504
|
+
Show a route in a modal while preserving context. Uses `(.)`, `(..)`, `(..)(..)`, or `(...)` conventions.
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
app/
|
|
508
|
+
feed/
|
|
509
|
+
page.tsx # Feed page
|
|
510
|
+
@modal/
|
|
511
|
+
(.)photo/[id]/
|
|
512
|
+
page.tsx # Intercepts /photo/:id when navigating from /feed
|
|
513
|
+
photo/[id]/
|
|
514
|
+
page.tsx # Direct access to /photo/:id (full page)
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## 9. Environment Variables
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
# .env.local (never committed)
|
|
523
|
+
DATABASE_URL=postgresql://... # Server-only (no prefix)
|
|
524
|
+
API_SECRET=sk_live_... # Server-only
|
|
525
|
+
|
|
526
|
+
NEXT_PUBLIC_API_URL=https://api.example.com # Available in browser
|
|
527
|
+
NEXT_PUBLIC_APP_NAME=MyApp # Available in browser
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Rule**: Variables without `NEXT_PUBLIC_` are server-only. They are never bundled into client JavaScript. Variables with `NEXT_PUBLIC_` are inlined into the client bundle at build time.
|
|
531
|
+
|
|
532
|
+
```tsx
|
|
533
|
+
// Server component or route handler -- works
|
|
534
|
+
const dbUrl = process.env.DATABASE_URL;
|
|
535
|
+
|
|
536
|
+
// Client component -- undefined (server-only variable)
|
|
537
|
+
const dbUrl = process.env.DATABASE_URL; // undefined
|
|
538
|
+
|
|
539
|
+
// Client component -- works (has NEXT_PUBLIC_ prefix)
|
|
540
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## 10. Deployment
|
|
546
|
+
|
|
547
|
+
### Vercel (Recommended)
|
|
548
|
+
|
|
549
|
+
Zero-config deployment. Supports all Next.js features natively.
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
# Install Vercel CLI
|
|
553
|
+
npm i -g vercel
|
|
554
|
+
|
|
555
|
+
# Deploy
|
|
556
|
+
vercel
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Self-Hosted with Docker
|
|
560
|
+
|
|
561
|
+
```dockerfile
|
|
562
|
+
FROM node:20-alpine AS base
|
|
563
|
+
|
|
564
|
+
FROM base AS deps
|
|
565
|
+
WORKDIR /app
|
|
566
|
+
COPY package.json pnpm-lock.yaml ./
|
|
567
|
+
RUN corepack enable pnpm && pnpm install --frozen-lockfile
|
|
568
|
+
|
|
569
|
+
FROM base AS builder
|
|
570
|
+
WORKDIR /app
|
|
571
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
572
|
+
COPY . .
|
|
573
|
+
RUN corepack enable pnpm && pnpm build
|
|
574
|
+
|
|
575
|
+
FROM base AS runner
|
|
576
|
+
WORKDIR /app
|
|
577
|
+
ENV NODE_ENV=production
|
|
578
|
+
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs
|
|
579
|
+
COPY --from=builder /app/public ./public
|
|
580
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
581
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
582
|
+
USER nextjs
|
|
583
|
+
EXPOSE 3000
|
|
584
|
+
ENV PORT=3000
|
|
585
|
+
CMD ["node", "server.js"]
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
```js
|
|
589
|
+
// next.config.ts -- enable standalone output for Docker
|
|
590
|
+
import type { NextConfig } from 'next';
|
|
591
|
+
const config: NextConfig = { output: 'standalone' };
|
|
592
|
+
export default config;
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## 11. Common Anti-Patterns
|
|
598
|
+
|
|
599
|
+
| Anti-Pattern | Why It's Wrong | Correct Approach |
|
|
600
|
+
|-------------|---------------|-----------------|
|
|
601
|
+
| `'use client'` on every component | Ships unnecessary JS, loses server rendering | Default to server components, add `'use client'` only for interactivity |
|
|
602
|
+
| `useEffect` for data fetching | Causes loading spinners, waterfalls, no SEO | Fetch in server components or use Server Actions |
|
|
603
|
+
| Putting secrets in `NEXT_PUBLIC_` vars | Exposes secrets in client bundle | Use non-prefixed env vars, access in server code only |
|
|
604
|
+
| Giant `layout.tsx` with all providers | Makes entire subtree client-rendered | Create a `providers.tsx` client component, keep layout as server |
|
|
605
|
+
| `fetch` in client components for initial data | Double renders, no streaming, poor UX | Fetch in server components, pass as props |
|
|
606
|
+
| Ignoring `loading.tsx` | Users see blank pages during navigation | Add `loading.tsx` for instant feedback |
|
|
607
|
+
| Not setting `sizes` on `<Image>` | Downloads oversized images | Always set `sizes` for responsive images |
|
|
608
|
+
| Using `router.push` for simple navigation | Loses prefetching, adds client JS | Use `<Link href="...">` for navigation |
|
|
609
|
+
| Catching errors only in `global-error.tsx` | Loses the layout, poor UX | Add `error.tsx` at each segment level |
|
|
610
|
+
| Mixing Pages Router and App Router patterns | Confusing, inconsistent behavior | Commit to App Router for new projects |
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## 12. Critical Reminders
|
|
615
|
+
|
|
616
|
+
### ALWAYS
|
|
617
|
+
|
|
618
|
+
- Default to Server Components; add `'use client'` only when needed
|
|
619
|
+
- Validate all inputs with Zod in Server Actions and Route Handlers
|
|
620
|
+
- Use `<Link>` for navigation (enables prefetching)
|
|
621
|
+
- Add `loading.tsx` and `error.tsx` at appropriate segment levels
|
|
622
|
+
- Set `sizes` prop on all `<Image>` components
|
|
623
|
+
- Use `revalidatePath` or `revalidateTag` after mutations
|
|
624
|
+
- Keep `'use client'` boundary as deep in the component tree as possible
|
|
625
|
+
- Use `Suspense` boundaries for progressive streaming
|
|
626
|
+
|
|
627
|
+
### NEVER
|
|
628
|
+
|
|
629
|
+
- Put database credentials or API secrets in `NEXT_PUBLIC_` variables
|
|
630
|
+
- Use `useEffect` + `fetch` when a server component can do the fetch
|
|
631
|
+
- Mark a layout as `'use client'` (pushes entire subtree to client)
|
|
632
|
+
- Use `router.push` where `<Link>` or `redirect()` works
|
|
633
|
+
- Mutate data in GET route handlers (use POST/PUT/DELETE)
|
|
634
|
+
- Skip input validation in Server Actions (they are public HTTP endpoints)
|
|
635
|
+
- Use `window` or `document` in server components
|