vibes-plug 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/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/BLUEPRINT.md +125 -0
- package/CHANGELOG.md +195 -0
- package/CONTRIBUTING.md +199 -0
- package/LICENSE +21 -0
- package/README.md +263 -0
- package/SECURITY.md +21 -0
- package/banner.png +0 -0
- package/package.json +25 -0
- package/plugin.json +8 -0
- package/scripts/update_skills.js +75 -0
- package/skills/ai-llm-integration-expert/SKILL.md +162 -0
- package/skills/api-design-expert/SKILL.md +310 -0
- package/skills/app-analyzer-optimizer/SKILL.md +189 -0
- package/skills/asisten_ramah/SKILL.md +41 -0
- package/skills/authentication-identity-expert/SKILL.md +45 -0
- package/skills/auto-doc-updater/SKILL.md +204 -0
- package/skills/bootstrap-to-modern/SKILL.md +87 -0
- package/skills/brainstorming/SKILL.md +353 -0
- package/skills/bun-runtime-expert/SKILL.md +211 -0
- package/skills/ci-cd-devops-architect/SKILL.md +45 -0
- package/skills/cloud-hosting-expert/SKILL.md +244 -0
- package/skills/coderabbit/SKILL.md +192 -0
- package/skills/data-telemetry-expert/SKILL.md +213 -0
- package/skills/database-orm-expert/SKILL.md +294 -0
- package/skills/design-system-architect/SKILL.md +243 -0
- package/skills/e2e-testing-expert/SKILL.md +315 -0
- package/skills/event-driven-architect/SKILL.md +81 -0
- package/skills/firebase-security-expert/SKILL.md +195 -0
- package/skills/fullstack-expert/SKILL.md +202 -0
- package/skills/fullstack-expert/references/api_design_guide.md +466 -0
- package/skills/fullstack-expert/references/devops_infrastructure.md +477 -0
- package/skills/fullstack-expert/references/multi_language_backend.md +528 -0
- package/skills/fullstack-expert/references/system_design_patterns.md +358 -0
- package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -0
- package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -0
- package/skills/gemini-agent-booster/SKILL.md +135 -0
- package/skills/global-a11y-i18n-expert/SKILL.md +81 -0
- package/skills/go-programming-expert/SKILL.md +295 -0
- package/skills/hig/SKILL.md +188 -0
- package/skills/js-backend-expert/SKILL.md +192 -0
- package/skills/mcp-server-architect/SKILL.md +194 -0
- package/skills/mobile-expo-expert/SKILL.md +186 -0
- package/skills/monday-design-aesthetic/SKILL.md +67 -0
- package/skills/monorepo-architect/SKILL.md +227 -0
- package/skills/mpa-orchestrator/SKILL.md +101 -0
- package/skills/multi-agent-orchestration/SKILL.md +234 -0
- package/skills/multiple-entry-points/SKILL.md +55 -0
- package/skills/mvc-expert/SKILL.md +231 -0
- package/skills/payment-gateway-expert/SKILL.md +45 -0
- package/skills/performance-web-vitals/SKILL.md +332 -0
- package/skills/prd-architect/SKILL.md +191 -0
- package/skills/production-ready-hardener/SKILL.md +469 -0
- package/skills/production-ready-hardener/references/performance_optimization.md +441 -0
- package/skills/production-ready-hardener/references/production_checklist.md +161 -0
- package/skills/production-ready-hardener/references/security_hardening_guide.md +379 -0
- package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +875 -0
- package/skills/python-programming-expert/SKILL.md +271 -0
- package/skills/realtime-collaboration-expert/SKILL.md +45 -0
- package/skills/rust-programming-expert/SKILL.md +235 -0
- package/skills/saas-billing/SKILL.md +377 -0
- package/skills/saas-multi-tenant/SKILL.md +237 -0
- package/skills/saas-mvp-launcher/SKILL.md +231 -0
- package/skills/saas-transformer/SKILL.md +446 -0
- package/skills/saas-transformer/references/billing_integration_guide.md +401 -0
- package/skills/saas-transformer/references/feature_gating_patterns.md +137 -0
- package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -0
- package/skills/saas-transformer/scripts/saas_transformation_scanner.py +254 -0
- package/skills/scalability-clean-code/SKILL.md +229 -0
- package/skills/secure-fuzz-testing/SKILL.md +201 -0
- package/skills/senior-frontend/SKILL.md +161 -0
- package/skills/senior-frontend/references/frontend_best_practices.md +806 -0
- package/skills/senior-frontend/references/nextjs_optimization_guide.md +724 -0
- package/skills/senior-frontend/references/react_patterns.md +746 -0
- package/skills/senior-frontend/scripts/bundle_analyzer.py +407 -0
- package/skills/senior-frontend/scripts/component_generator.py +329 -0
- package/skills/senior-frontend/scripts/frontend_scaffolder.py +1005 -0
- package/skills/senior-fullstack/SKILL.md +167 -0
- package/skills/senior-fullstack/references/architecture_patterns.md +160 -0
- package/skills/senior-fullstack/references/development_workflows.md +222 -0
- package/skills/senior-fullstack/references/tech_stack_guide.md +190 -0
- package/skills/senior-fullstack/scripts/code_quality_analyzer.py +114 -0
- package/skills/senior-fullstack/scripts/fullstack_scaffolder.py +114 -0
- package/skills/senior-fullstack/scripts/project_scaffolder.py +114 -0
- package/skills/seo/SKILL.md +225 -0
- package/skills/seo/references/cwv-thresholds.md +108 -0
- package/skills/seo/references/eeat-framework.md +214 -0
- package/skills/seo/references/quality-gates.md +155 -0
- package/skills/seo/references/schema-types.md +118 -0
- package/skills/seo-aeo-landing-page-writer/SKILL.md +97 -0
- package/skills/seo-geo/SKILL.md +188 -0
- package/skills/session-handoff-resume/SKILL.md +158 -0
- package/skills/skill_baru/SKILL.md +147 -0
- package/skills/spa-orchestrator/SKILL.md +288 -0
- package/skills/state-management-expert/SKILL.md +272 -0
- package/skills/supabase-migration/SKILL.md +45 -0
- package/skills/supabase-security-expert/SKILL.md +243 -0
- package/skills/tailwind-expert/SKILL.md +188 -0
- package/skills/tanstack-query-expert/SKILL.md +199 -0
- package/skills/tauri-expert/SKILL.md +97 -0
- package/skills/token-saver/SKILL.md +111 -0
- package/skills/typescript-expert/SKILL.md +279 -0
- package/skills/ui-components-expert/SKILL.md +63 -0
- package/skills/ui-ux-pro-max/SKILL.md +201 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +493 -0
- package/skills/ui-ux-pro-max/scripts/search.py +81 -0
- package/skills/ui_ux_expert/SKILL.md +114 -0
- package/skills/vibe-code-gardener/SKILL.md +173 -0
- package/skills/web-scraper/SKILL.md +205 -0
- package/skills/web-scraper/references/data-transforms.md +397 -0
- package/skills/web-scraper/references/extraction-patterns.md +475 -0
- package/skills/web-scraper/references/output-templates.md +481 -0
- package/skills/zero-to-prod-orchestrator/SKILL.md +180 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-baru
|
|
3
|
+
description: "Comprehensive template for creating new vibes-plug skills with proper structure, trigger conditions, and bilingual support / Template komprehensif untuk membuat skill vibes-plug baru dengan struktur yang tepat, kondisi pemicu, dan dukungan bilingual."
|
|
4
|
+
author: "Roedy Rustam"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# [Skill Name] — vibes-plug Skill Template
|
|
8
|
+
|
|
9
|
+
[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
> **HOW TO USE THIS TEMPLATE**
|
|
14
|
+
> 1. Copy this entire folder (`skill_baru/`) and rename it using kebab-case (e.g., `my-new-skill/`).
|
|
15
|
+
> 2. Replace all placeholder text marked with `[...]` brackets.
|
|
16
|
+
> 3. Update the frontmatter `name` and `description` fields above.
|
|
17
|
+
> 4. Delete this instruction block before publishing.
|
|
18
|
+
> 5. Add your skill to the `brainstorming` orchestration matrix if it belongs to a domain.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<a name="english"></a>
|
|
23
|
+
## English
|
|
24
|
+
|
|
25
|
+
### Description
|
|
26
|
+
[One paragraph describing the purpose and scope of this skill. Be specific about what problems it solves and what technology versions it targets.]
|
|
27
|
+
|
|
28
|
+
Example: *"Expert guide for [Technology/Domain] (v[X.Y]+). Covers [feature A], [feature B], [pattern C], and [best practice D] for production-grade TypeScript/JavaScript applications."*
|
|
29
|
+
|
|
30
|
+
### Trigger Conditions
|
|
31
|
+
Activate this skill when the user is:
|
|
32
|
+
- [Trigger scenario 1 — be specific, e.g., "Writing X with framework Y"]
|
|
33
|
+
- [Trigger scenario 2]
|
|
34
|
+
- [Trigger scenario 3]
|
|
35
|
+
- [Trigger scenario 4]
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### Core Concepts
|
|
40
|
+
|
|
41
|
+
#### [Concept 1 — e.g., "Architecture Overview"]
|
|
42
|
+
[Explain the foundational concept. Use tables for comparisons, bullet points for lists, and code blocks for examples.]
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// [Language] — [What this code demonstrates]
|
|
46
|
+
// Replace this block with a real, runnable code example.
|
|
47
|
+
const example = {
|
|
48
|
+
field: 'value',
|
|
49
|
+
};
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### [Concept 2 — e.g., "Selection Guide"]
|
|
53
|
+
|
|
54
|
+
| Criteria | Option A | Option B | Option C |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| [Criterion 1] | [Value] | [Value] | [Value] |
|
|
57
|
+
| [Criterion 2] | [Value] | [Value] | [Value] |
|
|
58
|
+
| **Best For** | [Use case] | [Use case] | [Use case] |
|
|
59
|
+
|
|
60
|
+
**Recommendation:** [State a clear default recommendation with rationale.]
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### [Main Topic Section 1 — e.g., "Setup & Configuration"]
|
|
65
|
+
|
|
66
|
+
#### [Sub-topic 1.1]
|
|
67
|
+
```typescript
|
|
68
|
+
// Example: Configuration or setup code
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### [Sub-topic 1.2]
|
|
72
|
+
```typescript
|
|
73
|
+
// Example: Core usage pattern
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### [Main Topic Section 2 — e.g., "Best Practices"]
|
|
79
|
+
|
|
80
|
+
1. **[Practice 1]:** [Explanation]
|
|
81
|
+
2. **[Practice 2]:** [Explanation]
|
|
82
|
+
3. **[Practice 3]:** [Explanation]
|
|
83
|
+
4. **[Practice 4]:** [Explanation]
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Common Pitfalls to Avoid
|
|
88
|
+
|
|
89
|
+
| Anti-Pattern | Problem | Correct Approach |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| [Bad practice 1] | [Why it's bad] | [What to do instead] |
|
|
92
|
+
| [Bad practice 2] | [Why it's bad] | [What to do instead] |
|
|
93
|
+
| [Bad practice 3] | [Why it's bad] | [What to do instead] |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### Integration with Other Skills
|
|
98
|
+
|
|
99
|
+
This skill works best when combined with:
|
|
100
|
+
- `[skill-name]` — [Why and when to combine]
|
|
101
|
+
- `[skill-name]` — [Why and when to combine]
|
|
102
|
+
- `[skill-name]` — [Why and when to combine]
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
<a name="bahasa-indonesia"></a>
|
|
107
|
+
## Bahasa Indonesia
|
|
108
|
+
|
|
109
|
+
### Deskripsi
|
|
110
|
+
[Satu paragraf menjelaskan tujuan dan ruang lingkup skill ini. Spesifik tentang masalah apa yang dipecahkan dan versi teknologi apa yang ditargetkan.]
|
|
111
|
+
|
|
112
|
+
Contoh: *"Panduan ahli untuk [Teknologi/Domain] (v[X.Y]+). Mencakup [fitur A], [fitur B], [pola C], dan [praktik terbaik D] untuk aplikasi TypeScript/JavaScript berkualitas produksi."*
|
|
113
|
+
|
|
114
|
+
### Kondisi Pemicu
|
|
115
|
+
Aktifkan skill ini ketika pengguna sedang:
|
|
116
|
+
- [Skenario pemicu 1 — spesifik, misal: "Menulis X dengan framework Y"]
|
|
117
|
+
- [Skenario pemicu 2]
|
|
118
|
+
- [Skenario pemicu 3]
|
|
119
|
+
- [Skenario pemicu 4]
|
|
120
|
+
|
|
121
|
+
### Panduan Singkat
|
|
122
|
+
|
|
123
|
+
[Ringkasan praktis berisi poin-poin utama yang harus diketahui. Merujuk ke bagian English untuk detail teknis dan contoh kode lengkap.]
|
|
124
|
+
|
|
125
|
+
- **[Prinsip 1]:** [Penjelasan singkat]
|
|
126
|
+
- **[Prinsip 2]:** [Penjelasan singkat]
|
|
127
|
+
- **[Prinsip 3]:** [Penjelasan singkat]
|
|
128
|
+
- **[Prinsip 4]:** [Penjelasan singkat]
|
|
129
|
+
|
|
130
|
+
### Integrasi dengan Skill Lain
|
|
131
|
+
|
|
132
|
+
Skill ini bekerja paling baik dikombinasikan dengan:
|
|
133
|
+
- `[nama-skill]` — [Mengapa dan kapan dikombinasikan]
|
|
134
|
+
- `[nama-skill]` — [Mengapa dan kapan dikombinasikan]
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Checklist Sebelum Mempublikasikan Skill Ini
|
|
139
|
+
|
|
140
|
+
- [ ] Frontmatter `name` dan `description` sudah diisi.
|
|
141
|
+
- [ ] Semua teks `[...]` placeholder sudah diganti.
|
|
142
|
+
- [ ] Ada minimal 2 contoh kode yang nyata dan dapat dijalankan.
|
|
143
|
+
- [ ] Ada tabel perbandingan atau selection guide jika relevan.
|
|
144
|
+
- [ ] Ada bagian "Common Pitfalls" atau anti-pattern.
|
|
145
|
+
- [ ] Bagian Bahasa Indonesia sudah diterjemahkan dengan benar.
|
|
146
|
+
- [ ] Blok instruksi ini sudah dihapus.
|
|
147
|
+
- [ ] Skill sudah ditambahkan ke matriks orkestrasi `brainstorming` jika relevan.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spa-orchestrator
|
|
3
|
+
description: "Orchestrates Single-Page Application (SPA) architecture, integrating frontend state management with API-driven backends / Mengorkestrasi arsitektur Single-Page Application (SPA), mengintegrasikan state management frontend dengan backend berbasis API."
|
|
4
|
+
author: "Roedy Rustam"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Single-Page Application (SPA) Orchestrator (2026 Edition)
|
|
8
|
+
|
|
9
|
+
[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<a name="english"></a>
|
|
14
|
+
## English
|
|
15
|
+
|
|
16
|
+
### Description
|
|
17
|
+
Structured orchestration guide for building modern Single-Page Applications (SPAs). Coordinates frontend architecture (TanStack Router, React 19, TanStack Query v5) with decoupled API backends (Hono RPC, tRPC). Covers state management strategy, routing patterns, API layer design, build tooling (Vite + TanStack Start), and deployment strategies.
|
|
18
|
+
|
|
19
|
+
### Trigger Conditions
|
|
20
|
+
- Building a highly interactive dashboard, admin panel, or data-heavy web application as a SPA.
|
|
21
|
+
- Choosing between SPA vs SSR vs MPA for a new project.
|
|
22
|
+
- Setting up client-side routing with **TanStack Router** (type-safe routes, loaders).
|
|
23
|
+
- Structuring state management: server state (TanStack Query) vs client state (Zustand/Jotai).
|
|
24
|
+
- Building a decoupled frontend that communicates with a separate backend via **Hono RPC** or tRPC.
|
|
25
|
+
- Deploying a SPA to Cloudflare Pages, Vercel, or a CDN.
|
|
26
|
+
|
|
27
|
+
### SPA vs SSR vs MPA — Decision Guide
|
|
28
|
+
```
|
|
29
|
+
Choose SPA when:
|
|
30
|
+
✅ Highly interactive app (dashboard, editor, admin panel)
|
|
31
|
+
✅ Rich client-side state that persists across navigation
|
|
32
|
+
✅ Auth-gated app (SEO is not a primary concern)
|
|
33
|
+
✅ Already have a separate backend API
|
|
34
|
+
|
|
35
|
+
Choose SSR (Next.js) when:
|
|
36
|
+
✅ SEO is critical (marketing pages, public content)
|
|
37
|
+
✅ Fast initial page load for unauthenticated users
|
|
38
|
+
✅ Mixed app: some public pages + some gated app pages
|
|
39
|
+
|
|
40
|
+
Choose MPA (Astro, Django, Laravel) when:
|
|
41
|
+
✅ Mostly static content, minimal interactivity
|
|
42
|
+
✅ SEO is the primary concern
|
|
43
|
+
✅ Small team that wants to avoid JS complexity
|
|
44
|
+
→ see mpa-orchestrator skill
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Recommended SPA Stack (2026)
|
|
48
|
+
|
|
49
|
+
| Layer | Tool | Why |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Build** | Vite 6 / TanStack Start | Instant HMR, ES modules, fast builds |
|
|
52
|
+
| **Routing** | TanStack Router | Fully type-safe routes, search params, loaders |
|
|
53
|
+
| **Server State** | TanStack Query v5 | Data fetching, caching, mutations |
|
|
54
|
+
| **Client State** | Zustand / Jotai | Lightweight, no boilerplate |
|
|
55
|
+
| **API Layer** | Hono RPC / tRPC | End-to-end type-safe, no codegen |
|
|
56
|
+
| **Forms** | React Hook Form + Zod | Performant, type-safe validation |
|
|
57
|
+
| **Styling** | Tailwind CSS v4 | Utility-first, zero-runtime |
|
|
58
|
+
| **Components** | shadcn/ui + Base UI | Headless, accessible, customizable |
|
|
59
|
+
| **Animations** | GSAP | Complex, timeline-based, scroll-driven |
|
|
60
|
+
|
|
61
|
+
### TanStack Router — File-Based Type-Safe Routing
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
src/routes/
|
|
65
|
+
__root.tsx # Root layout (providers, nav)
|
|
66
|
+
index.tsx # / — landing/home
|
|
67
|
+
_auth.tsx # Auth guard layout
|
|
68
|
+
_auth/
|
|
69
|
+
dashboard.tsx # /dashboard (auth required)
|
|
70
|
+
settings/
|
|
71
|
+
index.tsx # /settings
|
|
72
|
+
profile.tsx # /settings/profile
|
|
73
|
+
_public.tsx # Public layout
|
|
74
|
+
_public/
|
|
75
|
+
login.tsx # /login
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// src/routes/__root.tsx
|
|
80
|
+
import { createRootRouteWithContext, Outlet } from '@tanstack/react-router';
|
|
81
|
+
import type { QueryClient } from '@tanstack/react-query';
|
|
82
|
+
|
|
83
|
+
interface RouterContext {
|
|
84
|
+
queryClient: QueryClient;
|
|
85
|
+
auth: { user: User | null; isAuthenticated: boolean };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const Route = createRootRouteWithContext<RouterContext>()({
|
|
89
|
+
component: () => (
|
|
90
|
+
<div>
|
|
91
|
+
<Navbar />
|
|
92
|
+
<Outlet />
|
|
93
|
+
</div>
|
|
94
|
+
),
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// src/routes/_auth/dashboard.tsx — protected route with data preloading
|
|
100
|
+
import { createFileRoute, redirect } from '@tanstack/react-router';
|
|
101
|
+
import { workspacesQueryOptions } from '@/queries/workspaces';
|
|
102
|
+
|
|
103
|
+
export const Route = createFileRoute('/_auth/dashboard')({
|
|
104
|
+
// Runs before render — redirect if not authenticated
|
|
105
|
+
beforeLoad: ({ context }) => {
|
|
106
|
+
if (!context.auth.isAuthenticated) {
|
|
107
|
+
throw redirect({ to: '/login' });
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
// Prefetch data in loader — no loading state on initial render
|
|
111
|
+
loader: ({ context: { queryClient } }) =>
|
|
112
|
+
queryClient.ensureQueryData(workspacesQueryOptions()),
|
|
113
|
+
component: DashboardPage,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
function DashboardPage() {
|
|
117
|
+
// Data is already available — no loading state
|
|
118
|
+
const { data: workspaces } = useSuspenseQuery(workspacesQueryOptions());
|
|
119
|
+
return <WorkspaceList workspaces={workspaces} />;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### State Management Architecture
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
State Layers:
|
|
127
|
+
┌─────────────────────────────────────┐
|
|
128
|
+
│ Server State (TanStack Query v5) │ ← API data, cached, auto-refetch
|
|
129
|
+
│ workspaces, users, projects, etc. │
|
|
130
|
+
├─────────────────────────────────────┤
|
|
131
|
+
│ Client State (Zustand) │ ← UI state, sidebar open, theme
|
|
132
|
+
│ modals, filters, UI preferences │
|
|
133
|
+
├─────────────────────────────────────┤
|
|
134
|
+
│ Form State (React Hook Form) │ ← Active form inputs, validation
|
|
135
|
+
│ Scoped to individual forms │
|
|
136
|
+
├─────────────────────────────────────┤
|
|
137
|
+
│ URL State (TanStack Router) │ ← Shareable page state
|
|
138
|
+
│ search params, active tab, page # │
|
|
139
|
+
└─────────────────────────────────────┘
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// URL State — persist filter state in URL (shareable)
|
|
144
|
+
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
145
|
+
import { z } from 'zod';
|
|
146
|
+
|
|
147
|
+
const searchSchema = z.object({
|
|
148
|
+
page: z.number().int().positive().default(1).catch(1),
|
|
149
|
+
search: z.string().default('').catch(''),
|
|
150
|
+
status: z.enum(['all', 'active', 'archived']).default('all').catch('all'),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
export const Route = createFileRoute('/_auth/projects')({
|
|
154
|
+
validateSearch: searchSchema,
|
|
155
|
+
component: ProjectsPage,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
function ProjectsPage() {
|
|
159
|
+
const { page, search, status } = Route.useSearch();
|
|
160
|
+
const navigate = useNavigate({ from: Route.fullPath });
|
|
161
|
+
|
|
162
|
+
const setSearch = (q: string) =>
|
|
163
|
+
navigate({ search: (prev) => ({ ...prev, search: q, page: 1 }) });
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div>
|
|
167
|
+
<SearchInput value={search} onChange={setSearch} />
|
|
168
|
+
<ProjectList page={page} search={search} status={status} />
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Hono RPC — Decoupled Type-Safe API
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// apps/api/src/index.ts — backend Hono app
|
|
178
|
+
import { Hono } from 'hono';
|
|
179
|
+
import { zValidator } from '@hono/zod-validator';
|
|
180
|
+
|
|
181
|
+
const workspacesRoute = new Hono()
|
|
182
|
+
.get('/', async (c) => {
|
|
183
|
+
const user = c.get('user');
|
|
184
|
+
const workspaces = await db.workspace.findMany({
|
|
185
|
+
where: { members: { some: { userId: user.id } } },
|
|
186
|
+
});
|
|
187
|
+
return c.json(workspaces);
|
|
188
|
+
})
|
|
189
|
+
.post('/', zValidator('json', CreateWorkspaceSchema), async (c) => {
|
|
190
|
+
const data = c.req.valid('json');
|
|
191
|
+
const workspace = await db.workspace.create({ data });
|
|
192
|
+
return c.json(workspace, 201);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const app = new Hono()
|
|
196
|
+
.use('*', authMiddleware)
|
|
197
|
+
.route('/workspaces', workspacesRoute);
|
|
198
|
+
|
|
199
|
+
export type AppType = typeof app;
|
|
200
|
+
export default app;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// apps/web/src/lib/api.ts — type-safe client
|
|
205
|
+
import { hc } from 'hono/client';
|
|
206
|
+
import type { AppType } from '@myapp/api';
|
|
207
|
+
|
|
208
|
+
export const api = hc<AppType>(import.meta.env.VITE_API_URL);
|
|
209
|
+
|
|
210
|
+
// TanStack Query integration
|
|
211
|
+
export const workspacesQueryOptions = () =>
|
|
212
|
+
queryOptions({
|
|
213
|
+
queryKey: ['workspaces'],
|
|
214
|
+
queryFn: async () => {
|
|
215
|
+
const res = await api.workspaces.$get();
|
|
216
|
+
return res.json(); // Fully typed!
|
|
217
|
+
},
|
|
218
|
+
staleTime: 5 * 60 * 1000,
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Build & Deployment
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// vite.config.ts
|
|
226
|
+
import { defineConfig } from 'vite';
|
|
227
|
+
import react from '@vitejs/plugin-react';
|
|
228
|
+
import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
|
|
229
|
+
|
|
230
|
+
export default defineConfig({
|
|
231
|
+
plugins: [
|
|
232
|
+
TanStackRouterVite(), // Auto-generates route tree
|
|
233
|
+
react(),
|
|
234
|
+
],
|
|
235
|
+
build: {
|
|
236
|
+
rollupOptions: {
|
|
237
|
+
output: {
|
|
238
|
+
manualChunks: {
|
|
239
|
+
'vendor-react': ['react', 'react-dom'],
|
|
240
|
+
'vendor-query': ['@tanstack/react-query'],
|
|
241
|
+
'vendor-router': ['@tanstack/react-router'],
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Deployment target**: Cloudflare Pages or Vercel for CDN-served static SPA. Backend API deployed separately to Railway/Fly.io.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
<a name="bahasa-indonesia"></a>
|
|
254
|
+
## Bahasa Indonesia
|
|
255
|
+
|
|
256
|
+
### Deskripsi
|
|
257
|
+
Panduan orkestrasi terstruktur untuk membangun Single-Page Application (SPA) modern. Mengkoordinasikan arsitektur frontend (TanStack Router, React 19, TanStack Query v5) dengan backend API terpisah (Hono RPC, tRPC). Mencakup strategi state management, pola routing, desain API layer, build tooling (Vite + TanStack Start), dan strategi deployment.
|
|
258
|
+
|
|
259
|
+
### Kondisi Pemicu
|
|
260
|
+
- Membangun dashboard yang sangat interaktif, panel admin, atau aplikasi web berat data sebagai SPA.
|
|
261
|
+
- Memilih antara SPA vs SSR vs MPA untuk proyek baru.
|
|
262
|
+
- Menyiapkan client-side routing dengan **TanStack Router** (rute type-safe, loader).
|
|
263
|
+
- Menyusun state management: server state (TanStack Query) vs client state (Zustand/Jotai).
|
|
264
|
+
- Membangun frontend terpisah yang berkomunikasi dengan backend terpisah via **Hono RPC** atau tRPC.
|
|
265
|
+
- Men-deploy SPA ke Cloudflare Pages, Vercel, atau CDN.
|
|
266
|
+
|
|
267
|
+
### SPA vs SSR vs MPA — Panduan Keputusan
|
|
268
|
+
|
|
269
|
+
Pilih SPA saat: aplikasi sangat interaktif (dashboard, editor, panel admin), state sisi klien yang kaya, aplikasi yang dibatasi auth (SEO bukan perhatian utama).
|
|
270
|
+
|
|
271
|
+
Pilih SSR (Next.js) saat: SEO sangat penting, load halaman awal yang cepat untuk pengguna yang tidak terautentikasi, aplikasi campuran.
|
|
272
|
+
|
|
273
|
+
Pilih MPA (Astro, Django, Laravel) saat: konten sebagian besar statis, SEO adalah perhatian utama — lihat skill `mpa-orchestrator`.
|
|
274
|
+
|
|
275
|
+
### Stack SPA yang Direkomendasikan (2026)
|
|
276
|
+
Vite 6 untuk build, TanStack Router untuk routing type-safe, TanStack Query v5 untuk server state, Zustand untuk client state, Hono RPC untuk API layer type-safe, React Hook Form + Zod untuk form, Tailwind CSS v4 untuk styling, dan GSAP untuk animasi kompleks.
|
|
277
|
+
|
|
278
|
+
### TanStack Router — Routing File-Based Type-Safe
|
|
279
|
+
Atur rute dalam direktori `src/routes/` dengan layout bersarang. Gunakan `createFileRoute` dengan `beforeLoad` untuk guard autentikasi, `loader` untuk prefetch data, dan `validateSearch` untuk URL state yang dapat dibagikan.
|
|
280
|
+
|
|
281
|
+
### Arsitektur State Management
|
|
282
|
+
Empat lapisan state yang saling melengkapi: Server State (TanStack Query), Client State (Zustand), Form State (React Hook Form), dan URL State (TanStack Router search params).
|
|
283
|
+
|
|
284
|
+
### Hono RPC — API Type-Safe Terpisah
|
|
285
|
+
Ekspor `AppType` dari backend Hono dan gunakan `hc<AppType>()` di frontend untuk panggilan API yang fully typed tanpa codegen.
|
|
286
|
+
|
|
287
|
+
### Build & Deployment
|
|
288
|
+
Gunakan plugin `TanStackRouterVite` untuk auto-generate route tree. Konfigurasi `manualChunks` untuk code splitting yang optimal. Deploy SPA ke Cloudflare Pages atau Vercel; backend API ke Railway/Fly.io secara terpisah.
|