create-nextjs-stack 0.1.1 → 0.1.4

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.
Files changed (79) hide show
  1. package/README.md +502 -31
  2. package/package.json +6 -1
  3. package/templates/admin/app/(dashboard)/[resource]/[id]/page.tsx +6 -5
  4. package/templates/admin/app/(dashboard)/[resource]/new/page.tsx +11 -12
  5. package/templates/admin/app/(dashboard)/[resource]/page.tsx +4 -3
  6. package/templates/admin/app/actions/upload.ts +0 -7
  7. package/templates/admin/app/globals.css +112 -14
  8. package/templates/admin/app/layout.tsx +4 -1
  9. package/templates/admin/components/admin/Sidebar.tsx +2 -5
  10. package/templates/admin/components.json +22 -0
  11. package/templates/admin/hooks/useResource.ts +3 -0
  12. package/templates/admin/lib/services/resource.service.ts +2 -7
  13. package/templates/admin/lib/supabase/client.ts +8 -4
  14. package/templates/admin/lib/supabase/server.ts +1 -1
  15. package/templates/admin/lib/utils.ts +6 -0
  16. package/templates/admin/middleware.ts +1 -3
  17. package/templates/admin/next.config.ts +10 -2
  18. package/templates/admin/package-lock.json +13 -1
  19. package/templates/admin/package.json +11 -5
  20. package/templates/admin/src/lib/providers/StoreProvider.tsx +12 -0
  21. package/templates/admin/src/store/actions/index.ts +2 -0
  22. package/templates/admin/src/store/hooks.ts +11 -0
  23. package/templates/admin/src/store/index.ts +17 -0
  24. package/templates/admin/src/store/reducers/index.ts +11 -0
  25. package/templates/admin/src/store/types/index.ts +2 -0
  26. package/templates/admin/tsconfig.json +1 -1
  27. package/templates/web/.env.example +5 -1
  28. package/templates/web/package-lock.json +49 -18
  29. package/templates/web/package.json +3 -4
  30. package/templates/web/postcss.config.mjs +3 -1
  31. package/templates/web/src/app/api/revalidate/route.ts +46 -87
  32. package/templates/web/src/app/globals.css +1 -13
  33. package/templates/web/src/app/layout.tsx +4 -46
  34. package/templates/web/src/app/robots.ts +1 -1
  35. package/templates/web/src/app/sitemap.ts +27 -31
  36. package/templates/web/src/lib/seo/metadata.ts +5 -5
  37. package/templates/web/src/lib/seo/seo.config.ts +55 -59
  38. package/templates/web/src/lib/seo/seo.types.ts +1 -7
  39. package/templates/web/src/lib/services/categories.service.ts +3 -3
  40. package/templates/web/src/lib/services/clients.service.ts +2 -2
  41. package/templates/web/src/lib/services/products.service.ts +3 -3
  42. package/templates/web/src/lib/services/projects.service.ts +3 -3
  43. package/templates/web/src/lib/services/users.service.ts +2 -2
  44. package/templates/web/src/lib/supabase/client.ts +1 -1
  45. package/templates/web/src/lib/supabase/server.ts +1 -1
  46. package/templates/web/src/store/hooks.ts +11 -0
  47. package/templates/web/src/store/index.ts +11 -7
  48. package/templates/web/src/store/reducers/index.ts +1 -3
  49. package/templates/admin/app/(dashboard)/categories/[id]/page.tsx +0 -22
  50. package/templates/admin/app/(dashboard)/categories/new/page.tsx +0 -5
  51. package/templates/admin/app/(dashboard)/categories/page.tsx +0 -33
  52. package/templates/admin/app/(dashboard)/clients/[id]/page.tsx +0 -22
  53. package/templates/admin/app/(dashboard)/clients/new/page.tsx +0 -5
  54. package/templates/admin/app/(dashboard)/clients/page.tsx +0 -33
  55. package/templates/admin/app/(dashboard)/products/[id]/page.tsx +0 -22
  56. package/templates/admin/app/(dashboard)/products/new/page.tsx +0 -5
  57. package/templates/admin/app/(dashboard)/products/page.tsx +0 -33
  58. package/templates/admin/app/(dashboard)/projects/[id]/page.tsx +0 -22
  59. package/templates/admin/app/(dashboard)/projects/new/page.tsx +0 -5
  60. package/templates/admin/app/(dashboard)/projects/page.tsx +0 -33
  61. package/templates/admin/app/(dashboard)/users/[id]/page.tsx +0 -22
  62. package/templates/admin/app/(dashboard)/users/new/page.tsx +0 -5
  63. package/templates/admin/app/(dashboard)/users/page.tsx +0 -33
  64. package/templates/admin/components/categories/CategoryForm.tsx +0 -24
  65. package/templates/admin/components/categories/CategoryList.tsx +0 -113
  66. package/templates/admin/components/clients/ClientForm.tsx +0 -24
  67. package/templates/admin/components/clients/ClientList.tsx +0 -113
  68. package/templates/admin/components/products/ProductForm.tsx +0 -24
  69. package/templates/admin/components/products/ProductList.tsx +0 -117
  70. package/templates/admin/components/projects/ProjectForm.tsx +0 -24
  71. package/templates/admin/components/projects/ProjectList.tsx +0 -121
  72. package/templates/admin/components/users/UserForm.tsx +0 -39
  73. package/templates/admin/components/users/UserList.tsx +0 -101
  74. package/templates/web/src/lib/services/categoryService.ts +0 -251
  75. package/templates/web/src/lib/services/clientService.ts +0 -132
  76. package/templates/web/src/lib/services/productService.ts +0 -261
  77. package/templates/web/src/lib/services/projectService.ts +0 -234
  78. package/templates/web/src/lib/utils/cache.ts +0 -98
  79. package/templates/web/src/lib/utils/rate-limiter.ts +0 -102
