create-next-mdx-blog-app 2.1.6 â 2.1.8
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 +35 -2
- package/bin/create.js +1 -1
- package/package.json +17 -16
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ npx create-next-mdx-blog-app .
|
|
|
61
61
|
### Package Information
|
|
62
62
|
|
|
63
63
|
- **Package Name**: `create-next-mdx-blog-app`
|
|
64
|
-
- **Version**: `2.1.
|
|
64
|
+
- **Version**: `2.1.8`
|
|
65
65
|
- **License**: MIT
|
|
66
66
|
- **Homepage**: [https://www.npmjs.com/package/create-next-mdx-blog-app](https://www.npmjs.com/package/create-next-mdx-blog-app/)
|
|
67
67
|
|
|
@@ -216,6 +216,35 @@ The project includes an interactive AI-powered chatbot optimised for readers of
|
|
|
216
216
|
### API Route
|
|
217
217
|
`src/app/api/chat/route.ts` â Next.js edge route. Accepts the `UIMessages` array, converts it to `CoreMessages` via `convertToModelMessages`, streams a response using `streamText` with the three blog tools, and returns `result.toTextStreamResponse()`.
|
|
218
218
|
|
|
219
|
+
## đŦ Newsletter Subscription
|
|
220
|
+
The project ships with an integrated **newsletter signup form** powered by [Resend](https://resend.com). Visitors can subscribe from the home page or from the bottom of any article; new subscribers are added to a Resend **Audience** and immediately receive a welcome email.
|
|
221
|
+
|
|
222
|
+
### Components & Routes
|
|
223
|
+
- `src/components/NewsletterSignup.tsx` â reusable client component with `matrix` (article pages, glass-card + green) and `neutral` (home page, white/black/silver shadcn) visual variants.
|
|
224
|
+
- `src/app/api/newsletter/subscribe/route.ts` â Node-runtime POST handler; validates the email with Zod and forwards it to the Resend SDK.
|
|
225
|
+
- `src/utils/functions/newsletter/subscribeToNewsletter.ts` â server-side helper that adds the contact to your Resend Audience and triggers the welcome email.
|
|
226
|
+
- `src/utils/functions/newsletter/welcomeEmailTemplate.ts` â builds the subject + HTML/text bodies for the confirmation email.
|
|
227
|
+
- `src/utils/functions/resend_client/ResendClient.ts` â server-only Resend client factory.
|
|
228
|
+
|
|
229
|
+
### Setup Steps
|
|
230
|
+
1. Create a Resend account at [resend.com](https://resend.com).
|
|
231
|
+
2. **API Key** â go to **API Keys â Create API Key** and grant it access to **Sending** and **Audiences**. Copy the key into `RESEND_API_KEY` in `.env.local`.
|
|
232
|
+
3. **Audience** â go to **Audiences â Create Audience**, give it a name, and copy the generated UUID into `RESEND_AUDIENCE_ID` in `.env.local`.
|
|
233
|
+
4. Restart `npm run dev` after editing `.env.local` so Next.js picks up the new variables.
|
|
234
|
+
|
|
235
|
+
### Environment Variables
|
|
236
|
+
| Variable | Required for |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `RESEND_API_KEY` | Authenticating with the Resend API |
|
|
239
|
+
| `RESEND_AUDIENCE_ID` | The Resend Audience that new subscribers are added to |
|
|
240
|
+
|
|
241
|
+
### â ī¸ ***Important: A verified sending domain on Resend is required for the email-sending feature to fully work.***
|
|
242
|
+
Out of the box the welcome email is sent from **`onboarding@resend.dev`**, which is Resend's sandbox sender. **`onboarding@resend.dev` is only allowed to deliver to the email address that owns your Resend account** â sending to any other recipient will be rejected by Resend.
|
|
243
|
+
|
|
244
|
+
> đ¨ ***You MUST set up and verify your own sending domain on Resend (Resend dashboard â Domains â Add Domain, then complete the SPF / DKIM DNS records) before the newsletter can deliver welcome emails to real subscribers.*** Once your domain is verified, update the `WELCOME_EMAIL_FROM` constant in `src/utils/functions/newsletter/subscribeToNewsletter.ts` to an address on that domain (for example `newsletter@yourdomain.com`).
|
|
245
|
+
|
|
246
|
+
If the domain step is skipped, the contact will still be added to your Resend Audience, but the welcome email will silently fail (the failure is logged to the server console as `[newsletter] Resend emails.send returned an error: ...`).
|
|
247
|
+
|
|
219
248
|
## đ§Š Constants, Functions, & Types
|
|
220
249
|
In this project, you will find custom constants, functions, and types in the `/src/utils/` directory. Certain constants serve as placeholders in this demo application.
|
|
221
250
|
|
|
@@ -241,6 +270,8 @@ cp .env.example .env.local
|
|
|
241
270
|
| `GITHUB_TOKEN` | GitHub API authentication for `<GitHubGist>` â optional but raises rate limit from 60 to 5,000 req/hr |
|
|
242
271
|
| `GITHUB_USERNAME` | Your GitHub username, used to construct the mdxgists.net URL (defaults to `CodingAbdullah`) |
|
|
243
272
|
| `GIST_BASE_URL` | Base URL for mdxgists.net links (defaults to `https://mdxgists.net`) |
|
|
273
|
+
| `RESEND_API_KEY` | Newsletter signup â authenticates with the Resend API (see the **Newsletter Subscription** section below) |
|
|
274
|
+
| `RESEND_AUDIENCE_ID` | Newsletter signup â the Resend Audience that new subscribers are added to |
|
|
244
275
|
|
|
245
276
|
```
|
|
246
277
|
# .env.local
|
|
@@ -250,6 +281,8 @@ ANTHROPIC_API_KEY=
|
|
|
250
281
|
GITHUB_TOKEN=
|
|
251
282
|
GITHUB_USERNAME=
|
|
252
283
|
GIST_BASE_URL=
|
|
284
|
+
RESEND_API_KEY=
|
|
285
|
+
RESEND_AUDIENCE_ID=
|
|
253
286
|
```
|
|
254
287
|
|
|
255
288
|
## đŠī¸ AWS
|
|
@@ -267,7 +300,7 @@ docker build -t mdx-medium-blog .
|
|
|
267
300
|
``
|
|
268
301
|
|
|
269
302
|
``
|
|
270
|
-
docker run -e SUPABASE_URL=your_supabase_url \ -e SUPABASE_ANON_KEY=your_supabase_anon_key \ -e ANTHROPIC_API_KEY=your_anthropic_api_key \ -e GITHUB_TOKEN=your_github_token \ -e GITHUB_USERNAME=your_github_username \ -e GIST_BASE_URL=https://mdxgists.net \ -p 3000:3000 mdx-medium-blog
|
|
303
|
+
docker run -e SUPABASE_URL=your_supabase_url \ -e SUPABASE_ANON_KEY=your_supabase_anon_key \ -e ANTHROPIC_API_KEY=your_anthropic_api_key \ -e GITHUB_TOKEN=your_github_token \ -e GITHUB_USERNAME=your_github_username \ -e GIST_BASE_URL=https://mdxgists.net \ -e RESEND_API_KEY=your_resend_api_key \ -e RESEND_AUDIENCE_ID=your_resend_audience_id \ -p 3000:3000 mdx-medium-blog
|
|
271
304
|
``
|
|
272
305
|
|
|
273
306
|
## đ CRUD Operations and Supabase Actions
|
package/bin/create.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-next-mdx-blog-app",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "A production-ready technical blog starter kit built with Next.js, MDX, Supabase, and TypeScript.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Abdullah Muhammad",
|
|
@@ -40,46 +40,47 @@
|
|
|
40
40
|
"lint": "next lint"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@inquirer/prompts": "^8.3.2",
|
|
44
|
+
"degit": "^2.8.4",
|
|
45
|
+
"execa": "^9.6.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
43
48
|
"@ai-sdk/anthropic": "^3.0.64",
|
|
44
49
|
"@ai-sdk/react": "^3.0.143",
|
|
45
50
|
"@codesandbox/sandpack-react": "^2.20.0",
|
|
51
|
+
"@eslint/eslintrc": "^3",
|
|
46
52
|
"@mdx-js/loader": "^3.1.1",
|
|
47
53
|
"@mdx-js/react": "^3.1.1",
|
|
48
54
|
"@next/mdx": "^16.2.1",
|
|
49
55
|
"@radix-ui/react-avatar": "^1.1.11",
|
|
50
56
|
"@radix-ui/react-slot": "^1.2.4",
|
|
51
57
|
"@supabase/supabase-js": "^2.101.0",
|
|
58
|
+
"@tailwindcss/postcss": "^4",
|
|
52
59
|
"@types/mdx": "^2.0.13",
|
|
60
|
+
"@types/node": "^25.5.0",
|
|
61
|
+
"@types/react": "^19",
|
|
62
|
+
"@types/react-dom": "^19",
|
|
53
63
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
54
64
|
"@vercel/analytics": "^2.0.1",
|
|
55
65
|
"ai": "^6.0.141",
|
|
56
66
|
"class-variance-authority": "^0.7.1",
|
|
57
67
|
"clsx": "^2.1.1",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
68
|
+
"eslint": "^10",
|
|
69
|
+
"eslint-config-next": "16.2.1",
|
|
60
70
|
"gray-matter": "^4.0.3",
|
|
61
|
-
"@inquirer/prompts": "^8.3.2",
|
|
62
71
|
"lucide-react": "^1.7.0",
|
|
63
72
|
"next": "^16.2.1",
|
|
64
73
|
"next-mdx-remote": "^6.0.0",
|
|
65
74
|
"react": "^19.2.4",
|
|
66
75
|
"react-dom": "^19.2.4",
|
|
67
76
|
"react-syntax-highlighter": "^16.1.1",
|
|
77
|
+
"resend": "^6.12.2",
|
|
68
78
|
"sonner": "^2.0.7",
|
|
69
79
|
"tailwind-merge": "^3.5.0",
|
|
70
|
-
"tsx": "^4.21.0",
|
|
71
|
-
"zod": "^4.3.6"
|
|
72
|
-
},
|
|
73
|
-
"devDependencies": {
|
|
74
|
-
"@eslint/eslintrc": "^3",
|
|
75
|
-
"@tailwindcss/postcss": "^4",
|
|
76
|
-
"@types/node": "^25.5.0",
|
|
77
|
-
"@types/react": "^19",
|
|
78
|
-
"@types/react-dom": "^19",
|
|
79
|
-
"eslint": "^10",
|
|
80
|
-
"eslint-config-next": "16.2.1",
|
|
81
80
|
"tailwindcss": "^4",
|
|
81
|
+
"tsx": "^4.21.0",
|
|
82
82
|
"tw-animate-css": "^1.4.0",
|
|
83
|
-
"typescript": "6.0.2"
|
|
83
|
+
"typescript": "6.0.2",
|
|
84
|
+
"zod": "^4.3.6"
|
|
84
85
|
}
|
|
85
86
|
}
|