chalknotes 0.0.24 → 0.0.25
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 +154 -0
- package/bin/cli.js +7 -7
- package/package.json +1 -1
- package/src/lib/getPostBySlug.js +4 -5
package/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# ✏️ ChalkNotes
|
2
|
+
|
3
|
+
**Turn your Notion database into a blog with zero config. Works with Next.js Page Router and App Router.**
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
## 🚀 Features
|
8
|
+
|
9
|
+
- 📄 Fetch blog posts from Notion
|
10
|
+
- 🪄 Auto-generate routes for App Router or Page Router
|
11
|
+
- ⚙️ Helpers for `getStaticProps` / `getStaticPaths`
|
12
|
+
- 🧠 Minimal setup – just run `chalknotes`
|
13
|
+
|
14
|
+
---
|
15
|
+
|
16
|
+
## 📦 Installation
|
17
|
+
|
18
|
+
```bash
|
19
|
+
pnpm add chalknotes
|
20
|
+
# or
|
21
|
+
npm install chalknotes
|
22
|
+
```
|
23
|
+
|
24
|
+
---
|
25
|
+
|
26
|
+
## 🧙♂️ Quick Start
|
27
|
+
|
28
|
+
```bash
|
29
|
+
npx chalknotes
|
30
|
+
```
|
31
|
+
|
32
|
+
- Automatically detects if you're using **App Router** or **Page Router**
|
33
|
+
- Generates blog routes at `/blog/[slug]`
|
34
|
+
- You’re done ✅
|
35
|
+
|
36
|
+
---
|
37
|
+
|
38
|
+
## 🔧 Setup
|
39
|
+
|
40
|
+
Make sure your `.env` file contains:
|
41
|
+
|
42
|
+
```env
|
43
|
+
NOTION_TOKEN=secret_...
|
44
|
+
NOTION_DATABASE_ID=xxxxxxxxxxxxxxxxxxxxxx
|
45
|
+
```
|
46
|
+
|
47
|
+
Your Notion database should have:
|
48
|
+
- A **"Name"** title property
|
49
|
+
- A **"Published"** checkbox property
|
50
|
+
|
51
|
+
---
|
52
|
+
|
53
|
+
## 📚 Usage in Next.js
|
54
|
+
|
55
|
+
### Page Router
|
56
|
+
|
57
|
+
Creates:
|
58
|
+
|
59
|
+
```js
|
60
|
+
// pages/blog/[slug].js
|
61
|
+
import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
|
62
|
+
|
63
|
+
export const getStaticProps = getStaticPropsForPost;
|
64
|
+
export const getStaticPaths = getStaticPathsForPosts;
|
65
|
+
|
66
|
+
export default function BlogPost({ post }) {
|
67
|
+
return (
|
68
|
+
<article>
|
69
|
+
<h1>{post.title}</h1>
|
70
|
+
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
71
|
+
</article>
|
72
|
+
);
|
73
|
+
}
|
74
|
+
```
|
75
|
+
|
76
|
+
---
|
77
|
+
|
78
|
+
### App Router
|
79
|
+
|
80
|
+
Creates:
|
81
|
+
|
82
|
+
```jsx
|
83
|
+
// app/blog/[slug]/page.jsx
|
84
|
+
import { getPostBySlug } from 'chalknotes';
|
85
|
+
|
86
|
+
export default async function BlogPost({ params }) {
|
87
|
+
const post = await getPostBySlug(params.slug);
|
88
|
+
|
89
|
+
return (
|
90
|
+
<article>
|
91
|
+
<h1>{post.title}</h1>
|
92
|
+
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
93
|
+
</article>
|
94
|
+
);
|
95
|
+
}
|
96
|
+
```
|
97
|
+
|
98
|
+
---
|
99
|
+
|
100
|
+
## 🧩 API
|
101
|
+
|
102
|
+
### `getPostBySlug(slug: string)`
|
103
|
+
Fetches a post and renders Notion blocks as HTML.
|
104
|
+
|
105
|
+
```js
|
106
|
+
const post = await getPostBySlug('my-post-title');
|
107
|
+
```
|
108
|
+
|
109
|
+
---
|
110
|
+
|
111
|
+
### `getAllPosts()`
|
112
|
+
Returns all published posts with metadata:
|
113
|
+
|
114
|
+
```js
|
115
|
+
[
|
116
|
+
{
|
117
|
+
title: "My First Post",
|
118
|
+
slug: "my-first-post",
|
119
|
+
notionPageId: "xxxxxxxx"
|
120
|
+
},
|
121
|
+
...
|
122
|
+
]
|
123
|
+
```
|
124
|
+
|
125
|
+
---
|
126
|
+
|
127
|
+
### `getStaticPropsForPost()`
|
128
|
+
For use with `getStaticProps` in Page Router.
|
129
|
+
|
130
|
+
---
|
131
|
+
|
132
|
+
### `getStaticPathsForPosts()`
|
133
|
+
For use with `getStaticPaths` in Page Router.
|
134
|
+
|
135
|
+
---
|
136
|
+
|
137
|
+
## 📅 Roadmap
|
138
|
+
|
139
|
+
- [ ] Rich block support (images, lists, toggles, etc)
|
140
|
+
- [ ] RSS feed support
|
141
|
+
- [ ] MDX or Markdown output option
|
142
|
+
- [ ] Custom blog.config.js support
|
143
|
+
|
144
|
+
---
|
145
|
+
|
146
|
+
## 💡 Inspiration
|
147
|
+
|
148
|
+
Built to scratch an itch while exploring the simplicity of tools like [feather.so](https://feather.so/) and [Notion Blog](https://github.com/ijjk/notion-blog).
|
149
|
+
|
150
|
+
---
|
151
|
+
|
152
|
+
## 🧑💻 Author
|
153
|
+
|
154
|
+
[NepTune](https://github.com/yourhandle) • MIT License
|
package/bin/cli.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/env node
|
1
|
+
#!/usr/bin/env node
|
2
2
|
const fs = require("fs");
|
3
3
|
const path = require("path");
|
4
4
|
|
@@ -22,9 +22,9 @@ export const getStaticPaths = getStaticPathsForPosts;
|
|
22
22
|
|
23
23
|
export default function BlogPost({ post }) {
|
24
24
|
return (
|
25
|
-
<article>
|
26
|
-
<h1>{post.title}</h1>
|
27
|
-
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
25
|
+
<article className="max-w-4xl mx-auto px-4 py-8">
|
26
|
+
<h1 className="text-3xl font-bold mb-4">{post.title}</h1>
|
27
|
+
<div className="text-lg text-gray-700" dangerouslySetInnerHTML={{ __html: post.content }} />
|
28
28
|
</article>
|
29
29
|
);
|
30
30
|
}
|
@@ -44,9 +44,9 @@ export default async function BlogPost({ params }) {
|
|
44
44
|
const post = await getPostBySlug(params.slug);
|
45
45
|
|
46
46
|
return (
|
47
|
-
<article>
|
48
|
-
<h1>{post.title}</h1>
|
49
|
-
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
47
|
+
<article className="max-w-4xl mx-auto px-4 py-8">
|
48
|
+
<h1 className="text-3xl font-bold mb-4">{post.title}</h1>
|
49
|
+
<div className="text-lg text-gray-700" dangerouslySetInnerHTML={{ __html: post.content }} />
|
50
50
|
</article>
|
51
51
|
);
|
52
52
|
}
|
package/package.json
CHANGED
package/src/lib/getPostBySlug.js
CHANGED
@@ -27,22 +27,21 @@ const getPostBySlug = async (slug) => {
|
|
27
27
|
switch (block.type) {
|
28
28
|
case "paragraph":
|
29
29
|
const textHTML = block.paragraph.rich_text.map(text => text.plain_text).join("");
|
30
|
-
content += `<p>${textHTML}</p>`
|
30
|
+
content += `<p class="mb-4">${textHTML}</p>`
|
31
31
|
break;
|
32
32
|
case "heading_1":
|
33
33
|
const headingHTML = block.heading_1.rich_text.map(text => text.plain_text).join("");
|
34
|
-
content += `<h1>${headingHTML}</h1>`
|
34
|
+
content += `<h1 class="text-2xl font-bold mb-4">${headingHTML}</h1>`
|
35
35
|
break;
|
36
36
|
case "heading_2":
|
37
37
|
const heading2HTML = block.heading_2.rich_text.map(text => text.plain_text).join("");
|
38
|
-
content += `<h2>${heading2HTML}</h2>`
|
38
|
+
content += `<h2 class="text-xl font-bold mb-4">${heading2HTML}</h2>`
|
39
39
|
break;
|
40
40
|
case "heading_3":
|
41
41
|
const heading3HTML = block.heading_3.rich_text.map(text => text.plain_text).join("");
|
42
|
-
content += `<h3>${heading3HTML}</h3>`
|
42
|
+
content += `<h3 class="text-lg font-bold mb-4">${heading3HTML}</h3>`
|
43
43
|
break;
|
44
44
|
}
|
45
|
-
console.log(content)
|
46
45
|
}
|
47
46
|
return {
|
48
47
|
title,
|