package/README.md CHANGED
@@ -1,60 +1,531 @@
1
- # Create Next.js Stack
1
+ <div align="center">
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/create-nextjs-stack.svg)](https://www.npmjs.com/package/create-nextjs-stack)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Downloads](https://img.shields.io/npm/dm/create-nextjs-stack.svg)](https://www.npmjs.com/package/create-nextjs-stack)
3
+ # create-nextjs-stack
6
4
 
7
- A powerful CLI tool to scaffold production-ready Next.js applications and Supabase Admin panels.
5
+ [![npm version](https://img.shields.io/npm/v/create-nextjs-stack.svg?style=flat-square)](https://www.npmjs.com/package/create-nextjs-stack)
6
+ [![npm downloads](https://img.shields.io/npm/dm/create-nextjs-stack.svg?style=flat-square)](https://www.npmjs.com/package/create-nextjs-stack)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
8
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?style=flat-square)](https://nodejs.org/)
8
9
 
9
- ## 🚀 Features
10
+ **A zero-config CLI to scaffold production-ready Next.js applications.**
11
+ Choose between a marketing landing page, a Supabase admin panel, or both — in one command.
10
12
 
11
- - **Multi-Template Support**: Choose between Web, Admin, or Full Stack.
12
- - **Production Ready**: Includes Tailwind CSS 4, Redux Toolkit, Supabase, Cloudinary, and Resend.
13
- - **Smart Scaffolding**: Automatically handles environment variables and cleans up dependencies.
13
+ [Quick Start](#-quick-start) · [Templates](#-templates) · [Project Structure](#-project-structure) · [Environment Variables](#-environment-variables) · [Deployment](#-deployment) · [Contributing](#-contributing)
14
14
 
15
- ## 📦 Usage
15
+ </div>
16
16
 
17
- You can use this tool directly with `npx`:
17
+ ---
18
+
19
+ ## Table of Contents
20
+
21
+ - [Overview](#-overview)
22
+ - [Quick Start](#-quick-start)
23
+ - [CLI Reference](#-cli-reference)
24
+ - [Templates](#-templates)
25
+ - [Web — Landing Page](#-web--landing-page)
26
+ - [Admin — Supabase Panel](#-admin--supabase-admin-panel)
27
+ - [Full Stack](#-full-stack)
28
+ - [Project Structure](#-project-structure)
29
+ - [Web Template Structure](#web-template)
30
+ - [Admin Template Structure](#admin-template)
31
+ - [Environment Variables](#-environment-variables)
32
+ - [Web Template](#web-template-env)
33
+ - [Admin Template](#admin-template-env)
34
+ - [Development](#-development)
35
+ - [Deployment](#-deployment)
36
+ - [FAQ](#-faq)
37
+ - [Contributing](#-contributing)
38
+ - [Changelog](#-changelog)
39
+ - [License](#-license)
40
+
41
+ ---
42
+
43
+ ## 🔍 Overview
44
+
45
+ **`create-nextjs-stack`** handles the tedious setup so that you can start building immediately. In a single command it:
46
+
47
+ - Scaffolds a fully configured Next.js 16 application
48
+ - Copies `.env.example` to `.env` so credentials are ready to fill
49
+ - Sets the project name inside `package.json` automatically
50
+ - Prints exact next steps so you never have to guess
51
+
52
+ The result is a codebase that follows real-world best practices — App Router, TypeScript, Tailwind CSS 4, server-side Supabase auth, SEO metadata, and more — without any manual wiring.
53
+
54
+ ---
55
+
56
+ ## ⚡ Quick Start
18
57
 
19
58
  ```bash
20
- npx create-nextjs-stack my-app
59
+ # Using npx (no install required)
60
+ npx create-nextjs-stack@latest my-app
61
+
62
+ # Using npm
63
+ npm create nextjs-stack my-app
64
+
65
+ # Global install (optional)
66
+ npm install -g create-nextjs-stack
67
+ create-nextjs-stack my-app
68
+ ```
69
+
70
+ The interactive CLI will guide you:
71
+
72
+ ```
73
+ ? What is your project named? › my-app
74
+ ? Which template would you like to generate?
75
+ ❯ Full Stack (Web + Admin)
76
+ Web Only (Next.js Landing)
77
+ Admin Only (Supabase Admin)
78
+ ```
79
+
80
+ After scaffolding:
81
+
82
+ ```bash
83
+ cd my-app
84
+ npm install # install dependencies
85
+
86
+ # Open .env and fill in your credentials, then:
87
+ npm run dev # start development server at http://localhost:3000
21
88
  ```
22
89
 
23
- ### Interactive Mode
90
+ ---
24
91
 
25
- The CLI will ask you:
92
+ ## 🖥 CLI Reference
26
93
 
27
- 1. **Project Name**: What to call your new project.
28
- 2. **Template Type**:
29
- - `Full Stack`: Creates both `web` and `admin` projects.
30
- - `Web Only`: Creates the Next.js Landing website.
31
- - `Admin Only`: Creates the Supabase Admin Panel.
94
+ ```
95
+ Usage: create-nextjs-stack [project-directory] [options]
32
96
 
33
- ### Command Line Arguments
97
+ Arguments:
98
+ project-directory Target directory for the new project (optional, prompted if omitted)
34
99
 
35
- You can also bypass prompts:
100
+ Options:
101
+ -t, --template <type> Template to scaffold: web | admin | full-stack
102
+ -v, --version Print CLI version
103
+ -h, --help Show help
104
+ ```
105
+
106
+ ### Examples
36
107
 
37
108
  ```bash
38
- # Create a full stack project
109
+ # Interactive prompts for name and template
110
+ npx create-nextjs-stack
111
+
112
+ # Named project, interactive template selection
113
+ npx create-nextjs-stack my-app
114
+
115
+ # Fully non-interactive
116
+ npx create-nextjs-stack my-app --template web
117
+ npx create-nextjs-stack my-app --template admin
39
118
  npx create-nextjs-stack my-app --template full-stack
119
+ ```
40
120
 
41
- # Create just the web app
42
- npx create-nextjs-stack my-web-app --template web
121
+ ### Overwrite Behaviour
43
122
 
44
- # Create just the admin panel
45
- npx create-nextjs-stack my-admin --template admin
123
+ If the target directory already exists and is non-empty, the CLI will ask:
124
+
125
+ ```
126
+ Directory my-app is not empty. Overwrite? (y/N)
46
127
  ```
47
128
 
48
- ## 🛠 Project Structure
129
+ If you confirm, the directory is emptied before scaffolding. If you decline, the process aborts safely.
130
+
131
+ ---
132
+
133
+ ## 📦 Templates
134
+
135
+ ### 🌐 Web — Landing Page
136
+
137
+ A production-ready Next.js marketing website starter.
49
138
 
50
- After running the command, your project will look like this (for full-stack):
139
+ #### Tech Stack
140
+
141
+ | Layer | Technology | Notes |
142
+ | ---------------- | ----------------------------------------------------------------------------------------------- | ---------------------------- |
143
+ | Framework | [Next.js 16](https://nextjs.org/) | App Router, Turbopack |
144
+ | Language | TypeScript 5 | Strict mode |
145
+ | Styling | [Tailwind CSS 4](https://tailwindcss.com/) | `@tailwindcss/postcss` |
146
+ | State Management | [Redux Toolkit](https://redux-toolkit.js.org/) | Typed slices + actions |
147
+ | Database & Auth | [Supabase](https://supabase.com/) | PostgreSQL + SSR auth |
148
+ | Media | [Cloudinary](https://cloudinary.com/) + `next-cloudinary` | Optimized image delivery |
149
+ | Email | [Resend](https://resend.com/) | Transactional emails |
150
+ | Analytics | [Google Analytics](https://analytics.google.com/) | Via `@next/third-parties` |
151
+ | Forms | [React Hook Form](https://react-hook-form.com/) + [Zod](https://zod.dev/) | Schema validation |
152
+ | Animations | [Framer Motion](https://www.framer.com/motion/) | Page & component transitions |
153
+ | Icons | [Lucide React](https://lucide.dev/) + [React Icons](https://react-icons.github.io/react-icons/) | |
154
+
155
+ #### Feature Highlights
156
+
157
+ - **⚡ Turbopack** for sub-second dev rebuilds and faster production builds
158
+ - **🔍 Full SEO Suite** — dynamic `metadata` API, `sitemap.ts`, `robots.ts`, canonical URLs, and Open Graph tags all configurable from environment variables
159
+ - **🎯 Service Layer** — all external API calls go through `src/lib/services/`, keeping components clean
160
+ - **🗄 Supabase SSR** — server-side Supabase client with cookie-based session handling, compatible with Next.js App Router
161
+ - **🖼 Cloudinary Integration** — ready-to-use `CldImage` and `CldUploadWidget` components via `next-cloudinary`
162
+ - **📬 Email Service** — Resend integration with typed email helpers in the service layer
163
+ - **🔄 Redux Store** — fully typed store with actions, reducers, and providers already wired in
164
+ - **📱 Responsive** — mobile-first layout with Tailwind utilities
165
+ - **🌐 i18n Ready** — folder structure supports multi-language routing expansion
166
+
167
+ ---
168
+
169
+ ### 🛠 Admin — Supabase Admin Panel
170
+
171
+ A minimal, extensible admin dashboard for managing your Supabase data.
172
+
173
+ #### Tech Stack
174
+
175
+ | Layer | Technology | Notes |
176
+ | --------------- | ----------------------------------------------------------- | ------------------------- |
177
+ | Framework | [Next.js 16](https://nextjs.org/) | App Router |
178
+ | Language | TypeScript 5 | |
179
+ | Styling | [Tailwind CSS 4](https://tailwindcss.com/) | `tailwind-merge` + `clsx` |
180
+ | Database & Auth | [Supabase](https://supabase.com/) | PostgreSQL + SSR auth |
181
+ | Media | [Cloudinary](https://cloudinary.com/) | Image uploads |
182
+ | Forms | [React Hook Form](https://react-hook-form.com/) | |
183
+ | Notifications | [React Toastify](https://fkhadra.github.io/react-toastify/) | Toast alerts |
184
+ | Icons | [Lucide React](https://lucide.dev/) | |
185
+ | Utilities | `clsx`, `tailwind-merge` | Class merging helpers |
186
+
187
+ #### Feature Highlights
188
+
189
+ - **🔐 Server-side Auth** — Supabase SSR client; sessions stored in HTTP-only cookies
190
+ - **🛡 Route Protection** — `middleware.ts` guards all dashboard routes; unauthenticated users are redirected to `/login`
191
+ - **📊 Dashboard Layout** — sidebar + header shell with nested route groups `(auth)` and `(dashboard)`
192
+ - **⚙ Server Actions** — data mutations use Next.js Server Actions inside `app/actions/`, keeping client bundles small
193
+ - **🔔 Toast Notifications** — React Toastify integrated at the root layout for global alerts
194
+ - **📷 Cloudinary Uploads** — image upload utilities pre-configured
195
+ - **🧱 Component Library** — reusable admin-specific components in `components/admin/`
196
+
197
+ ---
198
+
199
+ ### 🏗 Full Stack
200
+
201
+ The `full-stack` template scaffolds both the Web and Admin templates into two independent subdirectories under a shared root:
51
202
 
52
203
  ```
53
204
  my-app/
54
- ├── web/ # Next.js Landing Page (App Router, Tailwind 4, Redux)
55
- └── admin/ # Supabase Admin Panel (React, Vite, Tailwind)
205
+ ├── web/ Next.js landing page (port 3000)
206
+ └── admin/ Supabase admin panel (port 3001)
56
207
  ```
57
208
 
209
+ Each sub-project is **completely independent** — separate `package.json`, separate `.env`, separate `node_modules` and dev server. There is no shared monorepo config by design; this keeps the scaffold simple and avoids coupling.
210
+
211
+ > **Tip:** Run each project in a separate terminal with `npm run dev`. If ports conflict, pass `-- --port 3001` to the admin project.
212
+
213
+ ---
214
+
215
+ ## 📁 Project Structure
216
+
217
+ ### Web Template
218
+
219
+ ```
220
+ my-app/
221
+ ├── public/
222
+ │ ├── og-image.png # Default Open Graph image
223
+ │ └── favicon.ico
224
+
225
+ ├── src/
226
+ │ ├── app/ # Next.js App Router
227
+ │ │ ├── layout.tsx # Root layout — fonts, providers, metadata
228
+ │ │ ├── page.tsx # Homepage
229
+ │ │ ├── robots.ts # Dynamic robots.txt generator
230
+ │ │ ├── sitemap.ts # Dynamic XML sitemap generator
231
+ │ │ └── api/ # API route handlers
232
+ │ │
233
+ │ ├── components/ # Shared UI components
234
+ │ │
235
+ │ ├── hooks/ # Custom React hooks
236
+ │ │
237
+ │ ├── lib/
238
+ │ │ ├── providers/
239
+ │ │ │ └── ReduxProvider.tsx # Wraps app with Redux store
240
+ │ │ ├── seo/
241
+ │ │ │ ├── seo.config.ts # Centralised SEO defaults
242
+ │ │ │ ├── metadata.ts # Page metadata helpers
243
+ │ │ │ └── structured-data.ts # JSON-LD schema helpers
244
+ │ │ ├── services/
245
+ │ │ │ ├── email.service.ts # Resend email helpers
246
+ │ │ │ ├── storage.service.ts # Cloudinary upload helpers
247
+ │ │ │ └── supabase.service.ts # Supabase query helpers
248
+ │ │ ├── supabase/
249
+ │ │ │ ├── client.ts # Browser Supabase client
250
+ │ │ │ ├── server.ts # Server Supabase client (SSR)
251
+ │ │ │ └── middleware.ts # Session refresh helper
252
+ │ │ └── utils/ # Shared utility functions
253
+ │ │
254
+ │ └── store/ # Redux Toolkit store
255
+ │ ├── index.ts # Store configuration
256
+ │ ├── actions/ # Action creators
257
+ │ ├── reducers/ # Slice reducers
258
+ │ └── types/ # Store-wide TypeScript types
259
+
260
+ ├── .env.example # All required env vars with descriptions
261
+ ├── components.json # shadcn/ui config (if used)
262
+ ├── next.config.ts
263
+ ├── postcss.config.mjs # Tailwind CSS 4 PostCSS config
264
+ └── tsconfig.json
265
+ ```
266
+
267
+ ### Admin Template
268
+
269
+ ```
270
+ my-admin/
271
+ ├── public/
272
+
273
+ ├── app/ # Next.js App Router (no src/ wrapper)
274
+ │ ├── layout.tsx # Root layout — Toastify provider
275
+ │ ├── page.tsx # Redirects to /dashboard
276
+ │ ├── globals.css # Tailwind CSS 4 imports + theme tokens
277
+ │ │
278
+ │ ├── (auth)/ # Unauthenticated routes
279
+ │ │ └── login/
280
+ │ │ └── page.tsx # Login page
281
+ │ │
282
+ │ ├── (dashboard)/ # Protected routes (guarded by middleware)
283
+ │ │ ├── layout.tsx # Dashboard shell (sidebar + header)
284
+ │ │ ├── dashboard/ # Main dashboard page
285
+ │ │ ├── users/ # User management
286
+ │ │ ├── content/ # Content management
287
+ │ │ └── settings/ # App settings
288
+ │ │
289
+ │ └── actions/ # Next.js Server Actions
290
+ │ ├── auth.actions.ts # Login / logout / session
291
+ │ └── data.actions.ts # CRUD operations
292
+
293
+ ├── components/
294
+ │ └── admin/ # Admin-specific components
295
+ │ ├── Sidebar.tsx
296
+ │ ├── Header.tsx
297
+ │ ├── DataTable.tsx
298
+ │ └── ...
299
+
300
+ ├── config/
301
+ │ └── navigation.ts # Sidebar navigation config
302
+
303
+ ├── hooks/ # Custom hooks
304
+
305
+ ├── lib/
306
+ │ ├── supabase/
307
+ │ │ ├── client.ts # Browser Supabase client
308
+ │ │ └── server.ts # Server Supabase client (SSR)
309
+ │ └── utils/ # Shared helpers (cn, formatters…)
310
+
311
+ ├── middleware.ts # Route protection — redirects to /login
312
+ ├── .env.example
313
+ ├── next.config.ts
314
+ ├── postcss.config.mjs
315
+ └── tsconfig.json
316
+ ```
317
+
318
+ ---
319
+
320
+ ## 🔑 Environment Variables
321
+
322
+ The CLI automatically copies `.env.example` → `.env` during scaffolding. Open `.env` and replace the placeholder values with your real credentials.
323
+
324
+ ### Web Template Env
325
+
326
+ ```bash
327
+ # ─── Email (Resend) ────────────────────────────────────────────────────────────
328
+ # https://resend.com → API Keys
329
+ RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx
330
+ # The verified sender address configured in your Resend domain
331
+ RESEND_FROM_EMAIL=hello@yourdomain.com
332
+
333
+ # ─── Supabase ──────────────────────────────────────────────────────────────────
334
+ # https://supabase.com → Project Settings → API
335
+ NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
336
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsIn...
337
+ SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsIn... # Never expose this client-side!
338
+
339
+ # Supabase project meta (used by Supabase CLI / migrations)
340
+ SUPABASE_PROJECT_ID=xxxxxxxxxxxx
341
+ SUPABASE_PROJECT_NAME=my-project
342
+ SUPABASE_DATABASE_PASSWORD=your-db-password
343
+
344
+ # Used to verify on-demand revalidation requests
345
+ REVALIDATION_SECRET=a-random-secret-string
346
+
347
+ # ─── Cloudinary ────────────────────────────────────────────────────────────────
348
+ # https://cloudinary.com → Dashboard
349
+ NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name
350
+ CLOUDINARY_API_KEY=000000000000000
351
+ CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
352
+ CLOUDINARY_ID=your-cloud-name # Same as CLOUD_NAME, for SDK compat
353
+ CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
354
+
355
+ # ─── Site ──────────────────────────────────────────────────────────────────────
356
+ NEXT_PUBLIC_SITE_URL=https://yourdomain.com # Used for canonical URLs & OG tags
357
+ NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX # Google Analytics Measurement ID
358
+ ```
359
+
360
+ ### Admin Template Env
361
+
362
+ ```bash
363
+ # ─── Supabase ──────────────────────────────────────────────────────────────────
364
+ NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
365
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsIn...
366
+ SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsIn... # Server-side only
367
+
368
+ # ─── Cloudinary ────────────────────────────────────────────────────────────────
369
+ NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name
370
+ CLOUDINARY_API_KEY=000000000000000
371
+ CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
372
+ CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
373
+ ```
374
+
375
+ > ⚠️ **Security:** Variables prefixed with `NEXT_PUBLIC_` are bundled into the client. Never prefix `SERVICE_ROLE_KEY` or `API_SECRET` with `NEXT_PUBLIC_`.
376
+
377
+ ---
378
+
379
+ ## 🛠 Development
380
+
381
+ ### Prerequisites
382
+
383
+ | Tool | Minimum Version |
384
+ | ------- | --------------- |
385
+ | Node.js | 18.x |
386
+ | npm | 9.x |
387
+
388
+ ### Available Scripts
389
+
390
+ Both templates share the same script interface:
391
+
392
+ ```bash
393
+ npm run dev # Start dev server (Web uses Turbopack: next dev --turbopack)
394
+ npm run build # Compile for production
395
+ npm run start # Serve the production build
396
+ npm run lint # Run ESLint across the project
397
+ ```
398
+
399
+ ### Third-party Account Setup
400
+
401
+ | Service | Free Tier | Setup Steps |
402
+ | ------------------------------------------------ | --------- | ----------------------------------------------------------------------- |
403
+ | [Supabase](https://supabase.com) | ✅ Yes | Create project → copy URL and anon key from **Project Settings → API** |
404
+ | [Cloudinary](https://cloudinary.com) | ✅ Yes | Create account → copy cloud name and API credentials from **Dashboard** |
405
+ | [Resend](https://resend.com) | ✅ Yes | Create account → add domain (or use sandbox) → create API key |
406
+ | [Google Analytics](https://analytics.google.com) | ✅ Yes | Create property → copy Measurement ID (`G-XXXXXXXXXX`) |
407
+
408
+ ---
409
+
410
+ ## 🚢 Deployment
411
+
412
+ ### Vercel (Recommended)
413
+
414
+ The Web template is optimised for Vercel — App Router, Edge Middleware, and Supabase SSR all work without any additional configuration.
415
+
416
+ 1. Push your project to GitHub, GitLab, or Bitbucket.
417
+ 2. Go to [vercel.com/new](https://vercel.com/new) and import the repository.
418
+ 3. Add all environment variables from your `.env` file via the **Environment Variables** panel.
419
+ 4. Click **Deploy**.
420
+
421
+ > **Full Stack:** Deploy `web/` and `admin/` as **separate Vercel projects** pointing to different subdirectories. In each project's settings, set the **Root Directory** to `web` or `admin` respectively.
422
+
423
+ ### Netlify
424
+
425
+ ```bash
426
+ # Build command
427
+ npm run build
428
+
429
+ # Publish directory
430
+ .next
431
+ ```
432
+
433
+ Add a `netlify.toml` at the project root:
434
+
435
+ ```toml
436
+ [build]
437
+ command = "npm run build"
438
+ publish = ".next"
439
+
440
+ [[plugins]]
441
+ package = "@netlify/plugin-nextjs"
442
+ ```
443
+
444
+ ### Railway / Render / Other Node hosts
445
+
446
+ These platforms detect Next.js automatically. Ensure your environment variables are configured in the platform's dashboard, then connect your repository and deploy.
447
+
448
+ ### Docker (Self-hosted)
449
+
450
+ ```dockerfile
451
+ FROM node:20-alpine AS deps
452
+ WORKDIR /app
453
+ COPY package*.json ./
454
+ RUN npm ci
455
+
456
+ FROM node:20-alpine AS builder
457
+ WORKDIR /app
458
+ COPY --from=deps /app/node_modules ./node_modules
459
+ COPY . .
460
+ RUN npm run build
461
+
462
+ FROM node:20-alpine AS runner
463
+ WORKDIR /app
464
+ ENV NODE_ENV=production
465
+ COPY --from=builder /app/.next/standalone ./
466
+ COPY --from=builder /app/.next/static ./.next/static
467
+ COPY --from=builder /app/public ./public
468
+ EXPOSE 3000
469
+ CMD ["node", "server.js"]
470
+ ```
471
+
472
+ > Enable `output: 'standalone'` in `next.config.ts` when using Docker.
473
+
474
+ ---
475
+
476
+ ## ❓ FAQ
477
+
478
+ **Q: Can I use JavaScript instead of TypeScript?**
479
+ A: Not yet — TypeScript only for now. A `--javascript` flag is planned for a future release. See [ROADMAP.md](./ROADMAP.md).
480
+
481
+ **Q: Can I use a different CSS framework?**
482
+ A: The templates are designed around Tailwind CSS 4. Swapping it out is possible but requires manual work. Additional styling options are on the roadmap.
483
+
484
+ **Q: The CLI overwrote my directory, can I undo it?**
485
+ A: The CLI asks for confirmation before overwriting. If you confirmed by mistake, restore from git or a backup — the CLI does not keep a copy.
486
+
487
+ **Q: How do I update to a newer template version?**
488
+ A: Re-run the scaffold into a new directory and manually migrate your custom code. There is no in-place upgrade mechanism currently.
489
+
490
+ **Q: Why does `npm run dev` use Turbopack in Web but not in Admin?**
491
+ A: The Web template targets higher-complexity landing pages where faster rebuilds matter most. The Admin template uses the standard Next.js dev server for broader compatibility. You can enable Turbopack in Admin by changing the `dev` script to `next dev --turbopack`.
492
+
493
+ **Q: Can I deploy the Full Stack template as a monorepo on Vercel?**
494
+ A: Yes — create two separate Vercel projects pointing to the same repository, and set their **Root Directory** to `web` and `admin` respectively.
495
+
496
+ ---
497
+
498
+ ## 🤝 Contributing
499
+
500
+ Contributions, bug reports, and feature requests are welcome!
501
+
502
+ 1. [Open an issue](https://github.com/mburakaltiparmak/create-nextjs-stack/issues) to discuss what you'd like to change.
503
+ 2. Fork the repository and create a feature branch:
504
+
505
+ ```bash
506
+ git clone https://github.com/mburakaltiparmak/create-nextjs-stack.git
507
+ cd create-nextjs-stack
508
+ npm install
509
+ ```
510
+
511
+ 3. Make your changes, run the tests:
512
+
513
+ ```bash
514
+ npm test
515
+ ```
516
+
517
+ 4. Submit a pull request with a clear description of the change.
518
+
519
+ Please follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages (`feat:`, `fix:`, `docs:`, `chore:`).
520
+
521
+ ---
522
+
523
+ ## 📋 Changelog
524
+
525
+ See [CHANGELOG.md](./CHANGELOG.md) for a full history of changes.
526
+
527
+ ---
528
+
58
529
  ## 📝 License
59
530
 
60
- MIT
531
+ [MIT](./LICENSE) © [Mehmet Burak Altıparmak](https://github.com/mburakaltiparmak)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextjs-stack",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "CLI to scaffold Next.js Landing Page and Supabase Admin Panel",
5
5
  "private": false,
6
6
  "bin": "./bin/cli.js",
@@ -40,9 +40,14 @@
40
40
  "url": "https://github.com/mburakaltiparmak/create-nextjs-stack/issues"
41
41
  },
42
42
  "devDependencies": {
43
+ "@reduxjs/toolkit": "^2.11.2",
43
44
  "@types/fs-extra": "^11.0.4",
44
45
  "@types/node": "^25.2.3",
46
+ "@types/redux-logger": "^3.0.13",
45
47
  "execa": "^9.6.1",
48
+ "react": "^19.2.4",
49
+ "react-redux": "^9.2.0",
50
+ "redux-logger": "^3.0.6",
46
51
  "vitest": "^4.0.18"
47
52
  }
48
53
  }
@@ -4,14 +4,15 @@ import { getServerClient } from "@/lib/supabase/server";
4
4
  import ResourceFormClient from "@/components/admin/ResourceFormClient";
5
5
 
6
6
  interface PageProps {
7
- params: {
7
+ params: Promise<{
8
8
  resource: string;
9
9
  id: string;
10
- };
10
+ }>;
11
11
  }
12
12
 
13
13
  export default async function EditResourcePage({ params }: PageProps) {
14
- const resourceName = params.resource;
14
+ const resolvedParams = await params;
15
+ const resourceName = resolvedParams.resource;
15
16
  const config = resources.find((r) => r.name === resourceName);
16
17
 
17
18
  if (!config) {
@@ -22,7 +23,7 @@ export default async function EditResourcePage({ params }: PageProps) {
22
23
  const { data: item, error } = await supabase
23
24
  .from(config.table)
24
25
  .select("*")
25
- .eq("id", params.id)
26
+ .eq("id", resolvedParams.id)
26
27
  .single();
27
28
 
28
29
  if (error || !item) {
@@ -38,7 +39,7 @@ export default async function EditResourcePage({ params }: PageProps) {
38
39
  config={config}
39
40
  mode="update"
40
41
  initialData={item}
41
- id={params.id}
42
+ id={resolvedParams.id}
42
43
  />
43
44
  </div>
44
45
  );
@@ -1,17 +1,16 @@
1
1
  import { resources } from "@/config/resources";
2
- import { notFound, redirect } from "next/navigation";
3
- import FormLayout from "@/components/admin/FormLayout";
4
- import { createResource } from "@/app/actions/resources"; // We will create this
5
- import ResourceFormClient from "@/components/admin/ResourceFormClient"; // Wrapper for logic
2
+ import { notFound } from "next/navigation";
3
+ import ResourceFormClient from "@/components/admin/ResourceFormClient";
6
4
 
7
5
  interface PageProps {
8
- params: {
6
+ params: Promise<{
9
7
  resource: string;
10
- };
8
+ }>;
11
9
  }
12
10
 
13
- export default function CreateResourcePage({ params }: PageProps) {
14
- const resourceName = params.resource;
11
+ export default async function CreateResourcePage({ params }: PageProps) {
12
+ const resolvedParams = await params;
13
+ const resourceName = resolvedParams.resource;
15
14
  const config = resources.find((r) => r.name === resourceName);
16
15
 
17
16
  if (!config) {
@@ -20,13 +19,13 @@ export default function CreateResourcePage({ params }: PageProps) {
20
19
 
21
20
  return (
22
21
  <div>
23
- <div className="mb-6">
22
+ <div className="mb-6">
24
23
  <h1 className="text-2xl font-bold">Create {config.singular}</h1>
25
24
  </div>
26
- <ResourceFormClient
27
- config={config}
25
+ <ResourceFormClient
26
+ config={config}
28
27
  mode="create"
29
28
  />
30
29
  </div>
31
30
  );
32
- }
31
+ }
@@ -6,13 +6,14 @@ import Image from "next/image";
6
6
  import { getService } from "@/lib/services";
7
7
 
8
8
  interface PageProps {
9
- params: {
9
+ params: Promise<{
10
10
  resource: string;
11
- };
11
+ }>;
12
12
  }
13
13
 
14
14
  export default async function ResourceListPage({ params }: PageProps) {
15
- const resourceName = params.resource;
15
+ const resolvedParams = await params;
16
+ const resourceName = resolvedParams.resource;
16
17
  const config = resources.find((r) => r.name === resourceName);
17
18
 
18
19
  if (!config) {