@djangocfg/nextjs 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -115
- package/package.json +24 -35
- package/src/config/base-next-config.ts +1 -0
- package/src/contact/submit.ts +24 -4
- package/src/index.ts +0 -9
- package/src/scripts/check-links.ts +477 -0
- package/src/scripts/index.ts +6 -0
- package/src/components/HomePage.tsx +0 -73
- package/src/components/index.ts +0 -7
- package/src/errors/ErrorLayout.tsx +0 -228
- package/src/errors/errorConfig.ts +0 -118
- package/src/errors/index.ts +0 -10
- package/src/legal/LegalPage.tsx +0 -85
- package/src/legal/configs.ts +0 -131
- package/src/legal/index.ts +0 -24
- package/src/legal/pages.tsx +0 -58
- package/src/legal/types.ts +0 -15
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @djangocfg/nextjs
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Server-side Next.js utilities: sitemap generation, health checks, OG images, contact forms, navigation, and config
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@djangocfg/nextjs)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
|
-
`@djangocfg/nextjs` provides
|
|
14
|
+
`@djangocfg/nextjs` provides server-side utilities for Next.js applications. This package focuses on server-only functionality: SEO optimization with sitemaps, health monitoring, dynamic OG images, contact form handling, navigation utilities, and configuration management.
|
|
15
|
+
|
|
16
|
+
> **Note:** Client components (legal pages, error pages, redirect components) have been moved to `@djangocfg/layouts` to keep this package server-only.
|
|
15
17
|
|
|
16
18
|
## Features
|
|
17
19
|
|
|
@@ -19,12 +21,10 @@
|
|
|
19
21
|
- **Sitemap Generation** - Dynamic XML sitemap generation for SEO
|
|
20
22
|
- **Health Checks** - Production-ready health monitoring endpoints
|
|
21
23
|
- **OG Images** - Dynamic Open Graph image generation with templates
|
|
24
|
+
- **Contact Forms** - Server-side contact form submission handlers
|
|
22
25
|
- **Navigation Utilities** - Route definitions, menu generation, and navigation helpers
|
|
23
|
-
- **Legal Pages** - Pre-built privacy, terms, cookies, and security pages
|
|
24
|
-
- **Error Pages** - Reusable 404 and 500 error layouts
|
|
25
|
-
- **HomePage Component** - Smart authentication redirect component
|
|
26
26
|
- **TypeScript** - Full type safety throughout
|
|
27
|
-
- **
|
|
27
|
+
- **Server-Only** - No client-side code, pure server utilities
|
|
28
28
|
|
|
29
29
|
## Installation
|
|
30
30
|
|
|
@@ -147,77 +147,55 @@ Automatically add OG images to page metadata:
|
|
|
147
147
|
|
|
148
148
|
```tsx
|
|
149
149
|
// app/page.tsx
|
|
150
|
-
import {
|
|
150
|
+
import { generateOgImageMetadata } from '@djangocfg/nextjs/og-image/utils';
|
|
151
151
|
|
|
152
|
-
export const metadata =
|
|
152
|
+
export const metadata = generateOgImageMetadata({
|
|
153
153
|
title: 'My Page',
|
|
154
154
|
description: 'Page description',
|
|
155
155
|
});
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
###
|
|
158
|
+
### Contact Form
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
Create a contact form API route:
|
|
161
161
|
|
|
162
162
|
```tsx
|
|
163
|
-
// app/
|
|
164
|
-
import {
|
|
163
|
+
// app/api/contact/route.ts
|
|
164
|
+
import { createContactRoute } from '@djangocfg/nextjs/contact';
|
|
165
165
|
|
|
166
|
-
export
|
|
166
|
+
export const POST = createContactRoute();
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
- `PrivacyPage` - Privacy policy
|
|
171
|
-
- `TermsPage` - Terms of service
|
|
172
|
-
- `CookiesPage` - Cookie policy
|
|
173
|
-
- `SecurityPage` - Security policy
|
|
174
|
-
|
|
175
|
-
### Error Pages
|
|
176
|
-
|
|
177
|
-
Use reusable error layouts:
|
|
169
|
+
The route handler accepts form data and submits it to your API endpoint. The `apiUrl` can be passed in the request body or configured via environment variables.
|
|
178
170
|
|
|
179
|
-
|
|
180
|
-
// app/not-found.tsx
|
|
181
|
-
import { ErrorLayout } from '@djangocfg/nextjs/errors';
|
|
171
|
+
### Navigation Utilities
|
|
182
172
|
|
|
183
|
-
|
|
184
|
-
return <ErrorLayout code={404} supportEmail="support@example.com" />;
|
|
185
|
-
}
|
|
186
|
-
```
|
|
173
|
+
Define routes and generate navigation menus:
|
|
187
174
|
|
|
188
175
|
```tsx
|
|
189
|
-
|
|
190
|
-
'use client';
|
|
176
|
+
import { defineRoute, routesToMenuItems } from '@djangocfg/nextjs/navigation';
|
|
191
177
|
|
|
192
|
-
|
|
193
|
-
|
|
178
|
+
const routes = [
|
|
179
|
+
defineRoute('/dashboard', { title: 'Dashboard' }),
|
|
180
|
+
defineRoute('/settings', { title: 'Settings' }),
|
|
181
|
+
];
|
|
194
182
|
|
|
195
|
-
|
|
196
|
-
useEffect(() => {
|
|
197
|
-
console.error('Error:', error);
|
|
198
|
-
}, [error]);
|
|
199
|
-
|
|
200
|
-
return <ErrorLayout code={500} supportEmail="support@example.com" />;
|
|
201
|
-
}
|
|
183
|
+
const menuItems = routesToMenuItems(routes);
|
|
202
184
|
```
|
|
203
185
|
|
|
204
|
-
###
|
|
186
|
+
### Client Components
|
|
205
187
|
|
|
206
|
-
|
|
188
|
+
Client-side components (legal pages, error pages, redirect components) are available in `@djangocfg/layouts`:
|
|
207
189
|
|
|
208
190
|
```tsx
|
|
209
|
-
//
|
|
210
|
-
import {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
loadingText="Loading..."
|
|
218
|
-
/>
|
|
219
|
-
);
|
|
220
|
-
}
|
|
191
|
+
// Legal pages
|
|
192
|
+
import { PrivacyPage, TermsPage } from '@djangocfg/layouts/pages/legal';
|
|
193
|
+
|
|
194
|
+
// Error pages
|
|
195
|
+
import { ErrorLayout } from '@djangocfg/layouts/components/errors';
|
|
196
|
+
|
|
197
|
+
// Redirect component
|
|
198
|
+
import { RedirectPage } from '@djangocfg/layouts/components/RedirectPage';
|
|
221
199
|
```
|
|
222
200
|
|
|
223
201
|
## Exports
|
|
@@ -230,10 +208,10 @@ export default function Page() {
|
|
|
230
208
|
| `@djangocfg/nextjs/health` | Health check handlers |
|
|
231
209
|
| `@djangocfg/nextjs/og-image` | OG image generation |
|
|
232
210
|
| `@djangocfg/nextjs/og-image/utils` | OG image URL and metadata utilities |
|
|
211
|
+
| `@djangocfg/nextjs/og-image/components` | OG image template components |
|
|
212
|
+
| `@djangocfg/nextjs/contact` | Contact form route handlers |
|
|
233
213
|
| `@djangocfg/nextjs/navigation` | Route definitions, menu generation, navigation helpers |
|
|
234
|
-
| `@djangocfg/nextjs/
|
|
235
|
-
| `@djangocfg/nextjs/errors` | Error page layouts |
|
|
236
|
-
| `@djangocfg/nextjs/components` | Reusable components |
|
|
214
|
+
| `@djangocfg/nextjs/scripts` | Utility scripts (e.g., link checking) |
|
|
237
215
|
|
|
238
216
|
## API Reference
|
|
239
217
|
|
|
@@ -326,17 +304,35 @@ generateOgImageMetadata(
|
|
|
326
304
|
|
|
327
305
|
#### `generateOgImageUrl(baseUrl, params, useBase64?)`
|
|
328
306
|
|
|
329
|
-
|
|
307
|
+
> **Note:** This utility has been moved to `@djangocfg/layouts/utils/og-image` for client-side usage.
|
|
308
|
+
|
|
309
|
+
For server-side usage, you can still use it from `@djangocfg/nextjs/og-image/utils`, but for client components, import from layouts:
|
|
330
310
|
|
|
331
311
|
```tsx
|
|
332
|
-
|
|
312
|
+
// Client component
|
|
313
|
+
import { generateOgImageUrl } from '@djangocfg/layouts/utils/og-image';
|
|
314
|
+
|
|
315
|
+
const url = generateOgImageUrl('/api/og', {
|
|
333
316
|
title: 'My Page',
|
|
334
317
|
description: 'Page description',
|
|
335
318
|
siteName: 'My Site',
|
|
336
|
-
|
|
337
|
-
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Contact Form
|
|
323
|
+
|
|
324
|
+
#### `createContactRoute(options?)`
|
|
325
|
+
|
|
326
|
+
Creates a Next.js API route handler for contact form submissions.
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
createContactRoute({
|
|
330
|
+
// Options are handled via request body or environment variables
|
|
331
|
+
})
|
|
338
332
|
```
|
|
339
333
|
|
|
334
|
+
The route accepts POST requests with form data and submits to the API endpoint specified in the request body (`_apiUrl` field) or environment variables.
|
|
335
|
+
|
|
340
336
|
### Navigation
|
|
341
337
|
|
|
342
338
|
#### `defineRoute(path, metadata, config?)`
|
|
@@ -371,57 +367,6 @@ Converts route definitions to menu items.
|
|
|
371
367
|
const menuItems = routesToMenuItems(allRoutes);
|
|
372
368
|
```
|
|
373
369
|
|
|
374
|
-
### Legal Pages
|
|
375
|
-
|
|
376
|
-
#### `PrivacyPage`, `TermsPage`, `CookiesPage`, `SecurityPage`
|
|
377
|
-
|
|
378
|
-
Pre-built legal page components with default content. Can be customized:
|
|
379
|
-
|
|
380
|
-
```tsx
|
|
381
|
-
import { PrivacyPage, privacyConfig } from '@djangocfg/nextjs/legal';
|
|
382
|
-
|
|
383
|
-
// Use default
|
|
384
|
-
export default PrivacyPage;
|
|
385
|
-
|
|
386
|
-
// Or customize
|
|
387
|
-
export default function CustomPrivacy() {
|
|
388
|
-
return <PrivacyPage config={{
|
|
389
|
-
...privacyConfig,
|
|
390
|
-
lastUpdated: '2024-01-01',
|
|
391
|
-
}} />;
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### Error Pages
|
|
396
|
-
|
|
397
|
-
#### `ErrorLayout`
|
|
398
|
-
|
|
399
|
-
Reusable error page layout component.
|
|
400
|
-
|
|
401
|
-
```tsx
|
|
402
|
-
<ErrorLayout
|
|
403
|
-
code={404 | 500 | string | number}
|
|
404
|
-
title?: string
|
|
405
|
-
description?: string
|
|
406
|
-
supportEmail?: string
|
|
407
|
-
actions?: React.ReactNode
|
|
408
|
-
showDefaultActions?: boolean
|
|
409
|
-
/>
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### Components
|
|
413
|
-
|
|
414
|
-
#### `HomePage`
|
|
415
|
-
|
|
416
|
-
Authentication redirect component.
|
|
417
|
-
|
|
418
|
-
```tsx
|
|
419
|
-
<HomePage
|
|
420
|
-
authenticatedPath?: string // Default: '/private'
|
|
421
|
-
unauthenticatedPath?: string // Default: '/auth'
|
|
422
|
-
loadingText?: string // Default: 'Loading...'
|
|
423
|
-
/>
|
|
424
|
-
```
|
|
425
370
|
|
|
426
371
|
## Requirements
|
|
427
372
|
|
|
@@ -431,9 +376,8 @@ Authentication redirect component.
|
|
|
431
376
|
|
|
432
377
|
## Peer Dependencies
|
|
433
378
|
|
|
434
|
-
- `@djangocfg/
|
|
435
|
-
-
|
|
436
|
-
- `lucide-react` - For icons
|
|
379
|
+
- `@djangocfg/api` - For API client functionality
|
|
380
|
+
- `next` - Next.js framework (^15.4.4)
|
|
437
381
|
|
|
438
382
|
## Documentation
|
|
439
383
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/nextjs",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Next.js utilities
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextjs",
|
|
7
7
|
"sitemap",
|
|
8
8
|
"health",
|
|
9
9
|
"og-image",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"contact",
|
|
11
|
+
"navigation",
|
|
12
|
+
"config",
|
|
12
13
|
"react",
|
|
13
14
|
"typescript"
|
|
14
15
|
],
|
|
@@ -59,21 +60,6 @@
|
|
|
59
60
|
"import": "./src/og-image/components/index.ts",
|
|
60
61
|
"default": "./src/og-image/components/index.ts"
|
|
61
62
|
},
|
|
62
|
-
"./legal": {
|
|
63
|
-
"types": "./src/legal/index.ts",
|
|
64
|
-
"import": "./src/legal/index.ts",
|
|
65
|
-
"default": "./src/legal/index.ts"
|
|
66
|
-
},
|
|
67
|
-
"./errors": {
|
|
68
|
-
"types": "./src/errors/index.ts",
|
|
69
|
-
"import": "./src/errors/index.ts",
|
|
70
|
-
"default": "./src/errors/index.ts"
|
|
71
|
-
},
|
|
72
|
-
"./components": {
|
|
73
|
-
"types": "./src/components/index.ts",
|
|
74
|
-
"import": "./src/components/index.ts",
|
|
75
|
-
"default": "./src/components/index.ts"
|
|
76
|
-
},
|
|
77
63
|
"./contact": {
|
|
78
64
|
"types": "./src/contact/index.ts",
|
|
79
65
|
"import": "./src/contact/index.ts",
|
|
@@ -88,6 +74,11 @@
|
|
|
88
74
|
"types": "./src/config/index.ts",
|
|
89
75
|
"import": "./src/config/index.ts",
|
|
90
76
|
"default": "./src/config/index.ts"
|
|
77
|
+
},
|
|
78
|
+
"./scripts": {
|
|
79
|
+
"types": "./src/scripts/index.ts",
|
|
80
|
+
"import": "./src/scripts/index.ts",
|
|
81
|
+
"default": "./src/scripts/index.ts"
|
|
91
82
|
}
|
|
92
83
|
},
|
|
93
84
|
"files": [
|
|
@@ -100,34 +91,32 @@
|
|
|
100
91
|
"dev": "tsup --watch",
|
|
101
92
|
"clean": "rm -rf dist",
|
|
102
93
|
"lint": "eslint .",
|
|
103
|
-
"check": "tsc --noEmit"
|
|
104
|
-
|
|
105
|
-
"dependencies": {
|
|
106
|
-
"@vercel/og": "^0.8.5"
|
|
94
|
+
"check": "tsc --noEmit",
|
|
95
|
+
"check-links": "tsx src/scripts/check-links.ts"
|
|
107
96
|
},
|
|
108
97
|
"peerDependencies": {
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"react-dom": "^19.1.0",
|
|
112
|
-
"@djangocfg/ui": "^1.4.33",
|
|
113
|
-
"@djangocfg/layouts": "^2.0.3",
|
|
114
|
-
"@djangocfg/api": "^1.4.33",
|
|
115
|
-
"lucide-react": "^0.469.0"
|
|
98
|
+
"@djangocfg/api": "^1.4.35",
|
|
99
|
+
"next": "^15.4.4"
|
|
116
100
|
},
|
|
117
101
|
"devDependencies": {
|
|
118
|
-
"@djangocfg/
|
|
119
|
-
"@djangocfg/layouts": "^2.0.
|
|
102
|
+
"@djangocfg/imgai": "^1.0.21",
|
|
103
|
+
"@djangocfg/layouts": "^2.0.5",
|
|
104
|
+
"@djangocfg/typescript-config": "^1.4.35",
|
|
120
105
|
"@types/node": "^24.7.2",
|
|
121
106
|
"@types/react": "19.2.2",
|
|
122
107
|
"@types/react-dom": "19.2.1",
|
|
123
108
|
"@types/webpack": "^5.28.5",
|
|
124
109
|
"eslint": "^9.37.0",
|
|
110
|
+
"linkinator": "^7.5.0",
|
|
125
111
|
"lucide-react": "^0.469.0",
|
|
112
|
+
"picocolors": "^1.1.1",
|
|
113
|
+
"prompts": "^2.4.2",
|
|
126
114
|
"tsup": "^8.0.1",
|
|
127
|
-
"
|
|
115
|
+
"tsx": "^4.19.2",
|
|
116
|
+
"typescript": "^5.9.3",
|
|
117
|
+
"@vercel/og": "^0.8.5"
|
|
128
118
|
},
|
|
129
119
|
"publishConfig": {
|
|
130
120
|
"access": "public"
|
|
131
121
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
122
|
+
}
|
|
@@ -226,6 +226,7 @@ export function createBaseNextConfig(
|
|
|
226
226
|
// Cleanup: Remove our custom options that are not part of NextConfig
|
|
227
227
|
// These are internal to BaseNextConfigOptions and should not be in the final config
|
|
228
228
|
delete (finalConfig as any).optimizePackageImports;
|
|
229
|
+
delete (finalConfig as any).isDefaultCfgAdmin;
|
|
229
230
|
// Note: We don't delete transpilePackages, experimental, env, webpack
|
|
230
231
|
// as they are valid NextConfig keys and may have been overridden by user
|
|
231
232
|
|
package/src/contact/submit.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { API,
|
|
20
|
+
import { API, Fetchers } from '@djangocfg/api';
|
|
21
21
|
import type { Schemas } from '@djangocfg/api';
|
|
22
22
|
|
|
23
23
|
export interface SubmitContactFormOptions {
|
|
@@ -35,6 +35,26 @@ export interface SubmitContactFormResult {
|
|
|
35
35
|
lead_id?: number;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Simple server-side memory storage adapter.
|
|
40
|
+
* Implements StorageAdapter interface without importing from client package.
|
|
41
|
+
*/
|
|
42
|
+
class ServerMemoryStorageAdapter {
|
|
43
|
+
private storage: Map<string, string> = new Map();
|
|
44
|
+
|
|
45
|
+
getItem(key: string): string | null {
|
|
46
|
+
return this.storage.get(key) || null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setItem(key: string, value: string): void {
|
|
50
|
+
this.storage.set(key, value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
removeItem(key: string): void {
|
|
54
|
+
this.storage.delete(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
38
58
|
/**
|
|
39
59
|
* Submit contact form data to backend API
|
|
40
60
|
*
|
|
@@ -55,10 +75,10 @@ export async function submitContactForm({
|
|
|
55
75
|
throw new Error('API URL is required');
|
|
56
76
|
}
|
|
57
77
|
|
|
58
|
-
// Create server-side API instance with
|
|
59
|
-
// This
|
|
78
|
+
// Create server-side API instance with server-only memory storage adapter
|
|
79
|
+
// This avoids importing MemoryStorageAdapter from client package
|
|
60
80
|
const serverApi = new API(apiUrl, {
|
|
61
|
-
storage: new
|
|
81
|
+
storage: new ServerMemoryStorageAdapter(),
|
|
62
82
|
});
|
|
63
83
|
|
|
64
84
|
// Prepare submission data with site_url
|
package/src/index.ts
CHANGED
|
@@ -13,15 +13,6 @@ export * from './health';
|
|
|
13
13
|
// OG Image
|
|
14
14
|
export * from './og-image';
|
|
15
15
|
|
|
16
|
-
// Legal pages
|
|
17
|
-
export * from './legal';
|
|
18
|
-
|
|
19
|
-
// Error pages
|
|
20
|
-
export * from './errors';
|
|
21
|
-
|
|
22
|
-
// Components
|
|
23
|
-
export * from './components';
|
|
24
|
-
|
|
25
16
|
// Contact form
|
|
26
17
|
export * from './contact';
|
|
27
18
|
|