@djangocfg/nextjs 1.0.4 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @djangocfg/nextjs
2
2
 
3
- > Comprehensive Next.js utilities and components: sitemap generation, health checks, OG images, legal pages, error pages, and more
3
+ > Server-side Next.js utilities: sitemap generation, health checks, OG images, contact forms, navigation, and config
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@djangocfg/nextjs.svg)](https://www.npmjs.com/package/@djangocfg/nextjs)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
@@ -11,7 +11,9 @@
11
11
 
12
12
  ## Overview
13
13
 
14
- `@djangocfg/nextjs` provides a comprehensive set of utilities and components for Next.js applications. From SEO optimization with sitemaps to health monitoring, from dynamic OG images to ready-to-use legal pages, this package covers common Next.js needs out of the box.
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
- - **Self-Contained** - No external dependencies beyond Next.js
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 { generateMetadata } from '@core/metadata';
150
+ import { generateOgImageMetadata } from '@djangocfg/nextjs/og-image/utils';
151
151
 
152
- export const metadata = generateMetadata({
152
+ export const metadata = generateOgImageMetadata({
153
153
  title: 'My Page',
154
154
  description: 'Page description',
155
155
  });
156
156
  ```
157
157
 
158
- ### Legal Pages
158
+ ### Contact Form
159
159
 
160
- Use pre-built legal pages:
160
+ Create a contact form API route:
161
161
 
162
162
  ```tsx
163
- // app/legal/privacy/page.tsx
164
- import { PrivacyPage } from '@djangocfg/nextjs/legal';
163
+ // app/api/contact/route.ts
164
+ import { createContactRoute } from '@djangocfg/nextjs/contact';
165
165
 
166
- export default PrivacyPage;
166
+ export const POST = createContactRoute();
167
167
  ```
168
168
 
169
- Available pages:
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
- ```tsx
180
- // app/not-found.tsx
181
- import { ErrorLayout } from '@djangocfg/nextjs/errors';
171
+ ### Navigation Utilities
182
172
 
183
- export default function NotFound() {
184
- return <ErrorLayout code={404} supportEmail="support@example.com" />;
185
- }
186
- ```
173
+ Define routes and generate navigation menus:
187
174
 
188
175
  ```tsx
189
- // app/error.tsx
190
- 'use client';
176
+ import { defineRoute, routesToMenuItems } from '@djangocfg/nextjs/navigation';
191
177
 
192
- import { useEffect } from 'react';
193
- import { ErrorLayout } from '@djangocfg/nextjs/errors';
178
+ const routes = [
179
+ defineRoute('/dashboard', { title: 'Dashboard' }),
180
+ defineRoute('/settings', { title: 'Settings' }),
181
+ ];
194
182
 
195
- export default function Error({ error, reset }: { error: Error; reset: () => void }) {
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
- ### HomePage Component
186
+ ### Client Components
205
187
 
206
- Smart authentication redirect component:
188
+ Client-side components (legal pages, error pages, redirect components) are available in `@djangocfg/layouts`:
207
189
 
208
190
  ```tsx
209
- // app/page.tsx
210
- import { HomePage } from '@djangocfg/nextjs/components';
211
-
212
- export default function Page() {
213
- return (
214
- <HomePage
215
- authenticatedPath="/dashboard"
216
- unauthenticatedPath="/auth"
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/legal` | Legal page components |
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
- Generates OG image URL with base64-encoded parameters.
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
- generateOgImageUrl('/api/og', {
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
- logo: '/logo.svg',
337
- }, true) // useBase64 = true (default)
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/layouts` - For auth context in HomePage
435
- - `@djangocfg/ui` - For UI components in legal/error pages
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",
4
- "description": "Next.js utilities and components: sitemap, health, OG images, legal pages, error pages",
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
- "legal-pages",
11
- "error-pages",
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
- "next": "^15.4.4",
110
- "react": "^19.1.0",
111
- "react-dom": "^19.1.0",
112
- "@djangocfg/ui": "^1.4.34",
113
- "@djangocfg/layouts": "^2.0.4",
114
- "@djangocfg/api": "^1.4.34",
115
- "lucide-react": "^0.469.0"
98
+ "@djangocfg/api": "^1.4.35",
99
+ "next": "^15.4.4"
116
100
  },
117
101
  "devDependencies": {
118
- "@djangocfg/typescript-config": "^1.4.34",
119
- "@djangocfg/layouts": "^2.0.4",
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
- "typescript": "^5.9.3"
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
 
@@ -17,7 +17,7 @@
17
17
  * ```
18
18
  */
19
19
 
20
- import { API, MemoryStorageAdapter, Fetchers } from '@djangocfg/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 MemoryStorageAdapter
59
- // This works on the server because MemoryStorageAdapter is not client-only
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 MemoryStorageAdapter(),
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