@donotdev/cli 0.0.4 → 0.0.6
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/dependencies-matrix.json +234 -114
- package/dist/bin/commands/build.js +9 -3
- package/dist/bin/commands/bump.js +119 -100
- package/dist/bin/commands/cacheout.js +9 -3
- package/dist/bin/commands/create-app.js +60 -34
- package/dist/bin/commands/create-project.js +61 -34
- package/dist/bin/commands/deploy.js +22 -14
- package/dist/bin/commands/dev.js +9 -3
- package/dist/bin/commands/emu.js +9 -3
- package/dist/bin/commands/format.js +9 -3
- package/dist/bin/commands/lint.js +9 -3
- package/dist/bin/commands/make-admin.d.ts +11 -0
- package/dist/bin/commands/make-admin.d.ts.map +1 -0
- package/dist/bin/commands/make-admin.js +12 -0
- package/dist/bin/commands/make-admin.js.map +1 -0
- package/dist/bin/commands/preview.js +9 -3
- package/dist/bin/commands/sync-secrets.js +9 -3
- package/dist/index.js +72 -44
- package/package.json +1 -1
- package/templates/app-demo/index.html.example +4 -0
- package/templates/app-demo/src/App.tsx.example +28 -10
- package/templates/app-demo/src/config/app.ts.example +56 -0
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +5 -5
- package/templates/app-next/src/app/ClientLayout.tsx.example +5 -4
- package/templates/app-next/src/app/layout.tsx.example +17 -25
- package/templates/app-next/src/globals.css.example +10 -7
- package/templates/app-next/src/locales/dndev_en.json.example +68 -0
- package/templates/app-next/src/pages/locales/example_en.json.example +5 -0
- package/templates/app-vite/index.html.example +3 -0
- package/templates/app-vite/src/App.tsx.example +1 -1
- package/templates/app-vite/src/globals.css.example +14 -6
- package/templates/app-vite/src/locales/dndev_en.json.example +68 -0
- package/templates/functions-firebase/README.md.example +25 -0
- package/templates/functions-firebase/tsconfig.json.example +3 -13
- package/templates/functions-vercel/tsconfig.json.example +1 -13
- package/templates/root-consumer/firebase.json.example +1 -1
- package/templates/root-consumer/guides/AGENT_START_HERE.md.example +229 -7
- package/templates/root-consumer/guides/COMPONENTS_ADV.md.example +456 -0
- package/templates/root-consumer/guides/COMPONENTS_ATOMIC.md.example +43 -1
- package/templates/root-consumer/guides/COMPONENTS_UI.md.example +6 -0
- package/templates/root-consumer/guides/INDEX.md.example +3 -0
- package/templates/root-consumer/guides/SETUP_APP_CONFIG.md.example +5 -2
- package/templates/root-consumer/guides/SETUP_BILLING.md.example +44 -4
- package/templates/root-consumer/guides/SETUP_CRUD.md.example +1244 -0
- package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +52 -0
- package/templates/root-consumer/guides/SETUP_I18N.md.example +145 -6
- package/templates/root-consumer/guides/SETUP_LAYOUTS.md.example +18 -0
- package/templates/root-consumer/guides/SETUP_PAGES.md.example +25 -0
- package/templates/root-consumer/guides/SETUP_PWA.md.example +213 -0
- package/templates/root-consumer/guides/USE_ROUTING.md.example +503 -0
- package/templates/root-consumer/vercel.json.example +315 -20
- package/templates/app-demo/src/Routes.tsx.example +0 -20
- package/templates/app-vite/src/Routes.tsx.example +0 -16
- package/templates/app-vite/src/pages/locales/README.md.example +0 -1
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
# Routing Guide
|
|
2
|
+
|
|
3
|
+
**For AI Agents:** Use framework routing components/hooks. NEVER import from `react-router-dom` directly. Framework handles SPA navigation, Outlet, and overlay closing automatically.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚨 Critical Rule: Never Use react-router-dom Directly
|
|
8
|
+
|
|
9
|
+
**❌ WRONG:**
|
|
10
|
+
```tsx
|
|
11
|
+
import { Link, useNavigate, useParams } from 'react-router-dom'; // ❌ BREAKS FRAMEWORK
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**✅ CORRECT:**
|
|
15
|
+
```tsx
|
|
16
|
+
import { Link, useNavigate, useParams } from '@donotdev/ui/routing'; // ✅ Framework routing
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Why?** The framework's routing components:
|
|
20
|
+
- Automatically close overlays on navigation
|
|
21
|
+
- Handle SPA navigation correctly with Outlet
|
|
22
|
+
- Work with both Vite and Next.js
|
|
23
|
+
- Integrate with auth and route discovery
|
|
24
|
+
- Provide proper TypeScript types
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Framework Routing API
|
|
29
|
+
|
|
30
|
+
### Components
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { Link, DnDevNavigationMenu } from '@donotdev/ui/routing';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Link Component:**
|
|
37
|
+
```tsx
|
|
38
|
+
<Link path="/products" label="Products" icon="Package" />
|
|
39
|
+
<Link path="/users/:id" replace prefetch={false}>User Details</Link>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**DnDevNavigationMenu (Sidebar/Header):**
|
|
43
|
+
```tsx
|
|
44
|
+
// Auto-fetches routes, handles auth filtering
|
|
45
|
+
<DnDevNavigationMenu vertical display={DISPLAY.AUTO} />
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Hooks
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import {
|
|
52
|
+
useNavigate,
|
|
53
|
+
useLocation,
|
|
54
|
+
useParams,
|
|
55
|
+
useRouteParam,
|
|
56
|
+
useSearchParams,
|
|
57
|
+
useNavigationItems,
|
|
58
|
+
} from '@donotdev/ui/routing';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Navigation Patterns
|
|
64
|
+
|
|
65
|
+
### 1. Basic Navigation
|
|
66
|
+
|
|
67
|
+
**✅ Use framework Link:**
|
|
68
|
+
```tsx
|
|
69
|
+
import { Link } from '@donotdev/ui/routing';
|
|
70
|
+
|
|
71
|
+
function ProductCard({ product }) {
|
|
72
|
+
return (
|
|
73
|
+
<Link path={`/products/${product.id}`} label={product.name} />
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**✅ Use framework useNavigate:**
|
|
79
|
+
```tsx
|
|
80
|
+
import { useNavigate } from '@donotdev/ui/routing';
|
|
81
|
+
|
|
82
|
+
function ProductForm() {
|
|
83
|
+
const navigate = useNavigate();
|
|
84
|
+
|
|
85
|
+
const handleSubmit = async () => {
|
|
86
|
+
await saveProduct();
|
|
87
|
+
navigate('/products'); // ✅ Closes overlays automatically
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return <form onSubmit={handleSubmit}>...</form>;
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**❌ DON'T use react-router-dom:**
|
|
95
|
+
```tsx
|
|
96
|
+
import { useNavigate } from 'react-router-dom'; // ❌ BREAKS FRAMEWORK
|
|
97
|
+
|
|
98
|
+
function ProductForm() {
|
|
99
|
+
const navigate = useNavigate(); // ❌ Doesn't close overlays, breaks SPA
|
|
100
|
+
// ...
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### 2. Route Parameters
|
|
107
|
+
|
|
108
|
+
**✅ Use framework useRouteParam:**
|
|
109
|
+
```tsx
|
|
110
|
+
import { useRouteParam } from '@donotdev/ui/routing';
|
|
111
|
+
|
|
112
|
+
function ProductPage() {
|
|
113
|
+
const id = useRouteParam('id'); // ✅ Returns string | undefined
|
|
114
|
+
// Safe: handles string | string[] | undefined automatically
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**✅ Or use framework useParams:**
|
|
119
|
+
```tsx
|
|
120
|
+
import { useParams } from '@donotdev/ui/routing';
|
|
121
|
+
|
|
122
|
+
function ProductPage() {
|
|
123
|
+
const params = useParams();
|
|
124
|
+
const id = typeof params.id === 'string' ? params.id : undefined;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**❌ DON'T use react-router-dom:**
|
|
129
|
+
```tsx
|
|
130
|
+
import { useParams } from 'react-router-dom'; // ❌ Type issues, breaks framework
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### 3. Sidebar Navigation
|
|
136
|
+
|
|
137
|
+
**✅ Use DnDevNavigationMenu (auto-fetches routes):**
|
|
138
|
+
```tsx
|
|
139
|
+
import { DnDevNavigationMenu, DISPLAY } from '@donotdev/ui/routing';
|
|
140
|
+
|
|
141
|
+
function Sidebar() {
|
|
142
|
+
return (
|
|
143
|
+
<DnDevNavigationMenu
|
|
144
|
+
vertical
|
|
145
|
+
display={DISPLAY.AUTO} // CSS-driven collapse
|
|
146
|
+
showIcons={true}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**✅ Or use useNavigationItems for custom sidebar:**
|
|
153
|
+
```tsx
|
|
154
|
+
import { Link, useNavigationItems } from '@donotdev/ui/routing';
|
|
155
|
+
|
|
156
|
+
function CustomSidebar() {
|
|
157
|
+
const menuItems = useNavigationItems(); // ✅ Auth-filtered routes
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<nav>
|
|
161
|
+
{menuItems.map((item) => (
|
|
162
|
+
<Link
|
|
163
|
+
key={item.path}
|
|
164
|
+
path={item.path}
|
|
165
|
+
label={item.label}
|
|
166
|
+
icon={item.icon}
|
|
167
|
+
className={item.isActive ? 'active' : ''}
|
|
168
|
+
/>
|
|
169
|
+
))}
|
|
170
|
+
</nav>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**❌ DON'T manually build navigation:**
|
|
176
|
+
```tsx
|
|
177
|
+
import { Link } from 'react-router-dom'; // ❌ BREAKS FRAMEWORK
|
|
178
|
+
|
|
179
|
+
function Sidebar() {
|
|
180
|
+
// ❌ Doesn't integrate with route discovery
|
|
181
|
+
// ❌ Doesn't handle auth filtering
|
|
182
|
+
// ❌ Doesn't work with Outlet
|
|
183
|
+
return (
|
|
184
|
+
<nav>
|
|
185
|
+
<Link to="/products">Products</Link>
|
|
186
|
+
</nav>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### 4. Programmatic Navigation
|
|
194
|
+
|
|
195
|
+
**✅ Use framework useNavigate:**
|
|
196
|
+
```tsx
|
|
197
|
+
import { useNavigate } from '@donotdev/ui/routing';
|
|
198
|
+
|
|
199
|
+
function LoginForm() {
|
|
200
|
+
const navigate = useNavigate();
|
|
201
|
+
|
|
202
|
+
const handleLogin = async () => {
|
|
203
|
+
await signIn();
|
|
204
|
+
navigate('/dashboard', { replace: true }); // ✅ Closes overlays
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
return <form onSubmit={handleLogin}>...</form>;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**✅ Navigate back:**
|
|
212
|
+
```tsx
|
|
213
|
+
const navigate = useNavigate();
|
|
214
|
+
navigate('back'); // ✅ Framework handles browser history
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**✅ With options:**
|
|
218
|
+
```tsx
|
|
219
|
+
navigate('/products', {
|
|
220
|
+
replace: true, // Replace history entry
|
|
221
|
+
preserveScroll: true, // Preserve scroll position
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### 5. Query Parameters
|
|
228
|
+
|
|
229
|
+
**✅ Use framework useSearchParams:**
|
|
230
|
+
```tsx
|
|
231
|
+
import { useSearchParams } from '@donotdev/ui/routing';
|
|
232
|
+
|
|
233
|
+
function ProductList() {
|
|
234
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
235
|
+
const page = searchParams.get('page') || '1';
|
|
236
|
+
|
|
237
|
+
const handlePageChange = (newPage: string) => {
|
|
238
|
+
setSearchParams({ page: newPage });
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return <div>Page: {page}</div>;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**✅ Or use useQueryParams helper:**
|
|
246
|
+
```tsx
|
|
247
|
+
import { useQueryParams } from '@donotdev/ui/routing';
|
|
248
|
+
|
|
249
|
+
function ProductList() {
|
|
250
|
+
const { page, sort } = useQueryParams({ page: '1', sort: 'name' });
|
|
251
|
+
// Returns { page: string, sort: string } with defaults
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### 6. Route Matching
|
|
258
|
+
|
|
259
|
+
**✅ Use framework useMatch:**
|
|
260
|
+
```tsx
|
|
261
|
+
import { useMatch } from '@donotdev/ui/routing';
|
|
262
|
+
|
|
263
|
+
function NavigationItem({ path }) {
|
|
264
|
+
const isActive = useMatch(path);
|
|
265
|
+
return <Link path={path} className={isActive ? 'active' : ''} />;
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Outlet and Nested Routes
|
|
272
|
+
|
|
273
|
+
**Framework handles Outlet automatically.** You don't need to manually use `<Outlet />` in most cases.
|
|
274
|
+
|
|
275
|
+
### How It Works
|
|
276
|
+
|
|
277
|
+
1. **RootLayout** wraps all routes and includes `<Outlet />`
|
|
278
|
+
2. **DnDevLayout** receives `<Outlet />` and renders it in the main content area
|
|
279
|
+
3. **Routes are discovered** from `src/pages/*Page.tsx` files automatically
|
|
280
|
+
|
|
281
|
+
**✅ Your pages just render content:**
|
|
282
|
+
```tsx
|
|
283
|
+
// src/pages/ProductsPage.tsx
|
|
284
|
+
export function ProductsPage() {
|
|
285
|
+
return <div>Products List</div>; // ✅ Rendered via Outlet automatically
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**❌ DON'T manually use Outlet:**
|
|
290
|
+
```tsx
|
|
291
|
+
import { Outlet } from 'react-router-dom'; // ❌ BREAKS FRAMEWORK
|
|
292
|
+
|
|
293
|
+
export function ProductsPage() {
|
|
294
|
+
return (
|
|
295
|
+
<div>
|
|
296
|
+
<h1>Products</h1>
|
|
297
|
+
<Outlet /> {/* ❌ Framework already handles this */}
|
|
298
|
+
</div>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Nested Routes (Advanced)
|
|
304
|
+
|
|
305
|
+
If you need nested routes, use the framework's route discovery:
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
// src/pages/products/ProductsPage.tsx
|
|
309
|
+
export const pageMeta = {
|
|
310
|
+
route: '/products',
|
|
311
|
+
// ...
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// src/pages/products/ProductDetailPage.tsx
|
|
315
|
+
export const pageMeta = {
|
|
316
|
+
route: '/products/:id',
|
|
317
|
+
// ...
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Framework automatically creates nested route structure.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Route Discovery
|
|
326
|
+
|
|
327
|
+
**Routes are auto-discovered from `src/pages/*Page.tsx` files.**
|
|
328
|
+
|
|
329
|
+
**✅ Define routes with PageMeta:**
|
|
330
|
+
```tsx
|
|
331
|
+
// src/pages/ProductsPage.tsx
|
|
332
|
+
import type { PageMeta } from '@donotdev/core';
|
|
333
|
+
|
|
334
|
+
export const pageMeta: PageMeta = {
|
|
335
|
+
title: 'Products',
|
|
336
|
+
route: '/products',
|
|
337
|
+
icon: 'Package',
|
|
338
|
+
auth: { required: true, roles: ['user', 'admin'] },
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
export function ProductsPage() {
|
|
342
|
+
return <div>Products</div>;
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Framework automatically:**
|
|
347
|
+
- Discovers routes from filesystem
|
|
348
|
+
- Generates navigation menus
|
|
349
|
+
- Filters by auth permissions
|
|
350
|
+
- Handles lazy loading
|
|
351
|
+
- Creates route structure
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Common Mistakes
|
|
356
|
+
|
|
357
|
+
### ❌ Mistake 1: Importing from react-router-dom
|
|
358
|
+
|
|
359
|
+
```tsx
|
|
360
|
+
// ❌ WRONG
|
|
361
|
+
import { Link, useNavigate } from 'react-router-dom';
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Fix:**
|
|
365
|
+
```tsx
|
|
366
|
+
// ✅ CORRECT
|
|
367
|
+
import { Link, useNavigate } from '@donotdev/ui/routing';
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
### ❌ Mistake 2: Manual Outlet Usage
|
|
373
|
+
|
|
374
|
+
```tsx
|
|
375
|
+
// ❌ WRONG
|
|
376
|
+
import { Outlet } from 'react-router-dom';
|
|
377
|
+
|
|
378
|
+
export function Layout() {
|
|
379
|
+
return <Outlet />; // Framework already handles this
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Fix:** Don't use Outlet manually. Framework handles it.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
### ❌ Mistake 3: Manual Route Configuration
|
|
388
|
+
|
|
389
|
+
```tsx
|
|
390
|
+
// ❌ WRONG
|
|
391
|
+
import { Routes, Route } from 'react-router-dom';
|
|
392
|
+
|
|
393
|
+
function App() {
|
|
394
|
+
return (
|
|
395
|
+
<Routes>
|
|
396
|
+
<Route path="/products" element={<ProductsPage />} />
|
|
397
|
+
</Routes>
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
**Fix:** Use route discovery. Create `src/pages/ProductsPage.tsx` with `pageMeta`.
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
### ❌ Mistake 4: Manual Navigation Menu
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
// ❌ WRONG
|
|
410
|
+
function Sidebar() {
|
|
411
|
+
return (
|
|
412
|
+
<nav>
|
|
413
|
+
<Link to="/products">Products</Link>
|
|
414
|
+
<Link to="/users">Users</Link>
|
|
415
|
+
</nav>
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Fix:**
|
|
421
|
+
```tsx
|
|
422
|
+
// ✅ CORRECT
|
|
423
|
+
import { DnDevNavigationMenu } from '@donotdev/ui/routing';
|
|
424
|
+
|
|
425
|
+
function Sidebar() {
|
|
426
|
+
return <DnDevNavigationMenu vertical />; // Auto-fetches routes
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
### ❌ Mistake 5: Not Using Framework Link
|
|
433
|
+
|
|
434
|
+
```tsx
|
|
435
|
+
// ❌ WRONG
|
|
436
|
+
import { Link } from 'react-router-dom';
|
|
437
|
+
|
|
438
|
+
<Link to="/products">Products</Link>
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Fix:**
|
|
442
|
+
```tsx
|
|
443
|
+
// ✅ CORRECT
|
|
444
|
+
import { Link } from '@donotdev/ui/routing';
|
|
445
|
+
|
|
446
|
+
<Link path="/products" label="Products" />
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Quick Reference
|
|
452
|
+
|
|
453
|
+
### Import Paths
|
|
454
|
+
|
|
455
|
+
```tsx
|
|
456
|
+
// ✅ Framework routing (platform-agnostic)
|
|
457
|
+
import {
|
|
458
|
+
Link,
|
|
459
|
+
useNavigate,
|
|
460
|
+
useLocation,
|
|
461
|
+
useParams,
|
|
462
|
+
useRouteParam,
|
|
463
|
+
useSearchParams,
|
|
464
|
+
useNavigationItems,
|
|
465
|
+
DnDevNavigationMenu,
|
|
466
|
+
} from '@donotdev/ui/routing';
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Common Patterns
|
|
470
|
+
|
|
471
|
+
```tsx
|
|
472
|
+
// Navigation
|
|
473
|
+
const navigate = useNavigate();
|
|
474
|
+
navigate('/products');
|
|
475
|
+
navigate('back');
|
|
476
|
+
navigate('/products', { replace: true });
|
|
477
|
+
|
|
478
|
+
// Route params
|
|
479
|
+
const id = useRouteParam('id');
|
|
480
|
+
|
|
481
|
+
// Query params
|
|
482
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
483
|
+
const page = searchParams.get('page');
|
|
484
|
+
|
|
485
|
+
// Navigation menu
|
|
486
|
+
const menuItems = useNavigationItems(); // Auth-filtered routes
|
|
487
|
+
|
|
488
|
+
// Link component
|
|
489
|
+
<Link path="/products" label="Products" icon="Package" />
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## Summary
|
|
495
|
+
|
|
496
|
+
1. **Always use `@donotdev/ui/routing`** - never `react-router-dom`
|
|
497
|
+
2. **Use `DnDevNavigationMenu`** for sidebars/headers
|
|
498
|
+
3. **Use `useNavigationItems()`** for custom navigation
|
|
499
|
+
4. **Don't use `<Outlet />` manually** - framework handles it
|
|
500
|
+
5. **Routes are auto-discovered** from `src/pages/*Page.tsx`
|
|
501
|
+
6. **Framework closes overlays** on navigation automatically
|
|
502
|
+
|
|
503
|
+
**Framework handles SPA navigation, Outlet, and route discovery. Use framework components/hooks only.**
|